package journal.reader; import java.text.ParseException; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.ArrayList; import java.util.Map; import journal.schema.Attribute; import journal.schema.Index; import journal.schema.Schema; import journal.schema.Table; import journal.schema.TableVersion; // Suppress unchecked because I cannot figure out a way to make Comparable<> work // the way I want it to work. @SuppressWarnings("unchecked") public class DataJournalEntry extends JournalEntry implements Comparable<DataJournalEntry> { private int version; private String tableName; private TableVersion tableVersion; public class Argument { Token token; Attribute attribute; Comparable<?> value; Argument(final Token token) { this.token = token; attribute = tableVersion.getAttribute(arguments.size()); value = (Comparable<Object>) attribute.getDomain().parse(token); } Argument(Argument copy) { this.token = copy.token; this.attribute = copy.attribute; this.value = copy.value; } public boolean equals(Object to) { Argument toArg = (Argument) to; return (toArg.attribute.equals(attribute) && toArg.value.equals(value)); } public String toString() { return attribute.getDomain().toJournalFormat(value); } public Attribute getAttribute() { return attribute; } public Comparable<?> getValue() { return value; } public void setValue(Comparable<?> value2) { value = value2; } } private List<Argument> arguments = new ArrayList<Argument>(); private Map<String, Argument> argumentsByName = new HashMap<String, Argument>(); public DataJournalEntry(DataJournalEntry copy) { super(copy.actionType); this.version = copy.version; this.tableName = copy.tableName; this.tableVersion = copy.tableVersion; for( Argument a : copy.arguments) { Argument na = new Argument(a); this.arguments.add(na); this.argumentsByName.put(na.attribute.getName(), na); } } public DataJournalEntry(Token startToken, Token versionToken, Token tableToken) throws ParseException { super(startToken); version = Integer.parseInt(versionToken.getValue()); tableName = tableToken.getValue(); try { tableVersion = Schema.GetTableVersion(tableName, version); if (tableVersion == null) { throw new ParseException("Unknown table " + tableName + "[" + version + "]", tableToken.getLine()); } } catch (IndexOutOfBoundsException e) { throw new ParseException("Unknown version " + tableName + "[" + version + "]", tableToken.getLine()); } } public void addArgument(Token token) { Argument argument = new Argument(token); arguments.add(argument); argumentsByName.put(argument.attribute.getName(), argument); } public Object getValue(String attributeName) { Argument argument = argumentsByName.get(attributeName); if (argument != null) { return argument.getValue(); } return null; } public void setValue(String attributeName, Comparable<?> value) { Argument argument = argumentsByName.get(attributeName); if (argument != null) { argument.setValue(value); } } public List<Object> getValues() { List<Object> result = new ArrayList<Object>(); for (Argument arg : arguments) { result.add(arg.getValue()); } return result; } public List<Argument> getArguments() { return arguments; } public boolean equals(Object to) { if (! to.getClass().equals(getClass())) { return false; } DataJournalEntry toEntry = (DataJournalEntry) to; if (toEntry.tableVersion == tableVersion) { Iterator<Argument> toArgIter = toEntry.arguments.iterator(); Iterator<Argument> argIter = arguments.iterator(); while (toArgIter.hasNext() && argIter.hasNext()) { if (! toArgIter.next().equals(argIter.next())) { return false; } } // both toArgIter.hasNext() and argIter.hasNext() should return false. If one does not // then that iterator is not finished and we have a mismatch return (toArgIter.hasNext() == argIter.hasNext()); } return false; } public String toString() { StringBuffer buf = new StringBuffer(actionType.toString()); buf.append(" "); buf.append(tableName); buf.append("["); buf.append(version); buf.append("] = "); for (Argument arg : arguments) { buf.append(arg.attribute); buf.append(":"); buf.append(arg.value); buf.append(" "); } return buf.toString(); } @SuppressWarnings("rawtypes") public int compareTo(DataJournalEntry o) { int tableDiff = Schema.GetTableIndex(tableName) - Schema.GetTableIndex(o.tableName); if (tableDiff == 0) { Table table = tableVersion.getTable(); List<Index> indeces = table.getIndeces(); for (Index index : indeces) { Argument myArg = argumentsByName.get(index.getName()); Argument otherArg = o.argumentsByName.get(index.getName()); Comparable v1 = myArg.value; Comparable v2 = otherArg.value; int result = v1.compareTo(v2); if (result != 0) { if (index.isAscending()) return result; else return -result; } } return 0; } else { return tableDiff; } } @Override public String toJournalString(ActionType action) { StringBuffer buf = new StringBuffer(super.toJournalString(action)); buf.append(" "); buf.append(tableVersion.toJournalString()); for (Argument a : arguments) { buf.append(" "); buf.append(a.toString()); } buf.append(" "); // that is the Perforce way - Chris knows why return buf.toString(); } @Override public String toJournalString() { return toJournalString(actionType); } public int getVersion() { return version; } public String getTableName() { return tableName; } public TableVersion getTableVersion() { return tableVersion; } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 24773 | Norman Morse |
Moving journalReader from sven's private branch to perforce_software. This is because journalReader is used in the perfsplit test harness, and should be updated over time. Merging //guest/sven_erik_knop/java/JournalReader/... to //guest/perforce_software/journalReader/... |
||
//guest/sven_erik_knop/java/JournalReader/src/journal/reader/DataJournalEntry.java | |||||
#3 | 8017 | Sven Erik Knop | Fixed patching by adding copy constructor. | ||
#2 | 7988 | Sven Erik Knop | Little changes: removed one warning, added an option to JournalSplitter | ||
#1 | 7527 | Sven Erik Knop |
JournalReader, now in its proper place. Documentation to follow. |