From 0ac869b3389bd21f23d99e5ff89db5c5122d83f4 Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Sun, 6 Nov 2011 21:49:57 +0000 Subject: [PATCH] implement unsupported complex value support; add some javadocs git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@586 f203690c-595d-4dc9-a70b-905162fa7fd2 --- TODO.txt | 2 + .../jackcess/complex/Attachment.java | 1 + .../complex/AttachmentColumnInfo.java | 17 +--- .../jackcess/complex/ComplexColumnInfo.java | 22 ++++- .../jackcess/complex/ComplexDataType.java | 1 + .../jackcess/complex/ComplexValue.java | 23 ++++++ .../complex/ComplexValueForeignKey.java | 36 ++++++++- .../complex/MultiValueColumnInfo.java | 18 +---- .../jackcess/complex/SingleValue.java | 1 + .../complex/UnsupportedColumnInfo.java | 80 ++++++++++++++++--- .../jackcess/complex/Version.java | 1 + .../complex/VersionHistoryColumnInfo.java | 13 ++- 12 files changed, 163 insertions(+), 52 deletions(-) diff --git a/TODO.txt b/TODO.txt index af1cefa..7c9802e 100644 --- a/TODO.txt +++ b/TODO.txt @@ -10,6 +10,8 @@ Missing pieces: * MEDIUM - implement (optional) foreign key enforcement * MEDIUM +- implement write support for properties + * EASY - implement table, column, index renaming * EASY - implement table, column, index deletion diff --git a/src/java/com/healthmarketscience/jackcess/complex/Attachment.java b/src/java/com/healthmarketscience/jackcess/complex/Attachment.java index af33544..2f4b046 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/Attachment.java +++ b/src/java/com/healthmarketscience/jackcess/complex/Attachment.java @@ -22,6 +22,7 @@ package com.healthmarketscience.jackcess.complex; import java.util.Date; /** + * Complex value corresponding to an attachment. * * @author James Ahlborn */ diff --git a/src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java b/src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java index f258ca0..b86b9d1 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java +++ b/src/java/com/healthmarketscience/jackcess/complex/AttachmentColumnInfo.java @@ -20,7 +20,6 @@ USA package com.healthmarketscience.jackcess.complex; import java.io.IOException; -import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; @@ -31,6 +30,7 @@ import com.healthmarketscience.jackcess.Table; /** + * Complex column info for a column holding 0 or more attachments per row. * * @author James Ahlborn */ @@ -131,19 +131,8 @@ public class AttachmentColumnInfo extends ComplexColumnInfo } @Override - protected List toValues(ComplexValueForeignKey complexValueFk, - List> rawValues) - throws IOException - { - List attachments = new ArrayList(); - for(Map rawValue : rawValues) { - attachments.add(toAttachment(complexValueFk, rawValue)); - } - return attachments; - } - - protected AttachmentImpl toAttachment(ComplexValueForeignKey complexValueFk, - Map rawValue) { + protected AttachmentImpl toValue(ComplexValueForeignKey complexValueFk, + Map rawValue) { int id = (Integer)getPrimaryKeyColumn().getRowValue(rawValue); String url = (String)getFileUrlColumn().getRowValue(rawValue); String name = (String)getFileNameColumn().getRowValue(rawValue); diff --git a/src/java/com/healthmarketscience/jackcess/complex/ComplexColumnInfo.java b/src/java/com/healthmarketscience/jackcess/complex/ComplexColumnInfo.java index 5232637..bcdaf9f 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/ComplexColumnInfo.java +++ b/src/java/com/healthmarketscience/jackcess/complex/ComplexColumnInfo.java @@ -76,9 +76,11 @@ public abstract class ComplexColumnInfo // the flat table has all the "value" columns and 2 extra columns, a // primary key for each row, and a LONG value which is essentially a // foreign key to the main table. - _typeCols = new ArrayList(); + List typeCols = new ArrayList(); List otherCols = new ArrayList(); - diffFlatColumns(typeObjTable, flatTable, _typeCols, otherCols); + diffFlatColumns(typeObjTable, flatTable, typeCols, otherCols); + + _typeCols = Collections.unmodifiableList(typeCols); Column pkCol = null; Column complexValFkCol = null; @@ -234,6 +236,18 @@ public abstract class ComplexColumnInfo return toValues(complexValueFk, rawValues); } + protected List toValues(ComplexValueForeignKey complexValueFk, + List> rawValues) + throws IOException + { + List values = new ArrayList(); + for(Map rawValue : rawValues) { + values.add(toValue(complexValueFk, rawValue)); + } + + return values; + } + public int addRawValue(Map rawValue) throws IOException { Object[] row = _flatTable.asRow(rawValue); _flatTable.addRow(row); @@ -336,9 +350,9 @@ public abstract class ComplexColumnInfo public abstract ComplexDataType getType(); - protected abstract List toValues( + protected abstract V toValue( ComplexValueForeignKey complexValueFk, - List> rawValues) + Map rawValues) throws IOException; protected static class ComplexValueImpl implements ComplexValue diff --git a/src/java/com/healthmarketscience/jackcess/complex/ComplexDataType.java b/src/java/com/healthmarketscience/jackcess/complex/ComplexDataType.java index 1c5e699..c0ae495 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/ComplexDataType.java +++ b/src/java/com/healthmarketscience/jackcess/complex/ComplexDataType.java @@ -20,6 +20,7 @@ USA package com.healthmarketscience.jackcess.complex; /** + * Secondary type classification for the data in a complex column. * * @author James Ahlborn */ diff --git a/src/java/com/healthmarketscience/jackcess/complex/ComplexValue.java b/src/java/com/healthmarketscience/jackcess/complex/ComplexValue.java index e65a09c..b2f7d8c 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/ComplexValue.java +++ b/src/java/com/healthmarketscience/jackcess/complex/ComplexValue.java @@ -24,20 +24,43 @@ import java.io.IOException; import com.healthmarketscience.jackcess.Column; /** + * Base class for a value in a complex column (where there may be multiple + * values for a single row in the main table). * * @author James Ahlborn */ public interface ComplexValue { + /** + * Returns the unique identifier of this complex value (this value is unique + * among all values in all rows of the main table). + * + * @return the current id or {@link ComplexColumnInfo#INVALID_ID} for a new, + * unsaved value. + */ public int getId(); public void setId(int newId); + /** + * Returns the foreign key identifier for this complex value (this value is + * the same for all values in the same row of the main table). + * + * @return the current id or {@link ComplexColumnInfo#INVALID_COMPLEX_VALUE_ID} + * for a new, unsaved value. + */ public ComplexValueForeignKey getComplexValueForeignKey(); public void setComplexValueForeignKey(ComplexValueForeignKey complexValueFk); + /** + * @return the column in the main table with which this complex value is + * associated + */ public Column getColumn(); + /** + * Writes any updated data for this complex value to the database. + */ public void update() throws IOException; } diff --git a/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java b/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java index 294958f..843cc5e 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java +++ b/src/java/com/healthmarketscience/jackcess/complex/ComplexValueForeignKey.java @@ -28,6 +28,16 @@ import java.util.Map; import com.healthmarketscience.jackcess.Column; /** + * Value which is returned for a complex column. This value corresponds to a + * foreign key in a secondary table which contains the actual complex data for + * this row (which could be 0 or more complex values for a given row). This + * class contains various convenience methods for interacting with the actual + * complex values. + *

+ * This class will cache the associated complex values returned from one of + * the lookup methods. The various modification methods will clear this cache + * automatically. The {@link #reset} method may be called manually to clear + * this internal cache. * * @author James Ahlborn */ @@ -37,10 +47,9 @@ public class ComplexValueForeignKey extends Number private final Column _column; private final int _value; - private List _values; + private transient List _values; - public ComplexValueForeignKey(Column column, int value) - { + public ComplexValueForeignKey(Column column, int value) { _column = column; _value = value; } @@ -103,6 +112,10 @@ public class ComplexValueForeignKey extends Number return (MultiValueColumnInfo)getComplexInfo(); } + protected UnsupportedColumnInfo getUnsupportedInfo() { + return (UnsupportedColumnInfo)getComplexInfo(); + } + public int countValues() throws IOException { @@ -217,6 +230,23 @@ public class ComplexValueForeignKey extends Number return value; } + public UnsupportedValue addUnsupportedValue(Map values) + throws IOException + { + reset(); + UnsupportedValue v = UnsupportedColumnInfo.newValue(this, values); + getUnsupportedInfo().addValue(v); + return v; + } + + public UnsupportedValue updateUnsupportedValue(UnsupportedValue value) + throws IOException + { + reset(); + getUnsupportedInfo().updateValue(value); + return value; + } + private Object writeReplace() throws ObjectStreamException { // if we are going to serialize this ComplexValueForeignKey, convert it // back to a normal Integer (in case it is restored outside of the context diff --git a/src/java/com/healthmarketscience/jackcess/complex/MultiValueColumnInfo.java b/src/java/com/healthmarketscience/jackcess/complex/MultiValueColumnInfo.java index 1b117c6..61488c1 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/MultiValueColumnInfo.java +++ b/src/java/com/healthmarketscience/jackcess/complex/MultiValueColumnInfo.java @@ -20,7 +20,6 @@ USA package com.healthmarketscience.jackcess.complex; import java.io.IOException; -import java.util.ArrayList; import java.util.EnumSet; import java.util.List; import java.util.Map; @@ -31,6 +30,7 @@ import com.healthmarketscience.jackcess.DataType; import com.healthmarketscience.jackcess.Table; /** + * Complex column info for a column holding multiple values per row. * * @author James Ahlborn */ @@ -60,21 +60,9 @@ public class MultiValueColumnInfo extends ComplexColumnInfo public Column getValueColumn() { return _valueCol; } - - @Override - protected List toValues(ComplexValueForeignKey complexValueFk, - List> rawValues) - throws IOException - { - List values = new ArrayList(); - for(Map rawValue : rawValues) { - values.add(toSingleValue(complexValueFk, rawValue)); - } - - return values; - } - protected SingleValueImpl toSingleValue( + @Override + protected SingleValueImpl toValue( ComplexValueForeignKey complexValueFk, Map rawValue) { diff --git a/src/java/com/healthmarketscience/jackcess/complex/SingleValue.java b/src/java/com/healthmarketscience/jackcess/complex/SingleValue.java index d8f6527..2e4c509 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/SingleValue.java +++ b/src/java/com/healthmarketscience/jackcess/complex/SingleValue.java @@ -20,6 +20,7 @@ USA package com.healthmarketscience.jackcess.complex; /** + * Complex value corresponding to an single value in a multi-value column. * * @author James Ahlborn */ diff --git a/src/java/com/healthmarketscience/jackcess/complex/UnsupportedColumnInfo.java b/src/java/com/healthmarketscience/jackcess/complex/UnsupportedColumnInfo.java index fd2a0fc..d362aa7 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/UnsupportedColumnInfo.java +++ b/src/java/com/healthmarketscience/jackcess/complex/UnsupportedColumnInfo.java @@ -20,6 +20,7 @@ USA package com.healthmarketscience.jackcess.complex; import java.io.IOException; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -27,10 +28,11 @@ import com.healthmarketscience.jackcess.Column; import com.healthmarketscience.jackcess.Table; /** + * Complex column info for an unsupported complex type. * * @author James Ahlborn */ -public class UnsupportedColumnInfo extends ComplexColumnInfo +public class UnsupportedColumnInfo extends ComplexColumnInfo { public UnsupportedColumnInfo(Column column, int complexId, Table typeObjTable, @@ -40,6 +42,10 @@ public class UnsupportedColumnInfo extends ComplexColumnInfo super(column, complexId, typeObjTable, flatTable); } + public List getValueColumns() { + return getTypeColumns(); + } + @Override public ComplexDataType getType() { @@ -47,17 +53,73 @@ public class UnsupportedColumnInfo extends ComplexColumnInfo } @Override - protected List toValues(ComplexValueForeignKey complexValueFk, - List> rawValues) - throws IOException + protected UnsupportedValueImpl toValue( + ComplexValueForeignKey complexValueFk, + Map rawValue) { - // FIXME - return null; + int id = (Integer)getPrimaryKeyColumn().getRowValue(rawValue); + + Map values = new LinkedHashMap(rawValue); + values.remove(getPrimaryKeyColumn().getName()); + + return new UnsupportedValueImpl(id, complexValueFk, values); + } + + @Override + protected Object[] asRow(Object[] row, UnsupportedValue value) { + super.asRow(row, value); + + Map values = value.getValues(); + for(Column col : getValueColumns()) { + col.setRowValue(row, col.getRowValue(values)); + } + + return row; + } + + public static UnsupportedValue newValue(Map values) { + return newValue(INVALID_COMPLEX_VALUE_ID, values); } - public ComplexValue newValue() { - // FIXME - return null; + public static UnsupportedValue newValue( + ComplexValueForeignKey complexValueFk, Map values) { + return new UnsupportedValueImpl(INVALID_ID, complexValueFk, values); } + private static class UnsupportedValueImpl extends ComplexValueImpl + implements UnsupportedValue + { + private Map _values; + + private UnsupportedValueImpl(int id, ComplexValueForeignKey complexValueFk, + Map values) + { + super(id, complexValueFk); + _values = values; + } + + public Map getValues() { + return _values; + } + + public Object get(String columnName) { + return getValues().get(columnName); + } + + public void set(String columnName, Object value) { + getValues().put(columnName, value); + } + + @Override + public void update() throws IOException { + getComplexValueForeignKey().updateUnsupportedValue(this); + } + + @Override + public String toString() + { + return "UnsupportedValue(" + getComplexValueForeignKey() + "," + getId() + + ") " + getValues(); + } + } } diff --git a/src/java/com/healthmarketscience/jackcess/complex/Version.java b/src/java/com/healthmarketscience/jackcess/complex/Version.java index 70477f8..376eb32 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/Version.java +++ b/src/java/com/healthmarketscience/jackcess/complex/Version.java @@ -22,6 +22,7 @@ package com.healthmarketscience.jackcess.complex; import java.util.Date; /** + * Complex value corresponding to a version of a memo column. * * @author James Ahlborn */ diff --git a/src/java/com/healthmarketscience/jackcess/complex/VersionHistoryColumnInfo.java b/src/java/com/healthmarketscience/jackcess/complex/VersionHistoryColumnInfo.java index 0cf2fe7..ba98708 100644 --- a/src/java/com/healthmarketscience/jackcess/complex/VersionHistoryColumnInfo.java +++ b/src/java/com/healthmarketscience/jackcess/complex/VersionHistoryColumnInfo.java @@ -20,7 +20,6 @@ USA package com.healthmarketscience.jackcess.complex; import java.io.IOException; -import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; @@ -30,6 +29,8 @@ import com.healthmarketscience.jackcess.Column; import com.healthmarketscience.jackcess.Table; /** + * Complex column info for a column which tracking the version history of an + * "append only" memo column. * * @author James Ahlborn */ @@ -92,10 +93,7 @@ public class VersionHistoryColumnInfo extends ComplexColumnInfo List> rawValues) throws IOException { - List versions = new ArrayList(); - for(Map rawValue : rawValues) { - versions.add(toVersion(complexValueFk, rawValue)); - } + List versions = super.toValues(complexValueFk, rawValues); // order versions newest to oldest Collections.sort(versions); @@ -103,8 +101,9 @@ public class VersionHistoryColumnInfo extends ComplexColumnInfo return versions; } - protected VersionImpl toVersion(ComplexValueForeignKey complexValueFk, - Map rawValue) { + @Override + protected VersionImpl toValue(ComplexValueForeignKey complexValueFk, + Map rawValue) { int id = (Integer)getPrimaryKeyColumn().getRowValue(rawValue); String value = (String)getValueColumn().getRowValue(rawValue); Date modifiedDate = (Date)getModifiedDateColumn().getRowValue(rawValue); -- 2.39.5