You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2006/07/19 23:35:07 UTC
svn commit: r423615 [20/44] - in /incubator/openjpa/trunk: ./
openjpa-jdbc-5/ openjpa-jdbc-5/src/ openjpa-jdbc-5/src/main/
openjpa-jdbc-5/src/main/java/ openjpa-jdbc-5/src/main/java/org/
openjpa-jdbc-5/src/main/java/org/apache/ openjpa-jdbc-5/src/main/...
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,1573 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.io.InputStream;
+import java.io.ObjectOutput;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.BitSet;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Locale;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.enhance.StateManager;
+import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
+import org.apache.openjpa.jdbc.meta.RelationId;
+import org.apache.openjpa.jdbc.meta.ValueMappingInfo;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ColumnIO;
+import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.Row;
+import org.apache.openjpa.jdbc.sql.RowManager;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.FetchState;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.PCState;
+import org.apache.openjpa.kernel.StoreContext;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.ValueMetaData;
+import org.apache.openjpa.util.InternalException;
+import org.apache.openjpa.util.MetaDataException;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * Mapping for an embedded persistent object.
+ *
+ * @author Abe White
+ * @since 4.0
+ */
+public class EmbedFieldStrategy
+ extends AbstractFieldStrategy {
+
+ private static final int INSERT = 0;
+ private static final int UPDATE = 1;
+ private static final int DELETE = 2;
+
+ private static final Localizer _loc = Localizer.forPackage
+ (EmbedFieldStrategy.class);
+
+ private boolean _synthetic = false;
+
+ public void map(boolean adapt) {
+ if (field.getEmbeddedMetaData() == null)
+ throw new MetaDataException(_loc.get("not-embed", field));
+ assertNotMappedBy();
+
+ // map join key (if any)
+ field.mapJoin(adapt, false);
+ field.getKeyMapping().getValueInfo().assertNoSchemaComponents
+ (field.getKey(), !adapt);
+ field.getElementMapping().getValueInfo().assertNoSchemaComponents
+ (field.getElement(), !adapt);
+
+ ValueMappingInfo vinfo = field.getValueInfo();
+ vinfo.assertNoJoin(field, true);
+ vinfo.assertNoForeignKey(field, !adapt);
+ vinfo.assertNoUnique(field, !adapt);
+ vinfo.assertNoIndex(field, !adapt);
+
+ // before we map the null indicator column, we need to make sure our
+ // value is mapped so we can tell whether the column is synthetic
+ field.getValueMapping().resolve(field.MODE_META | field.MODE_MAPPING);
+ Column col = vinfo.getNullIndicatorColumn(field, field.getName(),
+ field.getTable(), adapt);
+ if (col != null) {
+ field.setColumns(new Column[]{ col });
+ field.setColumnIO(vinfo.getColumnIO());
+ }
+
+ field.mapPrimaryKey(adapt);
+ }
+
+ public void initialize() {
+ Column[] cols = field.getColumns();
+ if (cols.length != 1)
+ _synthetic = false;
+ else {
+ // do any of the embedded field mappings use this column?
+ // if not, consider it synthetic
+ Column col = cols[0];
+ boolean found = false;
+ FieldMapping[] fields = field.getEmbeddedMapping().
+ getFieldMappings();
+ for (int i = 0; !found && i < fields.length; i++) {
+ cols = fields[i].getColumns();
+ for (int j = 0; j < cols.length; j++)
+ if (cols[j].equals(col))
+ found = true;
+ }
+ _synthetic = !found;
+ }
+ }
+
+ public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ Row row = field.getRow(sm, store, rm, Row.ACTION_INSERT);
+ if (row == null)
+ return;
+
+ OpenJPAStateManager em = store.getContext().getStateManager
+ (sm.fetchObject(field.getIndex()));
+ insert(sm, em, store, rm, row);
+ }
+
+ /**
+ * Insert an embedded object.
+ *
+ * @param owner the owning state manager
+ * @param sm the embedded state manager, or null if the value is null
+ * @param rm the row manager
+ * @param row expected row for this embedded value
+ */
+ public void insert(OpenJPAStateManager owner, OpenJPAStateManager sm,
+ JDBCStore store, RowManager rm, Row row)
+ throws SQLException {
+ OpenJPAStateManager em = sm;
+ if (em == null)
+ em = new NullEmbeddedStateManager(owner, field);
+ rm = new EmbeddedRowManager(rm, row);
+ FieldMapping[] fields = field.getEmbeddedMapping().getFieldMappings();
+ for (int i = 0; i < fields.length; i++)
+ if (!Boolean.TRUE.equals(fields[i].isCustomInsert(em, store)))
+ fields[i].insert(em, store, rm);
+
+ if (field.getColumnIO().isInsertable(0, true))
+ setNullIndicatorColumn(sm, row);
+ }
+
+ public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ OpenJPAStateManager em = store.getContext().getStateManager
+ (sm.fetchObject(field.getIndex()));
+ boolean newVal = em == null || em.getPCState() == PCState.ECOPY;
+
+ Row row = null;
+ if (newVal && field.getJoinForeignKey() != null
+ && field.isJoinOuter()) {
+ // if our record is in an outer-joined related table and we're not
+ // updating an existing value, delete the old one
+ Row del = rm.getRow(field.getTable(), Row.ACTION_DELETE, sm, true);
+ del.whereForeignKey(field.getJoinForeignKey(), sm);
+ delete(sm, null, store, rm, del);
+
+ // insert the new value
+ row = rm.getRow(field.getTable(), Row.ACTION_INSERT, sm,
+ em != null);
+ } else
+ row = rm.getRow(field.getTable(), Row.ACTION_UPDATE, sm, true);
+ if (row == null)
+ return;
+
+ if (row.getAction() == Row.ACTION_INSERT)
+ insert(sm, em, store, rm, row);
+ else
+ update(sm, em, store, rm, row);
+ }
+
+ /**
+ * Update an embedded object.
+ *
+ * @param owner the owning state manager
+ * @param sm the embedded state manager, or null if the value is null
+ * @param rm the row manager
+ * @param row expected row for this embedded value
+ */
+ public void update(OpenJPAStateManager owner, OpenJPAStateManager sm,
+ JDBCStore store, RowManager rm, Row row)
+ throws SQLException {
+ OpenJPAStateManager em = sm;
+ if (em == null)
+ em = new NullEmbeddedStateManager(owner, field);
+ rm = new EmbeddedRowManager(rm, row);
+ FieldMapping[] fields = field.getEmbeddedMapping().getFieldMappings();
+ for (int i = 0; i < fields.length; i++)
+ if (em.getDirty().get(i)
+ && !em.getFlushed().get(i)
+ && !Boolean.TRUE.equals(fields[i].isCustomUpdate(em, store)))
+ fields[i].update(em, store, rm);
+
+ if (field.getColumnIO().isUpdatable(0, true))
+ setNullIndicatorColumn(sm, row);
+ }
+
+ public void delete(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ OpenJPAStateManager em = null;
+ if (sm.getLoaded().get(field.getIndex()))
+ em = store.getContext().getStateManager(sm.fetchObject
+ (field.getIndex()));
+ Row row = field.getRow(sm, store, rm, Row.ACTION_DELETE);
+ delete(sm, em, store, rm, row);
+ }
+
+ /**
+ * Delete an embedded object record.
+ *
+ * @param owner the owning state manager
+ * @param sm the embedded state manager, or null if not known
+ * @param rm the row manager
+ * @param row expected row for this embedded value
+ */
+ public void delete(OpenJPAStateManager owner, OpenJPAStateManager sm,
+ JDBCStore store, RowManager rm, Row row)
+ throws SQLException {
+ rm = new EmbeddedRowManager(rm, row);
+ if (sm == null)
+ sm = new NullEmbeddedStateManager(owner, field);
+ FieldMapping[] fields = field.getEmbeddedMapping().getFieldMappings();
+ for (int i = 0; i < fields.length; i++)
+ if (!Boolean.TRUE.equals(fields[i].isCustomDelete(sm, store)))
+ fields[i].delete(sm, store, rm);
+ }
+
+ /**
+ * Set the proper null indicator value into the given row.
+ */
+ private void setNullIndicatorColumn(OpenJPAStateManager sm, Row row)
+ throws SQLException {
+ if (!_synthetic)
+ return;
+
+ Column col = field.getColumns()[0];
+ Object val = ((EmbeddedClassStrategy) field.getEmbeddedMapping().
+ getStrategy()).getNullIndicatorValue(sm);
+ if (val == null)
+ row.setNull(col, true);
+ else
+ row.setObject(col, val);
+ }
+
+ public Boolean isCustomInsert(OpenJPAStateManager sm, JDBCStore store) {
+ OpenJPAStateManager em = sm.getContext().getStateManager(sm.fetchObject
+ (field.getIndex()));
+ Boolean custom = isCustom(INSERT, sm, em, store);
+ if (Boolean.TRUE.equals(custom) && _synthetic)
+ return null;
+ return custom;
+ }
+
+ public Boolean isCustomUpdate(OpenJPAStateManager sm, JDBCStore store) {
+ OpenJPAStateManager em = sm.getContext().getStateManager(sm.fetchObject
+ (field.getIndex()));
+ Boolean custom = isCustom(UPDATE, sm, em, store);
+ if (Boolean.TRUE.equals(custom) && _synthetic)
+ return null;
+ return custom;
+ }
+
+ public Boolean isCustomDelete(OpenJPAStateManager sm, JDBCStore store) {
+ OpenJPAStateManager em = sm.getContext().getStateManager(sm.fetchObject
+ (field.getIndex()));
+ return isCustom(DELETE, sm, em, store);
+ }
+
+ /**
+ * Return whether the given action requires custom handling for any fields.
+ */
+ private Boolean isCustom(int action, OpenJPAStateManager owner,
+ OpenJPAStateManager sm, JDBCStore store) {
+ if (sm == null)
+ sm = new NullEmbeddedStateManager(owner, field);
+ boolean hasCustom = false;
+ boolean hasStd = false;
+
+ FieldMapping[] fields = field.getEmbeddedMapping().getFieldMappings();
+ Boolean custom = null;
+ for (int i = 0; i < fields.length; i++) {
+ switch (action) {
+ case INSERT:
+ custom = fields[i].isCustomInsert(sm, store);
+ break;
+ case UPDATE:
+ custom = fields[i].isCustomUpdate(sm, store);
+ break;
+ case DELETE:
+ custom = fields[i].isCustomDelete(sm, store);
+ break;
+ }
+
+ if (!Boolean.FALSE.equals(custom))
+ hasCustom = true;
+ if (!Boolean.TRUE.equals(custom))
+ hasStd = true;
+ }
+
+ if (hasCustom && hasStd)
+ return null;
+ return (hasCustom) ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ public void customInsert(OpenJPAStateManager sm, JDBCStore store)
+ throws SQLException {
+ OpenJPAStateManager em = store.getContext().getStateManager
+ (sm.fetchObject(field.getIndex()));
+ if (em == null)
+ em = new NullEmbeddedStateManager(sm, field);
+ FieldMapping[] fields = field.getEmbeddedMapping().getFieldMappings();
+ for (int i = 0; i < fields.length; i++)
+ if (!Boolean.FALSE.equals(fields[i].isCustomInsert(em, store)))
+ fields[i].customInsert(em, store);
+ }
+
+ public void customUpdate(OpenJPAStateManager sm, JDBCStore store)
+ throws SQLException {
+ OpenJPAStateManager em = store.getContext().getStateManager
+ (sm.fetchObject(field.getIndex()));
+ if (em == null)
+ em = new NullEmbeddedStateManager(sm, field);
+ FieldMapping[] fields = field.getEmbeddedMapping().getFieldMappings();
+ for (int i = 0; i < fields.length; i++)
+ if (em.getDirty().get(i)
+ && !em.getFlushed().get(i)
+ && !Boolean.FALSE.equals(fields[i].isCustomUpdate(em, store)))
+ fields[i].customUpdate(em, store);
+ }
+
+ public void customDelete(OpenJPAStateManager sm, JDBCStore store)
+ throws SQLException {
+ OpenJPAStateManager em = store.getContext().getStateManager
+ (sm.fetchObject(field.getIndex()));
+ if (em == null)
+ em = new NullEmbeddedStateManager(sm, field);
+ FieldMapping[] fields = field.getEmbeddedMapping().getFieldMappings();
+ for (int i = 0; i < fields.length; i++)
+ if (!Boolean.FALSE.equals(fields[i].isCustomDelete(em, store)))
+ fields[i].customDelete(em, store);
+ }
+
+ public int supportsSelect(Select sel, int type, OpenJPAStateManager sm,
+ JDBCStore store, JDBCFetchConfiguration fetch) {
+ if (type == Select.TYPE_JOINLESS && sel.isSelected(field.getTable()))
+ return 1;
+ return 0;
+ }
+
+ public int select(Select sel, OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, int eagerMode) {
+ Joins joins = field.join(sel);
+ sel.select(field.getColumns(), joins); // null indicator
+
+ // limit eager mode to join b/c at this point the select has been
+ // modified and an attempt to clone it for a to-many eager select can
+ // result in a clone that produces invalid SQL
+ eagerMode = Math.min(eagerMode, JDBCFetchConfiguration.EAGER_JOIN);
+ sel.select(field.getEmbeddedMapping(), sel.SUBS_EXACT, store,
+ fetchState, eagerMode, joins);
+ return 1;
+ }
+
+ public void load(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, Result res)
+ throws SQLException {
+ Boolean isNull = indicatesNull(res);
+ if (isNull == null)
+ return;
+
+ if (Boolean.TRUE.equals(isNull)) {
+ sm.storeObject(field.getIndex(), null);
+ return;
+ }
+
+ //### note: without a null indicator column, the above indicatesNull()
+ //### call will always return false, meaning we always have to assume
+ //### we selected the embedded object fields and load the object
+ //### immediately; this will be inefficient when the embedded object
+ //### was not selected after all
+
+ StoreContext ctx = store.getContext();
+ OpenJPAStateManager em = ctx.embed(null, null, sm, field);
+ sm.storeObject(field.getIndex(), em.getManagedInstance());
+
+ FieldMapping[] fields = field.getEmbeddedMapping().getFieldMappings();
+ Object eres, processed;
+ boolean loaded = false;
+ for (int i = 0; i < fields.length; i++) {
+ eres = res.getEager(fields[i]);
+ res.startDataRequest(fields[i]);
+ try {
+ if (eres == res)
+ fields[i].loadEagerJoin(em, store, fetchState, res);
+ else if (eres != null) {
+ processed =
+ fields[i].loadEagerParallel(em, store, fetchState,
+ eres);
+ if (processed != eres)
+ res.putEager(fields[i], processed);
+ } else
+ fields[i].load(em, store, fetchState, res);
+ loaded |= em.getLoaded().get(i);
+ } finally {
+ res.endDataRequest();
+ }
+ }
+
+ // after loading everything from result, load the rest of the
+ // configured fields
+ if (loaded)
+ em.load(fetchState);
+ }
+
+ /**
+ * Return whether the given result indicates that the embedded value is
+ * null.
+ *
+ * @return {@link Boolean#TRUE} if the value is null, {@link Boolean#FALSE}
+ * if it is not, or <code>null</code> if the result does not
+ * contain the embedded value
+ */
+ private Boolean indicatesNull(Result res)
+ throws SQLException {
+ Column[] cols = field.getColumns();
+ if (cols.length != 1)
+ return Boolean.FALSE;
+ if (!res.contains(cols[0]))
+ return null;
+
+ Object obj = res.getObject(cols[0], -1, (Object) null);
+ if (((EmbeddedClassStrategy) field.getEmbeddedMapping().getStrategy()).
+ indicatesNull(obj))
+ return Boolean.TRUE;
+ return Boolean.FALSE;
+ }
+
+ public Object toDataStoreValue(Object val, JDBCStore store) {
+ ClassMapping type = field.getTypeMapping();
+ return type.toDataStoreValue(val, type.getPrimaryKeyColumns(), store);
+ }
+
+ public void appendIsNull(SQLBuffer sql, Select sel, Joins joins) {
+ appendTestNull(sql, sel, joins, true);
+ }
+
+ public void appendIsNotNull(SQLBuffer sql, Select sel, Joins joins) {
+ appendTestNull(sql, sel, joins, false);
+ }
+
+ /**
+ * Append SQL to test whether the embedded object is null.
+ */
+ private void appendTestNull(SQLBuffer sql, Select sel, Joins joins,
+ boolean isNull) {
+ Column[] cols = field.getColumns();
+ if (cols.length != 1) {
+ if (isNull)
+ sql.append("1 <> 1");
+ else
+ sql.append("1 = 1");
+ return;
+ }
+
+ Object val;
+ if (cols[0].isNotNull()) {
+ if (_synthetic || cols[0].getDefaultString() == null)
+ val = JavaSQLTypes.getEmptyValue(cols[0].getJavaType());
+ else
+ val = cols[0].getDefault();
+ } else
+ val = null;
+
+ joins = join(joins, false);
+ sql.append(sel.getColumnAlias(cols[0], joins));
+ if (isNull && val == null)
+ sql.append(" IS ");
+ else if (isNull)
+ sql.append(" = ");
+ else if (val == null)
+ sql.append(" IS NOT ");
+ else
+ sql.append(" <> ");
+ sql.appendValue(val, cols[0]);
+ }
+
+ public Joins join(Joins joins, boolean forceOuter) {
+ return field.join(joins, forceOuter, false);
+ }
+
+ public Object loadProjection(JDBCStore store, JDBCFetchState fetchState,
+ Result res, Joins joins)
+ throws SQLException {
+ throw new UserException(_loc.get("cant-project-owned", field));
+ }
+
+ /**
+ * State manager that represents a null embedded object.
+ * Used to update embedded fields when the embedded value is null. This
+ * state manager doesn't require access to the old embedded value, because
+ * all updates are flushed before all deletes, so all foreign keys will
+ * be properly nulled before the related object is deleted. However, this
+ * state manager should not be used if possible when the parent object is
+ * being deleted; in that case having the original embedded state manager
+ * is preferable so that it can set foreign key relations to order DELETE
+ * statements to meet constraints.
+ */
+ private static class NullEmbeddedStateManager
+ implements OpenJPAStateManager {
+
+ private static final BitSet EMPTY_BITSET = new BitSet();
+
+ private final OpenJPAStateManager _owner;
+ private final ValueMetaData _vmd;
+ private BitSet _full = null;
+
+ /**
+ * Constructor; supply the owner of the null/deleted embedded value,
+ * and the value metadata.
+ */
+ public NullEmbeddedStateManager(OpenJPAStateManager owner,
+ ValueMetaData vmd) {
+ _owner = owner;
+ _vmd = vmd;
+ }
+
+ public void initialize(Class forType, PCState state) {
+ throw new InternalException();
+ }
+
+ public void load(FetchState fetchState) {
+ throw new InternalException();
+ }
+
+ public boolean assignObjectId(boolean flush) {
+ throw new InternalException();
+ }
+
+ public Object getManagedInstance() {
+ return null;
+ }
+
+ public PersistenceCapable getPersistenceCapable() {
+ return null;
+ }
+
+ public ClassMetaData getMetaData() {
+ return _vmd.getEmbeddedMetaData();
+ }
+
+ public OpenJPAStateManager getOwner() {
+ return _owner;
+ }
+
+ public ValueMetaData getOwnerMetaData() {
+ return _vmd;
+ }
+
+ public boolean isEmbedded() {
+ return true;
+ }
+
+ public boolean isTransactional() {
+ return true;
+ }
+
+ public boolean isPersistent() {
+ return true;
+ }
+
+ public boolean isNew() {
+ return _owner.isNew();
+ }
+
+ public boolean isDeleted() {
+ return _owner.isDeleted();
+ }
+
+ public boolean isDetached() {
+ return _owner.isDetached();
+ }
+
+ public boolean isVersionUpdateRequired() {
+ return _owner.isVersionUpdateRequired();
+ }
+
+ public boolean isVersionCheckRequired() {
+ return _owner.isVersionCheckRequired();
+ }
+
+ public boolean isDirty() {
+ return true;
+ }
+
+ public boolean isFlushed() {
+ return _owner.isFlushed();
+ }
+
+ public boolean isFlushedDirty() {
+ return isFlushed();
+ }
+
+ public BitSet getLoaded() {
+ // consider everything loaded
+ if (_full == null) {
+ FieldMetaData[] fmds = _vmd.getEmbeddedMetaData().getFields();
+ _full = new BitSet(fmds.length);
+ for (int i = 0; i < fmds.length; i++)
+ _full.set(i);
+ }
+ return _full;
+ }
+
+ public BitSet getDirty() {
+ // consider everything dirty
+ if (_full == null) {
+ FieldMetaData[] fmds = _vmd.getEmbeddedMetaData().getFields();
+ _full = new BitSet(fmds.length);
+ for (int i = 0; i < fmds.length; i++)
+ _full.set(i);
+ }
+ return _full;
+ }
+
+ public BitSet getFlushed() {
+ return EMPTY_BITSET;
+ }
+
+ public BitSet getUnloaded(FetchState fetchState) {
+ throw new InternalException();
+ }
+
+ public Object newProxy(int field) {
+ throw new InternalException();
+ }
+
+ public Object newFieldProxy(int field) {
+ throw new InternalException();
+ }
+
+ public boolean isDefaultValue(int field) {
+ return true;
+ }
+
+ public StoreContext getContext() {
+ return _owner.getContext();
+ }
+
+ public Object getId() {
+ return _owner.getId();
+ }
+
+ public Object getObjectId() {
+ return _owner.getObjectId();
+ }
+
+ public void setObjectId(Object oid) {
+ throw new InternalException();
+ }
+
+ public Object getLock() {
+ return null;
+ }
+
+ public void setLock(Object lock) {
+ throw new InternalException();
+ }
+
+ public Object getVersion() {
+ return null;
+ }
+
+ public void setVersion(Object version) {
+ throw new InternalException();
+ }
+
+ public void setNextVersion(Object version) {
+ throw new InternalException();
+ }
+
+ public PCState getPCState() {
+ return (_owner.isDeleted()) ? PCState.EDELETED : PCState.ECOPY;
+ }
+
+ public Object getImplData() {
+ return null;
+ }
+
+ public Object setImplData(Object data, boolean cacheable) {
+ throw new InternalException();
+ }
+
+ public boolean isImplDataCacheable() {
+ return false;
+ }
+
+ public Object getImplData(int field) {
+ return null;
+ }
+
+ public Object setImplData(int field, Object data) {
+ throw new InternalException();
+ }
+
+ public boolean isImplDataCacheable(int field) {
+ return false;
+ }
+
+ public Object getIntermediate(int field) {
+ return null;
+ }
+
+ public void setIntermediate(int field, Object value) {
+ throw new InternalException();
+ }
+
+ public boolean fetchBooleanField(int field) {
+ return false;
+ }
+
+ public byte fetchByteField(int field) {
+ return (byte) 0;
+ }
+
+ public char fetchCharField(int field) {
+ return (char) 0;
+ }
+
+ public double fetchDoubleField(int field) {
+ return 0D;
+ }
+
+ public float fetchFloatField(int field) {
+ return 0F;
+ }
+
+ public int fetchIntField(int field) {
+ return 0;
+ }
+
+ public long fetchLongField(int field) {
+ return 0L;
+ }
+
+ public Object fetchObjectField(int field) {
+ return null;
+ }
+
+ public short fetchShortField(int field) {
+ return (short) 0;
+ }
+
+ public String fetchStringField(int field) {
+ return null;
+ }
+
+ public Object fetchField(int field, boolean transitions) {
+ return null;
+ }
+
+ public void storeBooleanField(int field, boolean externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeByteField(int field, byte externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeCharField(int field, char externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeDoubleField(int field, double externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeFloatField(int field, float externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeIntField(int field, int externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeLongField(int field, long externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeObjectField(int field, Object externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeShortField(int field, short externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeStringField(int field, String externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeField(int field, Object value) {
+ throw new InternalException();
+ }
+
+ public boolean fetchBoolean(int field) {
+ return false;
+ }
+
+ public byte fetchByte(int field) {
+ return (byte) 0;
+ }
+
+ public char fetchChar(int field) {
+ return (char) 0;
+ }
+
+ public double fetchDouble(int field) {
+ return 0D;
+ }
+
+ public float fetchFloat(int field) {
+ return 0F;
+ }
+
+ public int fetchInt(int field) {
+ return 0;
+ }
+
+ public long fetchLong(int field) {
+ return 0L;
+ }
+
+ public Object fetchObject(int field) {
+ return null;
+ }
+
+ public short fetchShort(int field) {
+ return (short) 0;
+ }
+
+ public String fetchString(int field) {
+ return null;
+ }
+
+ public Object fetch(int field) {
+ return null;
+ }
+
+ public void storeBoolean(int field, boolean externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeByte(int field, byte externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeChar(int field, char externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeDouble(int field, double externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeFloat(int field, float externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeInt(int field, int externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeLong(int field, long externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeObject(int field, Object externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeShort(int field, short externalVal) {
+ throw new InternalException();
+ }
+
+ public void storeString(int field, String externalVal) {
+ throw new InternalException();
+ }
+
+ public void store(int field, Object value) {
+ throw new InternalException();
+ }
+
+ public Object fetchInitialField(int field) {
+ throw new InternalException();
+ }
+
+ public void dirty(int field) {
+ throw new InternalException();
+ }
+
+ public void removed(int field, Object removed, boolean key) {
+ throw new InternalException();
+ }
+
+ public boolean beforeRefresh(boolean refreshAll) {
+ throw new InternalException();
+ }
+
+ public void setRemote(int field, Object value) {
+ throw new InternalException();
+ }
+
+ ///////////////////////////////
+ // StateManager implementation
+ ///////////////////////////////
+
+ public byte replaceFlags() {
+ throw new InternalException();
+ }
+
+ public StateManager replaceStateManager(StateManager sm) {
+ throw new InternalException();
+ }
+
+ public Object getGenericContext() {
+ return getContext();
+ }
+
+ public void dirty(String field) {
+ throw new InternalException();
+ }
+
+ public Object fetchObjectId() {
+ return getObjectId();
+ }
+
+ public void accessingField(int field) {
+ }
+
+ public boolean serializing() {
+ throw new InternalException();
+ }
+
+ public boolean writeDetached(ObjectOutput out) {
+ throw new InternalException();
+ }
+
+ public void proxyDetachedDeserialized(int idx) {
+ throw new InternalException();
+ }
+
+ public void settingBooleanField(PersistenceCapable pc, int field,
+ boolean val1, boolean val2, int set) {
+ throw new InternalException();
+ }
+
+ public void settingCharField(PersistenceCapable pc, int field,
+ char val1, char val2, int set) {
+ throw new InternalException();
+ }
+
+ public void settingByteField(PersistenceCapable pc, int field,
+ byte val1, byte val2, int set) {
+ throw new InternalException();
+ }
+
+ public void settingShortField(PersistenceCapable pc, int field,
+ short val1, short val2, int set) {
+ throw new InternalException();
+ }
+
+ public void settingIntField(PersistenceCapable pc, int field,
+ int val1, int val2, int set) {
+ throw new InternalException();
+ }
+
+ public void settingLongField(PersistenceCapable pc, int field,
+ long val1, long val2, int set) {
+ throw new InternalException();
+ }
+
+ public void settingFloatField(PersistenceCapable pc, int field,
+ float val1, float val2, int set) {
+ throw new InternalException();
+ }
+
+ public void settingDoubleField(PersistenceCapable pc, int field,
+ double val1, double val2, int set) {
+ throw new InternalException();
+ }
+
+ public void settingStringField(PersistenceCapable pc, int field,
+ String val1, String val2, int set) {
+ throw new InternalException();
+ }
+
+ public void settingObjectField(PersistenceCapable pc, int field,
+ Object val1, Object val2, int set) {
+ throw new InternalException();
+ }
+
+ public void providedBooleanField(PersistenceCapable pc, int field,
+ boolean val) {
+ throw new InternalException();
+ }
+
+ public void providedCharField(PersistenceCapable pc, int field,
+ char val) {
+ throw new InternalException();
+ }
+
+ public void providedByteField(PersistenceCapable pc, int field,
+ byte val) {
+ throw new InternalException();
+ }
+
+ public void providedShortField(PersistenceCapable pc, int field,
+ short val) {
+ throw new InternalException();
+ }
+
+ public void providedIntField(PersistenceCapable pc, int field,
+ int val) {
+ throw new InternalException();
+ }
+
+ public void providedLongField(PersistenceCapable pc, int field,
+ long val) {
+ throw new InternalException();
+ }
+
+ public void providedFloatField(PersistenceCapable pc, int field,
+ float val) {
+ throw new InternalException();
+ }
+
+ public void providedDoubleField(PersistenceCapable pc, int field,
+ double val) {
+ throw new InternalException();
+ }
+
+ public void providedStringField(PersistenceCapable pc, int field,
+ String val) {
+ throw new InternalException();
+ }
+
+ public void providedObjectField(PersistenceCapable pc, int field,
+ Object val) {
+ throw new InternalException();
+ }
+
+ public boolean replaceBooleanField(PersistenceCapable pc, int field) {
+ throw new InternalException();
+ }
+
+ public char replaceCharField(PersistenceCapable pc, int field) {
+ throw new InternalException();
+ }
+
+ public byte replaceByteField(PersistenceCapable pc, int field) {
+ throw new InternalException();
+ }
+
+ public short replaceShortField(PersistenceCapable pc, int field) {
+ throw new InternalException();
+ }
+
+ public int replaceIntField(PersistenceCapable pc, int field) {
+ throw new InternalException();
+ }
+
+ public long replaceLongField(PersistenceCapable pc, int field) {
+ throw new InternalException();
+ }
+
+ public float replaceFloatField(PersistenceCapable pc, int field) {
+ throw new InternalException();
+ }
+
+ public double replaceDoubleField(PersistenceCapable pc, int field) {
+ throw new InternalException();
+ }
+
+ public String replaceStringField(PersistenceCapable pc, int field) {
+ throw new InternalException();
+ }
+
+ public Object replaceObjectField(PersistenceCapable pc, int field) {
+ throw new InternalException();
+ }
+ }
+
+ /**
+ * Special row manager type that unwraps embedded objects.
+ */
+ private static class EmbeddedRowManager
+ implements RowManager {
+
+ private final RowManager _rm;
+ private final Row _row;
+
+ public EmbeddedRowManager(RowManager delegate, Row row) {
+ _rm = delegate;
+ _row = (row == null) ? null : new EmbeddedRow(row);
+ }
+
+ public boolean hasAutoAssignConstraints() {
+ return false;
+ }
+
+ public Collection getInserts() {
+ throw new InternalException();
+ }
+
+ public Collection getUpdates() {
+ throw new InternalException();
+ }
+
+ public Collection getDeletes() {
+ throw new InternalException();
+ }
+
+ public Collection getSecondaryUpdates() {
+ throw new InternalException();
+ }
+
+ public Collection getSecondaryDeletes() {
+ throw new InternalException();
+ }
+
+ public Collection getAllRowUpdates() {
+ throw new InternalException();
+ }
+
+ public Collection getAllRowDeletes() {
+ throw new InternalException();
+ }
+
+ public Row getRow(Table table, int action, OpenJPAStateManager sm,
+ boolean create) {
+ while (sm != null && sm.getOwner() != null)
+ sm = sm.getOwner();
+ if (_row != null && table == _row.getTable()
+ && action == _row.getAction())
+ return _row;
+ return new EmbeddedRow(_rm.getRow(table, action, sm, create));
+ }
+
+ public Row getSecondaryRow(Table table, int action) {
+ return new EmbeddedRow(_rm.getSecondaryRow(table, action));
+ }
+
+ public void flushSecondaryRow(Row row)
+ throws SQLException {
+ _rm.flushSecondaryRow(((EmbeddedRow) row).getDelegate());
+ }
+
+ public Row getAllRows(Table table, int action) {
+ return new EmbeddedRow(_rm.getAllRows(table, action));
+ }
+
+ public void flushAllRows(Row row)
+ throws SQLException {
+ _rm.flushAllRows(((EmbeddedRow) row).getDelegate());
+ }
+ }
+
+ /**
+ * Special row type that unwraps embedded objects.
+ */
+ private static class EmbeddedRow
+ implements Row {
+
+ private final Row _row;
+
+ public EmbeddedRow(Row delegate) {
+ _row = delegate;
+ }
+
+ public Row getDelegate() {
+ return _row;
+ }
+
+ public boolean isValid() {
+ return _row.isValid();
+ }
+
+ public void setValid(boolean valid) {
+ _row.setValid(valid);
+ }
+
+ public void setPrimaryKey(OpenJPAStateManager sm)
+ throws SQLException {
+ _row.setPrimaryKey(getOwner(sm));
+ }
+
+ public void setPrimaryKey(ColumnIO io, OpenJPAStateManager sm)
+ throws SQLException {
+ _row.setPrimaryKey(io, getOwner(sm));
+ }
+
+ public void wherePrimaryKey(OpenJPAStateManager sm)
+ throws SQLException {
+ _row.wherePrimaryKey(getOwner(sm));
+ }
+
+ public void setForeignKey(ForeignKey fk, OpenJPAStateManager sm)
+ throws SQLException {
+ _row.setForeignKey(fk, getOwner(sm));
+ }
+
+ public void setForeignKey(ForeignKey fk, ColumnIO io,
+ OpenJPAStateManager sm)
+ throws SQLException {
+ _row.setForeignKey(fk, io, getOwner(sm));
+ }
+
+ public void whereForeignKey(ForeignKey fk, OpenJPAStateManager sm)
+ throws SQLException {
+ _row.whereForeignKey(fk, getOwner(sm));
+ }
+
+ public void setRelationId(Column col, OpenJPAStateManager sm,
+ RelationId rel)
+ throws SQLException {
+ _row.setRelationId(col, getOwner(sm), rel);
+ }
+
+ private OpenJPAStateManager getOwner(OpenJPAStateManager sm) {
+ while (sm != null && sm.getOwner() != null)
+ sm = sm.getOwner();
+ return sm;
+ }
+
+ ////////////////////////
+ // Pass-through methods
+ ////////////////////////
+
+ public Table getTable() {
+ return _row.getTable();
+ }
+
+ public int getAction() {
+ return _row.getAction();
+ }
+
+ public Object getFailedObject() {
+ return _row.getFailedObject();
+ }
+
+ public void setFailedObject(Object failed) {
+ _row.setFailedObject(failed);
+ }
+
+ public OpenJPAStateManager getPrimaryKey() {
+ return _row.getPrimaryKey();
+ }
+
+ public void setArray(Column col, Array val)
+ throws SQLException {
+ _row.setArray(col, val);
+ }
+
+ public void setAsciiStream(Column col, InputStream val, int length)
+ throws SQLException {
+ _row.setAsciiStream(col, val, length);
+ }
+
+ public void setBigDecimal(Column col, BigDecimal val)
+ throws SQLException {
+ _row.setBigDecimal(col, val);
+ }
+
+ public void setBigInteger(Column col, BigInteger val)
+ throws SQLException {
+ _row.setBigInteger(col, val);
+ }
+
+ public void setBinaryStream(Column col, InputStream val, int length)
+ throws SQLException {
+ _row.setBinaryStream(col, val, length);
+ }
+
+ public void setBlob(Column col, Blob val)
+ throws SQLException {
+ _row.setBlob(col, val);
+ }
+
+ public void setBoolean(Column col, boolean val)
+ throws SQLException {
+ _row.setBoolean(col, val);
+ }
+
+ public void setByte(Column col, byte val)
+ throws SQLException {
+ _row.setByte(col, val);
+ }
+
+ public void setBytes(Column col, byte[] val)
+ throws SQLException {
+ _row.setBytes(col, val);
+ }
+
+ public void setCalendar(Column col, Calendar val)
+ throws SQLException {
+ _row.setCalendar(col, val);
+ }
+
+ public void setChar(Column col, char val)
+ throws SQLException {
+ _row.setChar(col, val);
+ }
+
+ public void setCharacterStream(Column col, Reader val, int length)
+ throws SQLException {
+ _row.setCharacterStream(col, val, length);
+ }
+
+ public void setClob(Column col, Clob val)
+ throws SQLException {
+ _row.setClob(col, val);
+ }
+
+ public void setDate(Column col, Date val)
+ throws SQLException {
+ _row.setDate(col, val);
+ }
+
+ public void setDate(Column col, java.sql.Date val, Calendar cal)
+ throws SQLException {
+ _row.setDate(col, val, cal);
+ }
+
+ public void setDouble(Column col, double val)
+ throws SQLException {
+ _row.setDouble(col, val);
+ }
+
+ public void setFloat(Column col, float val)
+ throws SQLException {
+ _row.setFloat(col, val);
+ }
+
+ public void setInt(Column col, int val)
+ throws SQLException {
+ _row.setInt(col, val);
+ }
+
+ public void setLong(Column col, long val)
+ throws SQLException {
+ _row.setLong(col, val);
+ }
+
+ public void setLocale(Column col, Locale val)
+ throws SQLException {
+ _row.setLocale(col, val);
+ }
+
+ public void setNull(Column col)
+ throws SQLException {
+ _row.setNull(col);
+ }
+
+ public void setNull(Column col, boolean overrideDefault)
+ throws SQLException {
+ _row.setNull(col, overrideDefault);
+ }
+
+ public void setNumber(Column col, Number val)
+ throws SQLException {
+ _row.setNumber(col, val);
+ }
+
+ public void setObject(Column col, Object val)
+ throws SQLException {
+ _row.setObject(col, val);
+ }
+
+ public void setRaw(Column col, String val)
+ throws SQLException {
+ _row.setRaw(col, val);
+ }
+
+ public void setShort(Column col, short val)
+ throws SQLException {
+ _row.setShort(col, val);
+ }
+
+ public void setString(Column col, String val)
+ throws SQLException {
+ _row.setString(col, val);
+ }
+
+ public void setTime(Column col, Time val, Calendar cal)
+ throws SQLException {
+ _row.setTime(col, val, cal);
+ }
+
+ public void setTimestamp(Column col, Timestamp val, Calendar cal)
+ throws SQLException {
+ _row.setTimestamp(col, val, cal);
+ }
+
+ public void whereArray(Column col, Array val)
+ throws SQLException {
+ _row.whereArray(col, val);
+ }
+
+ public void whereAsciiStream(Column col, InputStream val, int length)
+ throws SQLException {
+ _row.whereAsciiStream(col, val, length);
+ }
+
+ public void whereBigDecimal(Column col, BigDecimal val)
+ throws SQLException {
+ _row.whereBigDecimal(col, val);
+ }
+
+ public void whereBigInteger(Column col, BigInteger val)
+ throws SQLException {
+ _row.whereBigInteger(col, val);
+ }
+
+ public void whereBinaryStream(Column col, InputStream val, int length)
+ throws SQLException {
+ _row.whereBinaryStream(col, val, length);
+ }
+
+ public void whereBlob(Column col, Blob val)
+ throws SQLException {
+ _row.whereBlob(col, val);
+ }
+
+ public void whereBoolean(Column col, boolean val)
+ throws SQLException {
+ _row.whereBoolean(col, val);
+ }
+
+ public void whereByte(Column col, byte val)
+ throws SQLException {
+ _row.whereByte(col, val);
+ }
+
+ public void whereBytes(Column col, byte[] val)
+ throws SQLException {
+ _row.whereBytes(col, val);
+ }
+
+ public void whereCalendar(Column col, Calendar val)
+ throws SQLException {
+ _row.whereCalendar(col, val);
+ }
+
+ public void whereChar(Column col, char val)
+ throws SQLException {
+ _row.whereChar(col, val);
+ }
+
+ public void whereCharacterStream(Column col, Reader val, int length)
+ throws SQLException {
+ _row.whereCharacterStream(col, val, length);
+ }
+
+ public void whereClob(Column col, Clob val)
+ throws SQLException {
+ _row.whereClob(col, val);
+ }
+
+ public void whereDate(Column col, Date val)
+ throws SQLException {
+ _row.whereDate(col, val);
+ }
+
+ public void whereDate(Column col, java.sql.Date val, Calendar cal)
+ throws SQLException {
+ _row.whereDate(col, val, cal);
+ }
+
+ public void whereDouble(Column col, double val)
+ throws SQLException {
+ _row.whereDouble(col, val);
+ }
+
+ public void whereFloat(Column col, float val)
+ throws SQLException {
+ _row.whereFloat(col, val);
+ }
+
+ public void whereInt(Column col, int val)
+ throws SQLException {
+ _row.whereInt(col, val);
+ }
+
+ public void whereLong(Column col, long val)
+ throws SQLException {
+ _row.whereLong(col, val);
+ }
+
+ public void whereLocale(Column col, Locale val)
+ throws SQLException {
+ _row.whereLocale(col, val);
+ }
+
+ public void whereNull(Column col)
+ throws SQLException {
+ _row.whereNull(col);
+ }
+
+ public void whereNumber(Column col, Number val)
+ throws SQLException {
+ _row.whereNumber(col, val);
+ }
+
+ public void whereObject(Column col, Object val)
+ throws SQLException {
+ _row.whereObject(col, val);
+ }
+
+ public void whereRaw(Column col, String val)
+ throws SQLException {
+ _row.whereRaw(col, val);
+ }
+
+ public void whereShort(Column col, short val)
+ throws SQLException {
+ _row.whereShort(col, val);
+ }
+
+ public void whereString(Column col, String val)
+ throws SQLException {
+ _row.whereString(col, val);
+ }
+
+ public void whereTime(Column col, Time val, Calendar cal)
+ throws SQLException {
+ _row.whereTime(col, val, cal);
+ }
+
+ public void whereTimestamp(Column col, Timestamp val, Calendar cal)
+ throws SQLException {
+ _row.whereTimestamp(col, val, cal);
+ }
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedValueHandler.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedValueHandler.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedValueHandler.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedValueHandler.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.Embeddable;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.ValueMapping;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ColumnIO;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.MetaDataException;
+
+/**
+ * Base class for embedded value handlers.
+ *
+ * @author Abe White
+ * @since 4.0
+ */
+public abstract class EmbedValueHandler
+ extends AbstractValueHandler {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (EmbedValueHandler.class);
+
+ /**
+ * Maps embedded value and gathers columns and arguments into given lists.
+ */
+ protected void map(ValueMapping vm, String name, ColumnIO io,
+ boolean adapt, List cols, List args) {
+ // have to resolve embedded value to collect its columns
+ vm.getEmbeddedMapping().resolve(vm.MODE_META | vm.MODE_MAPPING);
+
+ // gather columns and result arguments
+ FieldMapping[] fms = vm.getEmbeddedMapping().getFieldMappings();
+ Column[] curCols;
+ Object[] curArgs;
+ ColumnIO curIO;
+ for (int i = 0; i < fms.length; i++) {
+ if (fms[i].getManagement() != FieldMapping.MANAGE_PERSISTENT)
+ continue;
+ if (!(fms[i].getStrategy()instanceof Embeddable))
+ throw new MetaDataException(_loc.get("not-embeddable",
+ vm, fms[i]));
+
+ curCols = ((Embeddable) fms[i].getStrategy()).getColumns();
+ curIO = ((Embeddable) fms[i].getStrategy()).getColumnIO();
+ for (int j = 0; j < curCols.length; j++) {
+ io.setInsertable(cols.size(), curIO.isInsertable(j, false));
+ io.setNullInsertable(cols.size(),
+ curIO.isInsertable(j, true));
+ io.setUpdatable(cols.size(), curIO.isUpdatable(j, false));
+ io.setNullUpdatable(cols.size(), curIO.isUpdatable(j, true));
+ cols.add(curCols[j]);
+ }
+
+ curArgs = ((Embeddable) fms[i].getStrategy()).getResultArguments();
+ if (curCols.length == 1)
+ args.add(curArgs);
+ else if (curCols.length > 1)
+ for (int j = 0; j < curCols.length; j++)
+ args.add((curArgs == null) ? null
+ : ((Object[]) curArgs)[j]);
+ }
+ }
+
+ /**
+ * Helper to convert an object value to its datastore equivalent.
+ *
+ * @param em state manager for embedded object
+ * @param vm owning value
+ * @param store store manager
+ * @param cols embedded columns
+ * @param rval return array if multiple columns
+ * @param idx index in columns array to start
+ */
+ protected Object toDataStoreValue(OpenJPAStateManager em, ValueMapping vm,
+ JDBCStore store, Column[] cols, Object rval, int idx) {
+ // set rest of columns from fields
+ FieldMapping[] fms = vm.getEmbeddedMapping().getFieldMappings();
+ Object cval;
+ Column[] ecols;
+ Embeddable embed;
+ for (int i = 0; i < fms.length; i++) {
+ if (fms[i].getManagement() != FieldMapping.MANAGE_PERSISTENT)
+ continue;
+ embed = (Embeddable) fms[i].getStrategy();
+ ecols = embed.getColumns();
+ if (ecols.length == 0)
+ continue;
+
+ cval = (em == null) ? null : em.fetch(i);
+ cval = embed.toEmbeddedDataStoreValue(cval, store);
+ if (cols.length == 1)
+ rval = cval;
+ else if (ecols.length == 1)
+ ((Object[]) rval)[idx++] = cval;
+ else {
+ System.arraycopy(cval, 0, rval, idx, ecols.length);
+ idx += ecols.length;
+ }
+ }
+ return rval;
+ }
+
+ /**
+ * Helper to convert a datastore value to its object equivalent.
+ *
+ * @param em state manager for embedded object
+ * @param vm owning value
+ * @param val datastore value
+ * @param store optional store manager
+ * @param fetchState optional fetch configuration
+ * @param cols embedded columns
+ * @param idx index in columns array to start
+ */
+ protected void toObjectValue(OpenJPAStateManager em, ValueMapping vm,
+ Object val, JDBCStore store, JDBCFetchState fetchState,
+ Column[] cols, int idx)
+ throws SQLException {
+ FieldMapping[] fms = vm.getEmbeddedMapping().getFieldMappings();
+ Embeddable embed;
+ Object cval;
+ Column[] ecols;
+ for (int i = 0; i < fms.length; i++) {
+ if (fms[i].getManagement() != FieldMapping.MANAGE_PERSISTENT)
+ continue;
+
+ embed = (Embeddable) fms[i].getStrategy();
+ ecols = embed.getColumns();
+ if (ecols.length == 0)
+ cval = null;
+ else if (idx == 0 && ecols.length == cols.length)
+ cval = val;
+ else if (ecols.length == 1)
+ cval = ((Object[]) val)[idx++];
+ else {
+ cval = new Object[ecols.length];
+ System.arraycopy(val, idx, cval, 0, ecols.length);
+ idx += ecols.length;
+ }
+
+ if (store != null)
+ embed.loadEmbedded(em, store, fetchState, cval);
+ else {
+ cval = embed.toEmbeddedObjectValue(cval);
+ em.store(fms[i].getIndex(), cval);
+ }
+ }
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedValueHandler.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbeddedClassStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbeddedClassStrategy.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbeddedClassStrategy.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbeddedClassStrategy.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.ClassMappingInfo;
+import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
+import org.apache.openjpa.jdbc.meta.ValueMapping;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.MetaDataException;
+
+/**
+ * Class mapping for embedded objects.
+ *
+ * @author Abe White
+ * @nojavadoc
+ */
+public class EmbeddedClassStrategy
+ extends AbstractClassStrategy {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (EmbeddedClassStrategy.class);
+
+ public void map(boolean adapt) {
+ ValueMapping vm = cls.getEmbeddingMapping();
+ if (vm == null || vm.getType() != cls.getDescribedType())
+ throw new MetaDataException(_loc.get("not-embed", cls));
+
+ ClassMappingInfo info = cls.getMappingInfo();
+ info.assertNoSchemaComponents(cls, true);
+
+ ClassMapping owner = vm.getFieldMapping().getDefiningMapping();
+ cls.setIdentityType(owner.getIdentityType());
+ cls.setObjectIdType(owner.getObjectIdType(),
+ owner.isObjectIdTypeShared());
+ cls.setTable(vm.getFieldMapping().getTable());
+ cls.setPrimaryKeyColumns(owner.getPrimaryKeyColumns());
+ cls.setColumnIO(owner.getColumnIO());
+ }
+
+ /**
+ * Return the proper synthetic null indicator value for the given instance.
+ */
+ public Object getNullIndicatorValue(OpenJPAStateManager sm) {
+ Column[] cols = cls.getEmbeddingMapping().getColumns();
+ if (cols.length != 1)
+ return null;
+ if (sm == null && !cols[0].isNotNull())
+ return null;
+ if (sm == null)
+ return JavaSQLTypes.getEmptyValue(cols[0].getJavaType());
+ return JavaSQLTypes.getNonEmptyValue(cols[0].getJavaType());
+ }
+
+ /**
+ * Return whether the given null indicator value means the object is null.
+ */
+ public boolean indicatesNull(Object val) {
+ Column[] cols = cls.getEmbeddingMapping().getColumns();
+ if (cols.length != 1)
+ return false;
+ if (val == null)
+ return true;
+ if (cols[0].isNotNull()
+ && val.equals(JavaSQLTypes.getEmptyValue(cols[0].getJavaType())))
+ return true;
+ if (cols[0].getDefaultString() != null
+ && val.toString().equals(cols[0].getDefaultString()))
+ return true;
+ return false;
+ }
+
+ public boolean isPrimaryKeyObjectId(boolean hasAll) {
+ return cls.getEmbeddingMapping().getFieldMapping().
+ getDefiningMapping().isPrimaryKeyObjectId(hasAll);
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbeddedClassStrategy.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/FlatClassStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/FlatClassStrategy.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/FlatClassStrategy.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/FlatClassStrategy.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.ClassMappingInfo;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.MetaDataException;
+
+/**
+ * Mapping for classes mapped to their superclass table.
+ *
+ * @author Abe White
+ */
+public class FlatClassStrategy
+ extends AbstractClassStrategy {
+
+ public static final String ALIAS = "flat";
+
+ private static final Localizer _loc = Localizer.forPackage
+ (FlatClassStrategy.class);
+
+ public String getAlias() {
+ return ALIAS;
+ }
+
+ public void map(boolean adapt) {
+ ClassMapping sup = cls.getMappedPCSuperclassMapping();
+ if (sup == null || cls.getEmbeddingMetaData() != null)
+ throw new MetaDataException(_loc.get("not-sub", cls));
+
+ ClassMappingInfo info = cls.getMappingInfo();
+ info.assertNoSchemaComponents(cls, true);
+
+ if (info.getTableName() != null) {
+ Table table = info.createTable(cls, null, null,
+ info.getTableName(), false);
+ if (table != sup.getTable())
+ throw new MetaDataException(_loc.get("flat-table", cls,
+ table.getFullName(), sup.getTable().getFullName()));
+ }
+
+ cls.setTable(sup.getTable());
+ cls.setPrimaryKeyColumns(sup.getPrimaryKeyColumns());
+ cls.setColumnIO(sup.getColumnIO());
+ }
+
+ public boolean isPrimaryKeyObjectId(boolean hasAll) {
+ return cls.getMappedPCSuperclassMapping().isPrimaryKeyObjectId(hasAll);
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/FlatClassStrategy.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/FullClassStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/FullClassStrategy.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/FullClassStrategy.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/FullClassStrategy.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.ClassMappingInfo;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.PrimaryKey;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.jdbc.sql.Row;
+import org.apache.openjpa.jdbc.sql.RowManager;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.meta.ValueStrategies;
+import org.apache.openjpa.util.MetaDataException;
+
+/**
+ * Mapping for when the class maps all fields to its own table.
+ *
+ * @author Abe White
+ */
+public class FullClassStrategy
+ extends AbstractClassStrategy {
+
+ public static final String ALIAS = "full";
+
+ private static final Localizer _loc = Localizer.forPackage
+ (FullClassStrategy.class);
+
+ public String getAlias() {
+ return ALIAS;
+ }
+
+ public void map(boolean adapt) {
+ if (cls.getEmbeddingMetaData() != null)
+ throw new MetaDataException(_loc.get("not-full", cls));
+
+ ClassMapping sup = cls.getMappedPCSuperclassMapping();
+ ClassMappingInfo info = cls.getMappingInfo();
+ if (sup != null && info.isJoinedSubclass())
+ throw new MetaDataException(_loc.get("not-full", cls));
+
+ info.assertNoJoin(cls, true);
+ info.assertNoForeignKey(cls, !adapt);
+ info.assertNoIndex(cls, false);
+ info.assertNoUnique(cls, false);
+
+ // find class table
+ Table table = info.getTable(cls, adapt);
+
+ // find primary key column
+ Column[] pkCols = null;
+ if (cls.getIdentityType() == cls.ID_DATASTORE) {
+ Column id = new Column();
+ id.setName("id");
+ id.setJavaType(JavaTypes.LONG);
+ if (cls.getIdentityStrategy() == ValueStrategies.AUTOASSIGN)
+ id.setAutoAssigned(true);
+ id.setNotNull(true);
+ pkCols = info.getDataStoreIdColumns(cls, new Column[]{ id },
+ table, adapt);
+ cls.setPrimaryKeyColumns(pkCols);
+ cls.setColumnIO(info.getColumnIO());
+ }
+ cls.setTable(table);
+
+ // add a primary key if we don't have one already
+ PrimaryKey pk = table.getPrimaryKey();
+ if (pk == null) {
+ String pkname = null;
+ if (adapt)
+ pkname = cls.getMappingRepository().getMappingDefaults().
+ getPrimaryKeyName(cls, table);
+ pk = table.addPrimaryKey(pkname);
+ pk.setLogical(!adapt);
+ if (pkCols != null)
+ pk.setColumns(pkCols);
+ }
+
+ // set joinable
+ if (cls.getIdentityType() == ClassMapping.ID_DATASTORE)
+ cls.setJoinable(cls.getPrimaryKeyColumns()[0],
+ new IdentityJoinable(cls));
+ }
+
+ public boolean supportsEagerSelect(Select sel, OpenJPAStateManager sm,
+ JDBCStore store, ClassMapping base, JDBCFetchConfiguration fetch) {
+ return false;
+ }
+
+ public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ Row row = rm.getRow(cls.getTable(), Row.ACTION_INSERT, sm, true);
+ if (cls.getIdentityType() == cls.ID_DATASTORE)
+ row.setPrimaryKey(cls.getColumnIO(), sm);
+ }
+
+ public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ Row row = rm.getRow(cls.getTable(), Row.ACTION_UPDATE, sm, false);
+ if (row != null)
+ row.wherePrimaryKey(sm);
+ }
+
+ public void delete(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ Row row = rm.getRow(cls.getTable(), Row.ACTION_DELETE, sm, true);
+ row.wherePrimaryKey(sm);
+ }
+
+ public boolean isPrimaryKeyObjectId(boolean hasAll) {
+ return true;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/FullClassStrategy.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,401 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.Embeddable;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.Joinable;
+import org.apache.openjpa.jdbc.meta.ValueHandler;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ColumnIO;
+import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.schema.PrimaryKey;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.Row;
+import org.apache.openjpa.jdbc.sql.RowManager;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.meta.ValueStrategies;
+import org.apache.openjpa.util.InternalException;
+import org.apache.openjpa.util.MetaDataException;
+
+/**
+ * Mapping for a single-valued field that delegates to a {@link ValueHandler}.
+ *
+ * @author Abe White
+ * @since 4.0
+ */
+public class HandlerFieldStrategy
+ extends AbstractFieldStrategy
+ implements Joinable, Embeddable {
+
+ private static final Object NULL = new Object();
+
+ private static final Localizer _loc = Localizer.forPackage
+ (HandlerFieldStrategy.class);
+
+ private Column[] _cols = null;
+ private ColumnIO _io = null;
+ private Object[] _args = null;
+ private boolean _load = false;
+ private boolean _lob = false;
+
+ public void map(boolean adapt) {
+ if (field.getHandler() == null)
+ throw new MetaDataException(_loc.get("no-handler", field));
+ assertNotMappedBy();
+
+ // map join key (if any)
+ field.mapJoin(adapt, false);
+ field.getKeyMapping().getValueInfo().assertNoSchemaComponents
+ (field.getKey(), !adapt);
+ field.getElementMapping().getValueInfo().assertNoSchemaComponents
+ (field.getElement(), !adapt);
+
+ _io = new ColumnIO();
+ _cols = HandlerStrategies.map(field, field.getName(), _io, adapt);
+ if (field.getValueStrategy() == ValueStrategies.AUTOASSIGN) {
+ // first see if any columns already marked autoassign; if not mark
+ // them all
+ boolean marked = false;
+ for (int i = 0; !marked && i < _cols.length; i++)
+ if (_cols[i].isAutoAssigned())
+ marked = true;
+ if (!marked)
+ for (int i = 0; i < _cols.length; i++)
+ _cols[i].setAutoAssigned(true);
+ }
+
+ // add primary key columns to table pk if logical
+ field.mapPrimaryKey(adapt);
+ PrimaryKey pk = field.getTable().getPrimaryKey();
+ if (field.isPrimaryKey() && pk != null && (adapt || pk.isLogical()))
+ for (int i = 0; i < _cols.length; i++)
+ pk.addColumn(_cols[i]);
+
+ // set joinable
+ if (!field.getHandler().objectValueRequiresLoad(field))
+ for (int i = 0; i < _cols.length; i++)
+ field.getDefiningMapping().setJoinable(_cols[i], this);
+ }
+
+ public void initialize() {
+ _load = field.getHandler().objectValueRequiresLoad(field);
+ if (_load)
+ field.setUsesIntermediate(true);
+ for (int i = 0; !_lob && i < _cols.length; i++)
+ _lob = _cols[i].isLob();
+
+ Object args = field.getHandler().getResultArgument(field);
+ if (args == null)
+ _args = null;
+ else if (_cols.length == 1)
+ _args = new Object[]{ args };
+ else
+ _args = (Object[]) args;
+ }
+
+ public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ Row row = field.getRow(sm, store, rm, Row.ACTION_INSERT);
+ if (row != null)
+ HandlerStrategies.set(field, sm.fetch(field.getIndex()), store,
+ row, _cols, _io, field.getNullValue() ==
+ FieldMapping.NULL_NONE);
+ }
+
+ public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ Row row = field.getRow(sm, store, rm, Row.ACTION_UPDATE);
+ if (row != null)
+ HandlerStrategies.set(field, sm.fetch(field.getIndex()), store,
+ row, _cols, _io, field.getNullValue() ==
+ FieldMapping.NULL_NONE);
+ }
+
+ public void delete(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ field.deleteRow(sm, store, rm);
+ }
+
+ public int supportsSelect(Select sel, int type, OpenJPAStateManager sm,
+ JDBCStore store, JDBCFetchConfiguration fetch) {
+ if ((type == Select.TYPE_JOINLESS && sel.isSelected(field.getTable()))
+ || (_load && type == sel.TYPE_TWO_PART))
+ return 1;
+ return 0;
+ }
+
+ public int select(Select sel, OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, int eagerMode) {
+ if (_cols.length == 0)
+ return -1;
+
+ if (sm != null && sm.getIntermediate(field.getIndex()) != null)
+ return -1;
+ if (sel.isDistinct() && _lob && !field.isPrimaryKey())
+ return -1;
+ sel.select(_cols, field.join(sel));
+ return 1;
+ }
+
+ public void load(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, Result res)
+ throws SQLException {
+ if (_cols.length == 0 || !res.containsAll(_cols))
+ return;
+
+ Object val = HandlerStrategies.loadDataStore(field, res, null, _cols);
+ if (!_load)
+ sm.store(field.getIndex(), field.getHandler().
+ toObjectValue(field, val));
+ else {
+ if (val == null)
+ val = NULL;
+ sm.setIntermediate(field.getIndex(), val);
+ }
+ }
+
+ public void load(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState)
+ throws SQLException {
+ // even if no columns, allow a handler to load a generated value
+ if (_cols.length == 0) {
+ if (_load)
+ sm.store(field.getIndex(), field.getHandler().
+ toObjectValue(field, null, sm, store, fetchState));
+ else
+ sm.store(field.getIndex(), field.getHandler().
+ toObjectValue(field, null));
+ return;
+ }
+
+ // load cached intermediate value?
+ if (_load) {
+ Object ds = sm.getIntermediate(field.getIndex());
+ if (ds != null) {
+ if (ds == NULL)
+ ds = null;
+ sm.store(field.getIndex(), field.getHandler().
+ toObjectValue(field, ds, sm, store, fetchState));
+ return;
+ }
+ }
+
+ Select sel = store.getSQLFactory().newSelect();
+ sel.select(_cols);
+ field.wherePrimaryKey(sel, sm, store);
+
+ Result res = sel.execute(store,
+ fetchState.getJDBCFetchConfiguration());
+ Object val = null;
+ try {
+ if (res.next())
+ val = HandlerStrategies.loadDataStore(field, res, null, _cols);
+ } finally {
+ res.close();
+ }
+
+ loadEmbedded(sm, store, fetchState, val);
+ }
+
+ public Object toDataStoreValue(Object val, JDBCStore store) {
+ return HandlerStrategies.toDataStoreValue(field, val, _cols, store);
+ }
+
+ public void appendIsNull(SQLBuffer sql, Select sel, Joins joins) {
+ joins = join(joins, false);
+ for (int i = 0; i < _cols.length; i++) {
+ if (i > 0)
+ sql.append(" AND ");
+ sql.append(sel.getColumnAlias(_cols[i], joins)).append(" IS ").
+ appendValue(null, _cols[i]);
+ }
+ }
+
+ public void appendIsNotNull(SQLBuffer sql, Select sel, Joins joins) {
+ joins = join(joins, false);
+ if (_cols.length > 1)
+ sql.append("(");
+ for (int i = 0; i < _cols.length; i++) {
+ if (i > 0)
+ sql.append(" OR ");
+ sql.append(sel.getColumnAlias(_cols[i], joins)).
+ append(" IS NOT ").appendValue(null, _cols[i]);
+ }
+ if (_cols.length > 1)
+ sql.append(")");
+ }
+
+ public Joins join(Joins joins, boolean forceOuter) {
+ return field.join(joins, forceOuter, false);
+ }
+
+ public Joins joinRelation(Joins joins, boolean forceOuter,
+ boolean traverse) {
+ if (traverse)
+ HandlerStrategies.assertJoinable(field);
+ return joins;
+ }
+
+ public Object loadProjection(JDBCStore store, JDBCFetchState fetchState,
+ Result res, Joins joins)
+ throws SQLException {
+ return HandlerStrategies.loadObject(field, null, store, fetchState, res,
+ joins, _cols, _load);
+ }
+
+ public boolean isVersionable() {
+ return !_lob && !field.isJoinOuter()
+ && field.getHandler().isVersionable(field);
+ }
+
+ public void where(OpenJPAStateManager sm, JDBCStore store, RowManager rm,
+ Object prevValue)
+ throws SQLException {
+ Row row = field.getRow(sm, store, rm, Row.ACTION_UPDATE);
+ if (row != null)
+ HandlerStrategies.where(field, prevValue, store, row, _cols);
+ }
+
+ ///////////////////////////
+ // Joinable implementation
+ ///////////////////////////
+
+ public int getFieldIndex() {
+ return field.getIndex();
+ }
+
+ public Object getPrimaryKeyValue(Result res, Column[] cols, ForeignKey fk,
+ Joins joins)
+ throws SQLException {
+ Column col;
+ Object val = null;
+ if (cols.length == 1) {
+ col = cols[0];
+ if (fk != null)
+ col = fk.getColumn(col);
+ val = res.getObject(col, field.getHandler().
+ getResultArgument(field), joins);
+ } else if (cols.length > 1) {
+ Object[] vals = new Object[cols.length];
+ Object[] args = (Object[]) field.getHandler().
+ getResultArgument(field);
+ for (int i = 0; i < vals.length; i++) {
+ col = cols[i];
+ if (fk != null)
+ col = fk.getColumn(col);
+ vals[i] = res.getObject(col, (args == null) ? null : args[i],
+ joins);
+ }
+ val = vals;
+ }
+ return field.getHandler().toObjectValue(field, val);
+ }
+
+ public Column[] getColumns() {
+ return _cols;
+ }
+
+ public Object[] getResultArguments() {
+ return _args;
+ }
+
+ public Object getJoinValue(Object fieldVal, Column col, JDBCStore store) {
+ Object val = HandlerStrategies.toDataStoreValue(field, fieldVal,
+ _cols, store);
+ if (val == null || _cols.length < 2)
+ return val;
+
+ for (int i = 0; i < _cols.length; i++)
+ if (_cols[i] == col)
+ return ((Object[]) val)[i];
+ throw new InternalException();
+ }
+
+ public Object getJoinValue(OpenJPAStateManager sm, Column col,
+ JDBCStore store) {
+ return getJoinValue(sm.fetch(field.getIndex()), col, store);
+ }
+
+ public void setAutoAssignedValue(OpenJPAStateManager sm, JDBCStore store,
+ Column col, Object autoInc) {
+ Object data;
+ if (_cols.length == 1)
+ data = autoInc;
+ else {
+ // multiple columns; have to get current value, replace this col's
+ // value with the given one, and reset
+ data = field.getHandler().toDataStoreValue(field,
+ sm.fetch(field.getIndex()), store);
+ if (data == null)
+ data = new Object[_cols.length];
+ for (int i = 0; i < _cols.length; i++) {
+ if (_cols[i] == col) {
+ ((Object[]) data)[i] = autoInc;
+ break;
+ }
+ }
+ }
+
+ Object val = field.getHandler().toObjectValue(field, data);
+ sm.store(field.getIndex(), val);
+ }
+
+ /////////////////////////////
+ // Embeddable implementation
+ /////////////////////////////
+
+ public ColumnIO getColumnIO() {
+ return _io;
+ }
+
+ public Object toEmbeddedDataStoreValue(Object val, JDBCStore store) {
+ // don't use HandlerStrategies.toDataStoreValue b/c we want relation ids
+ // to be represented by state managers, not the serialized id value
+ val = field.getHandler().toDataStoreValue(field, val, store);
+ if (val == null && _cols.length > 1)
+ return new Object[_cols.length];
+ return val;
+ }
+
+ public Object toEmbeddedObjectValue(Object val) {
+ if (!_load)
+ return field.getHandler().toObjectValue(field, val);
+ return UNSUPPORTED;
+ }
+
+ public void loadEmbedded(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, Object val)
+ throws SQLException {
+ if (val == null && _cols.length > 1)
+ val = new Object[_cols.length];
+ if (_load)
+ sm.store(field.getIndex(), field.getHandler().
+ toObjectValue(field, val, sm, store, fetchState));
+ else
+ sm.store(field.getIndex(), field.getHandler().
+ toObjectValue(field, val));
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerFieldStrategy.java
------------------------------------------------------------------------------
svn:executable = *