Changed leading tabs to spaces.

cusax-fix
Emil Ivov 20 years ago
parent b7cf83ca42
commit c050451e46

@ -11,28 +11,29 @@
/**
* @author Alexander Pelov
*/
public interface History {
/**
* @return Returns an object which can be used to read and query
* this history.
*/
HistoryReader getReader();
/**
* @return Returns an object which can be used to append records to
* this history.
*/
HistoryWriter getWriter();
/**
* @return Returns the ID of this history.
*/
HistoryID getID();
/**
* @return Returns the structure of the history records in this history.
*/
HistoryRecordStructure getHistoryRecordsStructure();
public interface History
{
/**
* @return Returns an object which can be used to read and query
* this history.
*/
HistoryReader getReader();
/**
* @return Returns an object which can be used to append records to
* this history.
*/
HistoryWriter getWriter();
/**
* @return Returns the ID of this history.
*/
HistoryID getID();
/**
* @return Returns the structure of the history records in this history.
*/
HistoryRecordStructure getHistoryRecordsStructure();
}

@ -8,207 +8,242 @@
/**
* Object used to uniquely identify a group of history records.
*
*
* @author Alexander Pelov
*/
public class HistoryID {
private String[] id;
private String stringRepresentation;
private int hashCode;
private HistoryID(String[] id) {
this.id = id;
StringBuffer buff = new StringBuffer();
for(int i = 0; i < id.length; i++) {
if(i > 0) buff.append(' ');
buff.append(this.id[i]);
}
this.stringRepresentation = buff.toString();
this.hashCode = this.stringRepresentation.hashCode();
}
/**
* Create a HistoryID from a raw ID. You can pass any kind of
* strings and they will be safely converted to valid IDs.
*/
public static HistoryID createFromRawID(String[] rawid) {
// TODO: Validate: Assert.assertNonNull(rawid, "Parameter RAWID should be non-null");
// TODO: Validate: Assert.assertTrue(rawid.length > 0, "RAWID.length should be > 0");
String[] id = new String[rawid.length];
for(int i = 0; i < rawid.length; i++) {
id[i] = HistoryID.readableHash(rawid[i]);
}
return new HistoryID(id);
}
/**
* Create a HistoryID from a valid ID. You should pass only
* valid IDs (ones produced from readableHash).
*
* @throws IllegalArgumentException Thrown if a string from the ID is not
* valid an exception.
*/
public static HistoryID createFromID(String[] id)
throws IllegalArgumentException
{
// TODO: Validate: Assert.assertNonNull(id, "Parameter ID should be non-null");
// TODO: Validate: Assert.assertTrue(id.length > 0, "ID.length should be > 0");
for(int i = 0; i < id.length; i++) {
if(!HistoryID.isIDValid(id[i])) {
throw new IllegalArgumentException("Not a valid ID: " + id[i]);
}
}
String[] newID = new String[id.length];
System.arraycopy(id, 0, newID, 0, id.length);
return new HistoryID(newID);
}
public String[] getID() {
return this.id;
}
public String toString() {
return this.stringRepresentation;
}
public int hashCode() {
return this.hashCode;
}
public boolean equals(Object obj) {
boolean eq = false;
if(obj instanceof HistoryID) {
String[] id = ((HistoryID)obj).id;
if(this.id.length == id.length) {
for(int i = 0; i < id.length; i++) {
String s1 = id[i];
String s2 = this.id[i];
if(!((s1 == s2) || (s1 != null && s1.equals(s2)))) {
eq = false;
break;
}
}
}
}
return eq;
}
/**
* An one-way function returning a "human readable" containing no special
* characters. All characters _, a-z, A-Z, 0-9 are kept unchainged.
* All other are replaced with _ and the word is postfixed with
* %HASHCODE, where HASHCODE is the hexadecimal hash value of the
* original string. If there are no special characters the word is
* not postfixed.
*
* Note: This method does not use URLEncoder, because in url-encoding
* the * sign is considered as "safe".
*
* @param rawString The string to be hashed.
* @return The human-readable hash.
*/
public static String readableHash(String rawString) {
StringBuffer encodedString = new StringBuffer(rawString);
boolean addHash = false;
for(int i = 0; i < encodedString.length(); i++) {
if(HistoryID.isSpecialChar(encodedString.charAt(i))) {
addHash = true;
encodedString.setCharAt(i, '_');
}
}
if(addHash) {
encodedString.append('%');
encodedString.append(Integer.toHexString(rawString.hashCode()));
}
return encodedString.toString();
}
/**
* Tests if an ID is valid.
*/
private static boolean isIDValid(String id) {
boolean isValid = true;
int pos = id.indexOf('%');
if(pos < 0) {
// There is no % in the id. In order to be valid all characters
// should be non-special
isValid = !hasSpecialChar(id);
} else {
// There is a % sign in the id. In order to be valid it has
// to be in the form X..X%Y..Y, where there should be no
// special characters in X..X, and Y..Y should be a hexadecimal
// number
if(pos+1 < id.length()) {
String start = id.substring(0, pos);
String end = id.substring(pos+1);
// Check X..X
isValid = !hasSpecialChar(start);
if(isValid) {
// OK; Check Y..Y
try {
Integer.parseInt(end, 16);
// OK
isValid = true;
} catch(Exception e) {
// Not OK
isValid = false;
}
}
} else {
// The % sign is in the beginning - bad ID.
isValid = false;
}
}
return isValid;
}
/**
* Tests if a character is a special one. A character is special
* if it is not in the range _, a-z, A-Z, 0-9.
*
* @param c The character to test.
* @return Returns true if the character is special. False otherwise.
*/
private static boolean isSpecialChar(char c) {
return (c != '_') &&
(c < 'A' || c > 'Z') &&
(c < 'a' || c > 'z') &&
(c < '0' || c > '9');
}
/**
* Tests there is a special character in a string.
*/
private static boolean hasSpecialChar(String str) {
boolean hasSpecialChar = false;
for(int i = 0; i < str.length(); i++) {
if(isSpecialChar(str.charAt(i))) {
hasSpecialChar = false;
break;
}
}
return hasSpecialChar;
}
public class HistoryID
{
private String[] id;
private String stringRepresentation;
private int hashCode;
private HistoryID(String[] id)
{
this.id = id;
StringBuffer buff = new StringBuffer();
for (int i = 0; i < id.length; i++)
{
if (i > 0)
buff.append(' ');
buff.append(this.id[i]);
}
this.stringRepresentation = buff.toString();
this.hashCode = this.stringRepresentation.hashCode();
}
/**
* Create a HistoryID from a raw ID. You can pass any kind of
* strings and they will be safely converted to valid IDs.
*/
public static HistoryID createFromRawID(String[] rawid)
{
// TODO: Validate: Assert.assertNonNull(rawid, "Parameter RAWID should be non-null");
// TODO: Validate: Assert.assertTrue(rawid.length > 0, "RAWID.length should be > 0");
String[] id = new String[rawid.length];
for (int i = 0; i < rawid.length; i++)
{
id[i] = HistoryID.readableHash(rawid[i]);
}
return new HistoryID(id);
}
/**
* Create a HistoryID from a valid ID. You should pass only
* valid IDs (ones produced from readableHash).
*
* @throws IllegalArgumentException Thrown if a string from the ID is not
* valid an exception.
*/
public static HistoryID createFromID(String[] id) throws
IllegalArgumentException
{
// TODO: Validate: Assert.assertNonNull(id, "Parameter ID should be non-null");
// TODO: Validate: Assert.assertTrue(id.length > 0, "ID.length should be > 0");
for (int i = 0; i < id.length; i++)
{
if (!HistoryID.isIDValid(id[i]))
{
throw new IllegalArgumentException("Not a valid ID: " + id[i]);
}
}
String[] newID = new String[id.length];
System.arraycopy(id, 0, newID, 0, id.length);
return new HistoryID(newID);
}
public String[] getID()
{
return this.id;
}
public String toString()
{
return this.stringRepresentation;
}
public int hashCode()
{
return this.hashCode;
}
public boolean equals(Object obj)
{
boolean eq = false;
if (obj instanceof HistoryID)
{
String[] id = ( (HistoryID) obj).id;
if (this.id.length == id.length)
{
for (int i = 0; i < id.length; i++)
{
String s1 = id[i];
String s2 = this.id[i];
if (! ( (s1 == s2) || (s1 != null && s1.equals(s2))))
{
eq = false;
break;
}
}
}
}
return eq;
}
/**
* An one-way function returning a "human readable" containing no special
* characters. All characters _, a-z, A-Z, 0-9 are kept unchainged.
* All other are replaced with _ and the word is postfixed with
* %HASHCODE, where HASHCODE is the hexadecimal hash value of the
* original string. If there are no special characters the word is
* not postfixed.
*
* Note: This method does not use URLEncoder, because in url-encoding
* the * sign is considered as "safe".
*
* @param rawString The string to be hashed.
* @return The human-readable hash.
*/
public static String readableHash(String rawString)
{
StringBuffer encodedString = new StringBuffer(rawString);
boolean addHash = false;
for (int i = 0; i < encodedString.length(); i++)
{
if (HistoryID.isSpecialChar(encodedString.charAt(i)))
{
addHash = true;
encodedString.setCharAt(i, '_');
}
}
if (addHash)
{
encodedString.append('%');
encodedString.append(Integer.toHexString(rawString.hashCode()));
}
return encodedString.toString();
}
/**
* Tests if an ID is valid.
*/
private static boolean isIDValid(String id)
{
boolean isValid = true;
int pos = id.indexOf('%');
if (pos < 0)
{
// There is no % in the id. In order to be valid all characters
// should be non-special
isValid = !hasSpecialChar(id);
}
else
{
// There is a % sign in the id. In order to be valid it has
// to be in the form X..X%Y..Y, where there should be no
// special characters in X..X, and Y..Y should be a hexadecimal
// number
if (pos + 1 < id.length())
{
String start = id.substring(0, pos);
String end = id.substring(pos + 1);
// Check X..X
isValid = !hasSpecialChar(start);
if (isValid)
{
// OK; Check Y..Y
try
{
Integer.parseInt(end, 16);
// OK
isValid = true;
}
catch (Exception e)
{
// Not OK
isValid = false;
}
}
}
else
{
// The % sign is in the beginning - bad ID.
isValid = false;
}
}
return isValid;
}
/**
* Tests if a character is a special one. A character is special
* if it is not in the range _, a-z, A-Z, 0-9.
*
* @param c The character to test.
* @return Returns true if the character is special. False otherwise.
*/
private static boolean isSpecialChar(char c)
{
return (c != '_') &&
(c < 'A' || c > 'Z') &&
(c < 'a' || c > 'z') &&
(c < '0' || c > '9');
}
/**
* Tests there is a special character in a string.
*/
private static boolean hasSpecialChar(String str)
{
boolean hasSpecialChar = false;
for (int i = 0; i < str.length(); i++)
{
if (isSpecialChar(str.charAt(i)))
{
hasSpecialChar = false;
break;
}
}
return hasSpecialChar;
}
}

@ -20,43 +20,43 @@
*
* @author Alexander Pelov
*/
public interface HistoryService {
public interface HistoryService
{
/**
* Returns the IDs of all existing histories.
*
* @return An iterator to a list of IDs.
*/
Iterator getExistingIDs();
/**
* Returns the IDs of all existing histories.
*
* @return An iterator to a list of IDs.
*/
Iterator getExistingIDs();
/**
* Returns the history associated with this ID.
*
* @param id The ID of the history.
* @return Returns the history with this ID.
* @throws IllegalArgumentException Thrown if there is no such history.
*/
History getHistory(HistoryID id)
throws IllegalArgumentException;
/**
* Returns the history associated with this ID.
*
* @param id The ID of the history.
* @return Returns the history with this ID.
* @throws IllegalArgumentException Thrown if there is no such history.
*/
History getHistory(HistoryID id) throws IllegalArgumentException;
/**
* Tests if a history with the given ID exists.
*
* @param id The ID to test.
* @return True if a history with this ID exists. False otherwise.
*/
boolean isHistoryExisting(HistoryID id);
/**
* Tests if a history with the given ID exists.
*
* @param id The ID to test.
* @return True if a history with this ID exists. False otherwise.
*/
boolean isHistoryExisting(HistoryID id);
/**
* Creates a new history for this ID.
*
* @param id The ID of the history to be created.
* @param recordStructure The structure of the data.
* @return Returns the history with this ID.
* @throws IllegalArgumentException Thrown if such history already exists.
* @throws IOException Thrown if the history could not be created due to
* a IO error.
*/
History createHistory(HistoryID id, HistoryRecordStructure recordStructure)
throws IllegalArgumentException, IOException;
/**
* Creates a new history for this ID.
*
* @param id The ID of the history to be created.
* @param recordStructure The structure of the data.
* @return Returns the history with this ID.
* @throws IllegalArgumentException Thrown if such history already exists.
* @throws IOException Thrown if the history could not be created due to
* a IO error.
*/
History createHistory(HistoryID id, HistoryRecordStructure recordStructure) throws
IllegalArgumentException, IOException;
}

@ -13,24 +13,25 @@
/**
* @author Alexander Pelov
*/
public interface HistoryWriter {
/**
* Stores the passed record complying with the historyRecordStructure.
*
* @param record The record to be added.
*
* @throws IOException
*/
void addRecord(HistoryRecord record) throws IOException;
/**
* Stores the passed propertyValues complying with the historyRecordStructure.
*
* @param propertyValues The values of the record.
*
* @throws IOException
*/
void addRecord(String[] propertyValues) throws IOException;
public interface HistoryWriter
{
/**
* Stores the passed record complying with the historyRecordStructure.
*
* @param record The record to be added.
*
* @throws IOException
*/
void addRecord(HistoryRecord record) throws IOException;
/**
* Stores the passed propertyValues complying with the historyRecordStructure.
*
* @param propertyValues The values of the record.
*
* @throws IOException
*/
void addRecord(String[] propertyValues) throws IOException;
}

@ -11,78 +11,89 @@
/**
* @author Alexander Pelov
*/
public class HistoryRecord {
public class HistoryRecord
{
private Date timestamp;
private String[] propertyNames;
private String[] propertyValues;
private Date timestamp;
private String[] propertyNames;
private String[] propertyValues;
/**
* Constructs an entry containing multiple name-value pairs, where the names
* are taken from the defined structure. The timestamp is set to the time this
* object is created.
*
* @param entryStructure
* @param propertyValues
*/
public HistoryRecord(HistoryRecordStructure entryStructure, String[] propertyValues) {
this(entryStructure.getPropertyNames(), propertyValues, new Date());
}
/**
* Constructs an entry containing multiple name-value pairs, where the names
* are taken from the defined structure. The timestamp is set to the time this
* object is created.
*
* @param entryStructure
* @param propertyValues
*/
public HistoryRecord(HistoryRecordStructure entryStructure,
String[] propertyValues)
{
this(entryStructure.getPropertyNames(), propertyValues, new Date());
}
/**
* Constructs an entry containing multiple name-value pairs, where the name is not
* unique. The timestamp is set to the time this object is created.
*
* @param propertyNames
* @param propertyValues
*/
public HistoryRecord(String[] propertyNames, String[] propertyValues) {
this(propertyNames, propertyValues, new Date());
}
/**
* Constructs an entry containing multiple name-value pairs, where the name is not
* unique. The timestamp is set to the time this object is created.
*
* @param propertyNames
* @param propertyValues
*/
public HistoryRecord(String[] propertyNames, String[] propertyValues)
{
this(propertyNames, propertyValues, new Date());
}
/**
* Constructs an entry containing multiple name-value pairs, where the names
* are taken from the defined structure.
*
* @param entryStructure
* @param propertyValues
* @param timestamp
*/
public HistoryRecord(HistoryRecordStructure entryStructure, String[] propertyValues, Date timestamp) {
this(entryStructure.getPropertyNames(), propertyValues, timestamp);
}
/**
* Constructs an entry containing multiple name-value pairs, where the names
* are taken from the defined structure.
*
* @param entryStructure
* @param propertyValues
* @param timestamp
*/
public HistoryRecord(HistoryRecordStructure entryStructure,
String[] propertyValues, Date timestamp)
{
this(entryStructure.getPropertyNames(), propertyValues, timestamp);
}
/**
* Constructs an entry containing multiple name-value pairs, where the name is not
* unique.
*
* @param propertyNames
* @param propertyValues
* @param timestamp
*/
public HistoryRecord(String[] propertyNames, String[] propertyValues, Date timestamp) {
// TODO: Validate: Assert.assertNonNull(propertyNames, "The property names should be non-null.");
// TODO: Validate: Assert.assertNonNull(propertyValues, "The property values should be non-null.");
// TODO: Validate: Assert.assertNonNull(timestamp, "The timestamp should be non-null.");
// TODO: Validate Assert.assertTrue(propertyNames.length == propertyValues.length,
// "The length of the property names and property values should be equal.");
/**
* Constructs an entry containing multiple name-value pairs, where the name is not
* unique.
*
* @param propertyNames
* @param propertyValues
* @param timestamp
*/
public HistoryRecord(String[] propertyNames, String[] propertyValues,
Date timestamp)
{
// TODO: Validate: Assert.assertNonNull(propertyNames, "The property names should be non-null.");
// TODO: Validate: Assert.assertNonNull(propertyValues, "The property values should be non-null.");
// TODO: Validate: Assert.assertNonNull(timestamp, "The timestamp should be non-null.");
this.propertyNames = propertyNames;
this.propertyValues = propertyValues;
this.timestamp = timestamp;
}
// TODO: Validate Assert.assertTrue(propertyNames.length == propertyValues.length,
// "The length of the property names and property values should be equal.");
public String[] getPropertyNames() {
return this.propertyNames;
}
this.propertyNames = propertyNames;
this.propertyValues = propertyValues;
this.timestamp = timestamp;
}
public String[] getPropertyValues() {
return this.propertyValues;
}
public String[] getPropertyNames()
{
return this.propertyNames;
}
public Date getTimestamp() {
return this.timestamp;
}
public String[] getPropertyValues()
{
return this.propertyValues;
}
public Date getTimestamp()
{
return this.timestamp;
}
}

@ -9,33 +9,37 @@
/**
* @author Alexander Pelov
*/
public class HistoryRecordStructure {
public class HistoryRecordStructure
{
private String[] propertyNames;
private String[] propertyNames;
/**
* Creates an entry structure object used to define the shape of the data
* stored in the history.
*
* Note that the property names are not unique, i.e. a single property
* may have 0, 1 or more values.
*
* @param propertyNames
*/
public HistoryRecordStructure(String[] propertyNames) {
// TODO: Validate: Assert.assertNonNull(propertyNames, "Parameter propertyNames should be non-null.");
this.propertyNames = new String[propertyNames.length];
System.arraycopy(propertyNames, 0, this.propertyNames, 0, this.propertyNames.length);
}
/**
* Creates an entry structure object used to define the shape of the data
* stored in the history.
*
* Note that the property names are not unique, i.e. a single property
* may have 0, 1 or more values.
*
* @param propertyNames
*/
public HistoryRecordStructure(String[] propertyNames)
{
// TODO: Validate: Assert.assertNonNull(propertyNames, "Parameter propertyNames should be non-null.");
this.propertyNames = new String[propertyNames.length];
System.arraycopy(propertyNames, 0, this.propertyNames, 0,
this.propertyNames.length);
}
public String[] getPropertyNames()
{
return this.propertyNames;
}
public int getPropertyCount()
{
return this.propertyNames.length;
}
public String[] getPropertyNames() {
return this.propertyNames;
}
public int getPropertyCount() {
return this.propertyNames.length;
}
}

Loading…
Cancel
Save