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 [11/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/Discriminator.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Discriminator.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Discriminator.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Discriminator.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,383 @@
+/*
+ * 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;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ColumnIO;
+import org.apache.openjpa.jdbc.schema.Index;
+import org.apache.openjpa.jdbc.schema.Schemas;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+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.log.Log;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.meta.MetaDataContext;
+import org.apache.openjpa.meta.MetaDataModes;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.util.InternalException;
+
+/**
+ * Handles determining the object class of database records.
+ *
+ * @author Abe White
+ */
+public class Discriminator
+ implements DiscriminatorStrategy, MetaDataContext, MetaDataModes {
+
+ /**
+ * Null discriminator value marker.
+ */
+ public static final Object NULL = new Object();
+
+ private static final Localizer _loc = Localizer.forPackage
+ (Discriminator.class);
+
+ private final ClassMapping _mapping;
+ private final DiscriminatorMappingInfo _info;
+ private DiscriminatorStrategy _strategy = null;
+ private int _resMode = MODE_NONE;
+
+ private Column[] _cols = Schemas.EMPTY_COLUMNS;
+ private ColumnIO _io = null;
+ private Index _idx = null;
+ private boolean _subsLoaded = false;
+ private Object _value = null;
+
+ /**
+ * Constructor. Supply owning mapping.
+ */
+ public Discriminator(ClassMapping mapping) {
+ _mapping = mapping;
+ _info = getMappingRepository().newMappingInfo(this);
+ }
+
+ public MetaDataRepository getRepository() {
+ return _mapping.getRepository();
+ }
+
+ public MappingRepository getMappingRepository() {
+ return _mapping.getMappingRepository();
+ }
+
+ /**
+ * Return the owning mapping.
+ */
+ public ClassMapping getClassMapping() {
+ return _mapping;
+ }
+
+ /**
+ * The strategy used for class discrimination.
+ */
+ public DiscriminatorStrategy getStrategy() {
+ return _strategy;
+ }
+
+ /**
+ * The strategy used for class discrimination. The <code>adapt</code>
+ * parameter determines whether to adapt when mapping the strategy;
+ * use null if the strategy should not be mapped.
+ */
+ public void setStrategy(DiscriminatorStrategy strategy, Boolean adapt) {
+ // set strategy first so we can access it during mapping
+ DiscriminatorStrategy orig = _strategy;
+ _strategy = strategy;
+ if (strategy != null) {
+ try {
+ strategy.setDiscriminator(this);
+ if (adapt != null)
+ strategy.map(adapt.booleanValue());
+ } catch (RuntimeException re) {
+ // reset strategy
+ _strategy = orig;
+ throw re;
+ }
+ }
+ }
+
+ /**
+ * The discriminator value.
+ */
+ public Object getValue() {
+ return _value;
+ }
+
+ /**
+ * The discriminator value.
+ */
+ public void setValue(Object value) {
+ _value = value;
+ }
+
+ /**
+ * Raw mapping data.
+ */
+ public DiscriminatorMappingInfo getMappingInfo() {
+ return _info;
+ }
+
+ /**
+ * Columns used by this Discriminator.
+ */
+ public Column[] getColumns() {
+ return _cols;
+ }
+
+ /**
+ * Columns used by this Discriminator.
+ */
+ public void setColumns(Column[] cols) {
+ if (cols == null)
+ cols = Schemas.EMPTY_COLUMNS;
+ _cols = cols;
+ }
+
+ /**
+ * I/O information on the discriminator columns.
+ */
+ public ColumnIO getColumnIO() {
+ return (_io == null) ? ColumnIO.UNRESTRICTED : _io;
+ }
+
+ /**
+ * I/O information on the discriminator columns.
+ */
+ public void setColumnIO(ColumnIO io) {
+ _io = io;
+ }
+
+ /**
+ * Index on the Discriminator columns, or null if none.
+ */
+ public Index getIndex() {
+ return _idx;
+ }
+
+ /**
+ * Index on the Discriminator columns, or null if none.
+ */
+ public void setIndex(Index idx) {
+ _idx = idx;
+ }
+
+ /**
+ * Increment the reference count of used schema components.
+ */
+ public void refSchemaComponents() {
+ for (int i = 0; i < _cols.length; i++)
+ _cols[i].ref();
+ }
+
+ /**
+ * Clear mapping information, including strategy.
+ */
+ public void clearMapping() {
+ _strategy = null;
+ _cols = Schemas.EMPTY_COLUMNS;
+ _idx = null;
+ _value = null;
+ _info.clear();
+ setResolve(MODE_MAPPING | MODE_MAPPING_INIT, false);
+ }
+
+ /**
+ * Update {@link MappingInfo} with our current mapping information.
+ */
+ public void syncMappingInfo() {
+ _info.syncWith(this);
+ }
+
+ /**
+ * Resolve mode.
+ */
+ public int getResolve() {
+ return _resMode;
+ }
+
+ /**
+ * Resolve mode.
+ */
+ public void setResolve(int mode) {
+ _resMode = mode;
+ }
+
+ /**
+ * Resolve mode.
+ */
+ public void setResolve(int mode, boolean on) {
+ if (mode == MODE_NONE)
+ _resMode = mode;
+ else if (on)
+ _resMode |= mode;
+ else
+ _resMode &= ~mode;
+ }
+
+ /**
+ * Resolve mapping information.
+ */
+ public boolean resolve(int mode) {
+ if ((_resMode & mode) == mode)
+ return true;
+ int cur = _resMode;
+ _resMode |= mode;
+ if ((mode & MODE_MAPPING) != 0 && (cur & MODE_MAPPING) == 0)
+ resolveMapping();
+ if ((mode & MODE_MAPPING_INIT) != 0 && (cur & MODE_MAPPING_INIT) == 0)
+ _strategy.initialize();
+ return false;
+ }
+
+ /**
+ * Setup mapping.
+ */
+ private void resolveMapping() {
+ // map strategy
+ MappingRepository repos = getMappingRepository();
+ if (_strategy == null)
+ repos.getStrategyInstaller().installStrategy(this);
+ Log log = repos.getLog();
+ if (log.isTraceEnabled())
+ log.trace(_loc.get("strategy", this, _strategy.getAlias()));
+
+ // mark columns as mapped
+ Column[] cols = getColumns();
+ ColumnIO io = getColumnIO();
+ for (int i = 0; i < cols.length; i++) {
+ if (io.isInsertable(i, false))
+ cols[i].setFlag(Column.FLAG_DIRECT_INSERT, true);
+ if (io.isUpdatable(i, false))
+ cols[i].setFlag(Column.FLAG_DIRECT_UPDATE, true);
+ }
+ }
+
+ /**
+ * Whether this Discriminator has loaded subclasses yet.
+ */
+ public boolean getSubclassesLoaded() {
+ if (!_subsLoaded) {
+ ClassMapping sup = _mapping.getPCSuperclassMapping();
+ if (sup != null && sup.getDiscriminator().getSubclassesLoaded())
+ _subsLoaded = true;
+ }
+ return _subsLoaded;
+ }
+
+ /**
+ * Whether this Discriminator has loaded subclasses yet.
+ */
+ public void setSubclassesLoaded(boolean loaded) {
+ _subsLoaded = loaded;
+ }
+
+ ////////////////////////////////////////
+ // DiscriminatorStrategy implementation
+ ////////////////////////////////////////
+
+ public String getAlias() {
+ return assertStrategy().getAlias();
+ }
+
+ public void map(boolean adapt) {
+ assertStrategy().map(adapt);
+ }
+
+ public void initialize() {
+ assertStrategy().initialize();
+ }
+
+ public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ assertStrategy().insert(sm, store, rm);
+ }
+
+ public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ assertStrategy().update(sm, store, rm);
+ }
+
+ public void delete(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ assertStrategy().delete(sm, store, rm);
+ }
+
+ public Boolean isCustomInsert(OpenJPAStateManager sm, JDBCStore store) {
+ return assertStrategy().isCustomInsert(sm, store);
+ }
+
+ public Boolean isCustomUpdate(OpenJPAStateManager sm, JDBCStore store) {
+ return assertStrategy().isCustomUpdate(sm, store);
+ }
+
+ public Boolean isCustomDelete(OpenJPAStateManager sm, JDBCStore store) {
+ return assertStrategy().isCustomDelete(sm, store);
+ }
+
+ public void customInsert(OpenJPAStateManager sm, JDBCStore store)
+ throws SQLException {
+ assertStrategy().customInsert(sm, store);
+ }
+
+ public void customUpdate(OpenJPAStateManager sm, JDBCStore store)
+ throws SQLException {
+ assertStrategy().customUpdate(sm, store);
+ }
+
+ public void customDelete(OpenJPAStateManager sm, JDBCStore store)
+ throws SQLException {
+ assertStrategy().customDelete(sm, store);
+ }
+
+ public void setDiscriminator(Discriminator owner) {
+ assertStrategy().setDiscriminator(owner);
+ }
+
+ public boolean select(Select sel, ClassMapping mapping) {
+ return assertStrategy().select(sel, mapping);
+ }
+
+ public void loadSubclasses(JDBCStore store)
+ throws SQLException, ClassNotFoundException {
+ assertStrategy().loadSubclasses(store);
+ }
+
+ public Class getClass(JDBCStore store, ClassMapping base, Result result)
+ throws SQLException, ClassNotFoundException {
+ return assertStrategy().getClass(store, base, result);
+ }
+
+ public SQLBuffer getClassConditions(JDBCStore store, Select sel,
+ Joins joins, ClassMapping base, boolean subs) {
+ return assertStrategy().getClassConditions(store, sel, joins,
+ base, subs);
+ }
+
+ private DiscriminatorStrategy assertStrategy() {
+ if (_strategy == null)
+ throw new InternalException();
+ return _strategy;
+ }
+
+ public String toString() {
+ return _mapping + "<discriminator>";
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Discriminator.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DiscriminatorMappingInfo.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DiscriminatorMappingInfo.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DiscriminatorMappingInfo.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DiscriminatorMappingInfo.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,173 @@
+/*
+ * 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;
+
+import java.lang.reflect.Modifier;
+
+import org.apache.openjpa.jdbc.meta.strats.NoneDiscriminatorStrategy;
+import org.apache.openjpa.jdbc.meta.strats.SuperclassDiscriminatorStrategy;
+import org.apache.openjpa.jdbc.meta.strats.ValueMapDiscriminatorStrategy;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.Index;
+import org.apache.openjpa.jdbc.schema.SchemaGroup;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.MetaDataException;
+
+/**
+ * Information about the mapping from a discriminator to the schema, in
+ * raw form. The columns and tables used in mapping info will not be part of
+ * the {@link SchemaGroup} used at runtime. Rather, they will be structs
+ * with the relevant pieces of information filled in.
+ *
+ * @author Abe White
+ */
+public class DiscriminatorMappingInfo
+ extends MappingInfo {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (DiscriminatorMappingInfo.class);
+
+ private String _value = null;
+
+ /**
+ * Raw discriminator value string.
+ */
+ public String getValue() {
+ return _value;
+ }
+
+ /**
+ * Raw discriminator value string.
+ */
+ public void setValue(String value) {
+ _value = value;
+ }
+
+ /**
+ * Return the discriminator value as an object of the right type.
+ */
+ public Object getValue(Discriminator discrim, boolean adapt) {
+ if (discrim.getValue() != null)
+ return discrim.getValue();
+ if (_value == null)
+ return discrim.getMappingRepository().getMappingDefaults().
+ getDiscriminatorValue(discrim, adapt);
+
+ if (_value.length() > 0 &&
+ (_value.charAt(0) == '-' || Character.isDigit(_value.charAt(0)))) {
+ try {
+ if (_value.indexOf('.') == -1)
+ return new Integer(_value);
+ return new Double(_value);
+ } catch (RuntimeException re) {
+ throw new MetaDataException(_loc.get("bad-discrim-value",
+ discrim.getClassMapping(), _value));
+ }
+ }
+ if ("null".equalsIgnoreCase(_value))
+ return (Discriminator.NULL);
+
+ // strip quotes
+ if (_value.length() > 0 && _value.charAt(0) == '\'')
+ return _value.substring(1, _value.length() - 1);
+ return _value;
+ }
+
+ /**
+ * Return the columns set for this discriminator, based on the given
+ * templates.
+ */
+ public Column[] getColumns(Discriminator discrim, Column[] tmplates,
+ boolean adapt) {
+ Table table = discrim.getClassMapping().getTable();
+ discrim.getMappingRepository().getMappingDefaults().populateColumns
+ (discrim, table, tmplates);
+ return createColumns(discrim, null, tmplates, table, adapt);
+ }
+
+ /**
+ * Return the index to set on the discriminator columns, or null if none.
+ */
+ public Index getIndex(Discriminator discrim, Column[] cols, boolean adapt) {
+ Index idx = null;
+ if (cols.length > 0)
+ idx = discrim.getMappingRepository().getMappingDefaults().
+ getIndex(discrim, cols[0].getTable(), cols);
+ return createIndex(discrim, null, idx, cols, adapt);
+ }
+
+ /**
+ * Synchronize internal information with the mapping data for the given
+ * discriminator.
+ */
+ public void syncWith(Discriminator disc) {
+ clear(false);
+
+ // set io before syncing cols
+ setColumnIO(disc.getColumnIO());
+ syncColumns(disc, disc.getColumns(), disc.getValue() != null
+ && !(disc.getValue()instanceof String));
+ syncIndex(disc, disc.getIndex());
+ if (disc.getValue() == Discriminator.NULL)
+ _value = "null";
+ else if (disc.getValue() != null)
+ _value = disc.getValue().toString();
+
+ if (disc.getStrategy() == null
+ || disc.getStrategy()instanceof SuperclassDiscriminatorStrategy)
+ return;
+
+ // explicit discriminator strategy if:
+ // - unmapped class and discriminator is mapped
+ // - final base class and discriminator is mapped
+ // - table-per-class subclass and discriminator is mapped
+ // - mapped subclass and doesn't rely on superclass discriminator
+ // - mapped base class and doesn't use value-map strategy with value
+ // and isn't a final class that uses the final strategy
+ ClassMapping cls = disc.getClassMapping();
+ String strat = disc.getStrategy().getAlias();
+ boolean sync = false;
+
+ if (!cls.isMapped()
+ || (cls.getJoinablePCSuperclassMapping() != null
+ && Modifier.isFinal(cls.getDescribedType().getModifiers()))
+ || (cls.getJoinablePCSuperclassMapping() == null
+ && cls.getMappedPCSuperclassMapping() != null))
+ sync = !NoneDiscriminatorStrategy.ALIAS.equals(strat);
+ else
+ sync = cls.getJoinablePCSuperclassMapping() != null
+ || _value == null
+ || !ValueMapDiscriminatorStrategy.ALIAS.equals(strat);
+
+ if (sync)
+ setStrategy(strat);
+ }
+
+ protected void clear(boolean canFlags) {
+ super.clear(canFlags);
+ _value = null;
+ }
+
+ public void copy(MappingInfo info) {
+ super.copy(info);
+ if (!(info instanceof DiscriminatorMappingInfo))
+ return;
+
+ if (_value == null)
+ _value = ((DiscriminatorMappingInfo) info).getValue();
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DiscriminatorMappingInfo.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DiscriminatorStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DiscriminatorStrategy.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DiscriminatorStrategy.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DiscriminatorStrategy.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,69 @@
+/*
+ * 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;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.Select;
+
+/**
+ * Handles determining the object class of database records.
+ *
+ * @author Abe White
+ */
+public interface DiscriminatorStrategy
+ extends Strategy {
+
+ /**
+ * Set the Discriminator that uses this strategy. This will be called
+ * before use.
+ */
+ public void setDiscriminator(Discriminator owner);
+
+ /**
+ * Select the data for this Discriminator.
+ *
+ * @param mapping the known base class being selected; this may
+ * not be the base class in the inheritance hierarchy
+ * @return true if anything was selected; false otherwise
+ */
+ public boolean select(Select sel, ClassMapping mapping);
+
+ /**
+ * Load all subclasses of the owning class mapping into the JVM.
+ */
+ public void loadSubclasses(JDBCStore store)
+ throws SQLException, ClassNotFoundException;
+
+ /**
+ * Return the class for the current result row.
+ */
+ public Class getClass(JDBCStore store, ClassMapping base, Result result)
+ throws SQLException, ClassNotFoundException;
+
+ /**
+ * Return SQL to limit the classes selected as much as possible to the
+ * given base class, and optionally its subclasses. Return null if
+ * no conditions needed. The select and joins instances are supplied
+ * in order to get column aliases.
+ */
+ public SQLBuffer getClassConditions(JDBCStore store, Select sel,
+ Joins joins, ClassMapping base, boolean subs);
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DiscriminatorStrategy.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Embeddable.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Embeddable.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Embeddable.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Embeddable.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,82 @@
+/*
+ * 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;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ColumnIO;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+
+/**
+ * Interface for field strategies that can managed fields of
+ * embedded-element, embedded-key, and embedded-value objects. Fields of
+ * directly embedded objects do not have to implement this interface.
+ *
+ * @author Abe White
+ * @since 4.0
+ */
+public interface Embeddable {
+
+ public static final Object UNSUPPORTED = new Object();
+
+ /**
+ * Return the columns used by this strategy.
+ */
+ public Column[] getColumns();
+
+ /**
+ * Return column I/O information for this mapping.
+ */
+ public ColumnIO getColumnIO();
+
+ /**
+ * Return the arguments needed to extract datastore values via
+ * {@link Result#getObject} for each column.
+ */
+ public Object[] getResultArguments();
+
+ /**
+ * Convert the given Java value to its datastore equivalent. If this
+ * mapping occupies multiple columns, return an object array with one
+ * element per column. For relation id columns, return the state manager
+ * the column depends on.
+ */
+ public Object toEmbeddedDataStoreValue(Object val, JDBCStore store);
+
+ /**
+ * Convert the given datastore value to its Java equivalent.
+ * If {@link #getColumns} returns multiple columns, the given datastore
+ * value will be an object array of the corresponding length. This method
+ * must only be supported by mappings of embedded id objects. In other
+ * cases {@link #loadEmbedded} will be used instead. Return
+ * {@link #UNSUPPORTED} if this mapping cannot support this method.
+ */
+ public Object toEmbeddedObjectValue(Object val);
+
+ /**
+ * Load this strategy's field by transforming the given datastore value.
+ * If {@link #getColumns} returns multiple columns, the given datastore
+ * value will be an object array of the corresponding length. The value
+ * does not have to be loaded immediately; it may be stored as impl data.
+ */
+ public void loadEmbedded(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, Object val)
+ throws SQLException;
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Embeddable.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,1013 @@
+/*
+ * 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;
+
+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.strats.NoneFieldStrategy;
+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.Index;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.jdbc.schema.Unique;
+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.jdbc.sql.SelectExecutor;
+import org.apache.openjpa.kernel.FetchConfiguration;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.util.InternalException;
+import org.apache.openjpa.util.MetaDataException;
+
+/**
+ * Specialization of metadata for relational databases.
+ *
+ * @author Abe White
+ */
+public class FieldMapping
+ extends FieldMetaData
+ implements ValueMapping, FieldStrategy {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (FieldMapping.class);
+
+ private final ValueMapping _val;
+ private final ValueMapping _key;
+ private final ValueMapping _elem;
+ private final FieldMappingInfo _info;
+ private final JDBCColumnOrder _orderCol = new JDBCColumnOrder();
+ private FieldStrategy _strategy = null;
+
+ private ForeignKey _fk = null;
+ private ColumnIO _io = null;
+ private Unique _unq = null;
+ private Index _idx = null;
+ private boolean _outer = false;
+ private int _fetchMode = Integer.MAX_VALUE;
+
+ /**
+ * Constructor.
+ */
+ public FieldMapping(String name, Class type, ClassMapping owner) {
+ super(name, type, owner);
+ _info = owner.getMappingRepository().newMappingInfo(this);
+ _val = (ValueMapping) getValue();
+ _key = (ValueMapping) getKey();
+ _elem = (ValueMapping) getElement();
+
+ setUsesIntermediate(false);
+ setUsesImplData(Boolean.FALSE);
+ }
+
+ ///////
+ // ORM
+ ///////
+
+ /**
+ * Raw mapping data about field's join to parent table, as well as
+ * miscellaneous specialized columns like order column.
+ */
+ public FieldMappingInfo getMappingInfo() {
+ return _info;
+ }
+
+ /**
+ * The strategy used to map this mapping.
+ */
+ public FieldStrategy getStrategy() {
+ return _strategy;
+ }
+
+ /**
+ * The strategy used to map this mapping. The <code>adapt</code>
+ * parameter determines whether to adapt when mapping the strategy;
+ * use null if the strategy should not be mapped.
+ */
+ public void setStrategy(FieldStrategy strategy, Boolean adapt) {
+ // set strategy first so we can access it during mapping
+ FieldStrategy orig = _strategy;
+ _strategy = strategy;
+ if (strategy != null) {
+ try {
+ strategy.setFieldMapping(this);
+ if (adapt != null)
+ strategy.map(adapt.booleanValue());
+ } catch (RuntimeException re) {
+ // reset strategy
+ _strategy = orig;
+ throw re;
+ }
+
+ // if set to unmapped, clear defined field cache in parent
+ if (!isMapped())
+ getDefiningMapping().clearDefinedFieldCache();
+ }
+ }
+
+ /**
+ * The mapping's primary table.
+ */
+ public Table getTable() {
+ if (_fk != null)
+ return _fk.getTable();
+ if (_val.getForeignKey() != null)
+ return _val.getForeignKey().getTable();
+ return getDefiningMapping().getTable();
+ }
+
+ /**
+ * I/O information on the join columns.
+ */
+ public ColumnIO getJoinColumnIO() {
+ return (_io == null) ? ColumnIO.UNRESTRICTED : _io;
+ }
+
+ /**
+ * I/O information on the join columns.
+ */
+ public void setJoinColumnIO(ColumnIO io) {
+ _io = io;
+ }
+
+ /**
+ * Foreign key linking the field table to the class' primary table.
+ */
+ public ForeignKey getJoinForeignKey() {
+ return _fk;
+ }
+
+ /**
+ * Foreign key linking the field table to the class' primary table.
+ */
+ public void setJoinForeignKey(ForeignKey fk) {
+ _fk = fk;
+ }
+
+ /**
+ * Unique constraint on join foreign key columns.
+ */
+ public Unique getJoinUnique() {
+ return _unq;
+ }
+
+ /**
+ * Unique constraint on join foreign key columns.
+ */
+ public void setJoinUnique(Unique unq) {
+ _unq = unq;
+ }
+
+ /**
+ * Index on join foreign key columns.
+ */
+ public Index getJoinIndex() {
+ return _idx;
+ }
+
+ /**
+ * Index on join foreign key columns.
+ */
+ public void setJoinIndex(Index idx) {
+ _idx = idx;
+ }
+
+ /**
+ * Whether to use an outer join from the class' primary table.
+ */
+ public boolean isJoinOuter() {
+ return _outer;
+ }
+
+ /**
+ * Whether to use an outer join from the class' primary table.
+ */
+ public void setJoinOuter(boolean outer) {
+ _outer = outer;
+ }
+
+ /**
+ * Field order column, if any.
+ */
+ public Column getOrderColumn() {
+ return _orderCol.getColumn();
+ }
+
+ /**
+ * Field order column, if any.
+ */
+ public void setOrderColumn(Column order) {
+ _orderCol.setColumn(order);
+ }
+
+ /**
+ * I/O information for order column.
+ */
+ public ColumnIO getOrderColumnIO() {
+ return _orderCol.getColumnIO();
+ }
+
+ /**
+ * I/O information for order column.
+ */
+ public void setOrderColumnIO(ColumnIO io) {
+ _orderCol.setColumnIO(io);
+ }
+
+ /**
+ * Increment the reference count of used schema components.
+ */
+ public void refSchemaComponents() {
+ if (_fk != null) {
+ _fk.ref();
+ _fk.refColumns();
+ }
+ if (_orderCol.getColumn() != null)
+ _orderCol.getColumn().ref();
+ _val.refSchemaComponents();
+ _key.refSchemaComponents();
+ _elem.refSchemaComponents();
+ }
+
+ /**
+ * Clear mapping information, including strategy.
+ */
+ public void clearMapping() {
+ _strategy = null;
+ _fk = null;
+ _unq = null;
+ _idx = null;
+ _outer = false;
+ _orderCol.setColumn(null);
+ _val.clearMapping();
+ _key.clearMapping();
+ _elem.clearMapping();
+ _info.clear();
+ setResolve(MODE_MAPPING, false);
+ }
+
+ /**
+ * Update {@link MappingInfo} with our current mapping information.
+ */
+ public void syncMappingInfo() {
+ if (isVersion()) {
+ // we rely on the fact that the version will setup our mapping
+ // info correctly when it is synced
+ } else if (getMappedByMapping() != null) {
+ _info.clear();
+ _val.getValueInfo().clear();
+ _key.getValueInfo().clear();
+ _elem.getValueInfo().clear();
+
+ FieldMapping mapped = getMappedByMapping();
+ _info.syncStrategy(this);
+ if (_orderCol.getColumn() != null
+ && mapped.getOrderColumn() == null)
+ _info.syncOrderColumn(this);
+ _val.getValueInfo().setUseClassCriteria
+ (_val.getUseClassCriteria());
+ _key.getValueInfo().setUseClassCriteria
+ (_key.getUseClassCriteria());
+ _elem.getValueInfo().setUseClassCriteria
+ (_elem.getUseClassCriteria());
+ } else {
+ _info.syncWith(this);
+ _val.syncMappingInfo();
+ _key.syncMappingInfo();
+ _elem.syncMappingInfo();
+ }
+ }
+
+ /**
+ * Returns true if field class does not use the "none" strategy (including
+ * if it has a null strategy, and therefore is probably in the process of
+ * being mapped).
+ */
+ public boolean isMapped() {
+ return _strategy != NoneFieldStrategy.getInstance();
+ }
+
+ //////////////////////
+ // MetaData interface
+ //////////////////////
+
+ /**
+ * The eager fetch mode, as one of the eager constants in
+ * {@link JDBCFetchConfiguration}.
+ */
+ public int getEagerFetchMode() {
+ if (_fetchMode == Integer.MAX_VALUE)
+ _fetchMode = FetchConfiguration.DEFAULT;
+ return _fetchMode;
+ }
+
+ /**
+ * The eager fetch mode, as one of the eager constants in
+ * {@link JDBCFetchConfiguration}.
+ */
+ public void setEagerFetchMode(int mode) {
+ _fetchMode = mode;
+ }
+
+ /**
+ * Convenience method to perform cast from
+ * {@link FieldMetaData#getRepository}
+ */
+ public MappingRepository getMappingRepository() {
+ return (MappingRepository) getRepository();
+ }
+
+ /**
+ * Convenience method to perform cast from
+ * {@link FieldMetaData#getDefiningMetaData}
+ */
+ public ClassMapping getDefiningMapping() {
+ return (ClassMapping) getDefiningMetaData();
+ }
+
+ /**
+ * Convenience method to perform cast from
+ * {@link FieldMetaData#getDeclaringMetaData}
+ */
+ public ClassMapping getDeclaringMapping() {
+ return (ClassMapping) getDeclaringMetaData();
+ }
+
+ /**
+ * Convenience method to perform cast from {@link FieldMetaData#getKey}
+ */
+ public ValueMapping getKeyMapping() {
+ return _key;
+ }
+
+ /**
+ * Convenience method to perform cast from {@link FieldMetaData#getElement}
+ */
+ public ValueMapping getElementMapping() {
+ return _elem;
+ }
+
+ /**
+ * Convenience method to perform cast from {@link FieldMetaData#getValue}
+ */
+ public ValueMapping getValueMapping() {
+ return (ValueMapping) getValue();
+ }
+
+ /**
+ * Convenience method to perform cast from
+ * {@link FieldMetaData#getMappedByMetaData}
+ */
+ public FieldMapping getMappedByMapping() {
+ return (FieldMapping) getMappedByMetaData();
+ }
+
+ /**
+ * Convenience method to perform cast from
+ * {@link FieldMetaData#getInverseMetaDatas}
+ */
+ public FieldMapping[] getInverseMappings() {
+ return (FieldMapping[]) getInverseMetaDatas();
+ }
+
+ public boolean resolve(int mode) {
+ int cur = getResolve();
+ if (super.resolve(mode))
+ return true;
+ if ((mode & MODE_MAPPING) != 0 && (cur & MODE_MAPPING) == 0)
+ resolveMapping();
+ if ((mode & MODE_MAPPING_INIT) != 0 && (cur & MODE_MAPPING_INIT) == 0)
+ initializeMapping();
+ return false;
+ }
+
+ /**
+ * Resolve the mapping information for this field.
+ */
+ private void resolveMapping() {
+ MappingRepository repos = getMappingRepository();
+ if (repos.getMappingDefaults().defaultMissingInfo()) {
+ // copy embedded template mapping info
+ ClassMapping cls = getDefiningMapping();
+ if (cls.getEmbeddingMapping() != null) {
+ ClassMapping orig = repos.getMapping(cls.getDescribedType(),
+ cls.getEnvClassLoader(), true);
+ FieldMapping tmplate = orig.getFieldMapping(getName());
+ if (tmplate != null)
+ copyMappingInfo(tmplate);
+ }
+ // copy superclass field info
+ else if (cls.isMapped() && cls.getPCSuperclass() != null
+ && cls.getDescribedType() != getDeclaringType()) {
+ FieldMapping sup = cls.getPCSuperclassMapping().
+ getFieldMapping(getName());
+ if (sup != null)
+ copyMappingInfo(sup);
+ }
+ }
+
+ if (_strategy == null) {
+ if (isVersion())
+ _strategy = NoneFieldStrategy.getInstance();
+ else
+ repos.getStrategyInstaller().installStrategy(this);
+ }
+ Log log = getRepository().getLog();
+ if (log.isTraceEnabled())
+ log.trace(_loc.get("field-strategy", getName(),
+ _strategy.getAlias()));
+
+ // mark mapped columns
+ if (_orderCol.getColumn() != null) {
+ if (getOrderColumnIO().isInsertable(0, false))
+ _orderCol.getColumn().setFlag(Column.FLAG_DIRECT_INSERT, true);
+ if (getOrderColumnIO().isUpdatable(0, false))
+ _orderCol.getColumn().setFlag(Column.FLAG_DIRECT_UPDATE, true);
+ }
+ if (_fk != null) {
+ Column[] cols = _fk.getColumns();
+ ColumnIO io = getJoinColumnIO();
+ for (int i = 0; i < cols.length; i++) {
+ if (io.isInsertable(i, false))
+ cols[i].setFlag(Column.FLAG_FK_INSERT, true);
+ if (io.isUpdatable(i, false))
+ cols[i].setFlag(Column.FLAG_FK_UPDATE, true);
+ }
+ }
+
+ _val.resolve(MODE_MAPPING);
+ _key.resolve(MODE_MAPPING);
+ _elem.resolve(MODE_MAPPING);
+ }
+
+ /**
+ * Copy mapping info from the given instance to this one.
+ */
+ public void copyMappingInfo(FieldMapping fm) {
+ setMappedBy(fm.getMappedBy());
+ _info.copy(fm.getMappingInfo());
+ _val.copyMappingInfo(fm.getValueMapping());
+ _key.copyMappingInfo(fm.getKeyMapping());
+ _elem.copyMappingInfo(fm.getElementMapping());
+ }
+
+ /**
+ * Prepare mapping for runtime use.
+ */
+ private void initializeMapping() {
+ _val.resolve(MODE_MAPPING_INIT);
+ _key.resolve(MODE_MAPPING_INIT);
+ _val.resolve(MODE_MAPPING_INIT);
+ _strategy.initialize();
+ }
+
+ public void copy(FieldMetaData fmd) {
+ super.copy(fmd);
+ if (_fetchMode == Integer.MAX_VALUE)
+ _fetchMode = ((FieldMapping) fmd).getEagerFetchMode();
+ }
+
+ protected boolean validateDataStoreExtensionPrefix(String prefix) {
+ return "jdbc-".equals(prefix);
+ }
+
+ ////////////////////////////////
+ // FieldStrategy implementation
+ ////////////////////////////////
+
+ public String getAlias() {
+ return assertStrategy().getAlias();
+ }
+
+ public void map(boolean adapt) {
+ assertStrategy().map(adapt);
+ }
+
+ /**
+ * Map this field to its table, optionally requiring that it be
+ * in another table. Utility method for use by mapping strategies.
+ */
+ public void mapJoin(boolean adapt, boolean joinRequired) {
+ Table table = _info.getTable(this, joinRequired, adapt);
+ ForeignKey join = null;
+ if (table != null)
+ join = _info.getJoin(this, table, adapt);
+ if (join == null && joinRequired)
+ throw new MetaDataException(_loc.get("join-required", this));
+
+ if (join == null) {
+ _info.assertNoJoin(this, true);
+ _info.assertNoForeignKey(this, !adapt);
+ _info.assertNoUnique(this, !adapt);
+ _info.assertNoIndex(this, !adapt);
+ } else {
+ _fk = join;
+ _io = _info.getColumnIO();
+ _outer = _info.isJoinOuter();
+ _unq = _info.getJoinUnique(this, false, adapt);
+ _idx = _info.getJoinIndex(this, adapt);
+ }
+ }
+
+ /**
+ * Maps the primary key on the secondary table for this field, if the
+ * user's defaults create one. This must be called after
+ * this field is mapped so that it's table has its columns set.
+ */
+ public void mapPrimaryKey(boolean adapt) {
+ if (adapt && _fk != null && _fk.getTable().getPrimaryKey() == null)
+ getMappingRepository().getMappingDefaults().
+ installPrimaryKey(this, _fk.getTable());
+ }
+
+ public void initialize() {
+ assertStrategy().initialize();
+ }
+
+ public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ assertStrategy().insert(sm, store, rm);
+ }
+
+ public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ assertStrategy().update(sm, store, rm);
+ }
+
+ public void delete(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ assertStrategy().delete(sm, store, rm);
+ }
+
+ /**
+ * Delete the row for this object if the reference foreign key exists.
+ * Utility method for use by mapping strategies.
+ */
+ public void deleteRow(OpenJPAStateManager sm, JDBCStore store,
+ RowManager rm)
+ throws SQLException {
+ if (_fk != null) {
+ Row row = rm.getRow(getTable(), Row.ACTION_DELETE, sm, true);
+ row.whereForeignKey(_fk, sm);
+ }
+ }
+
+ /**
+ * Return the row to use for this field. This method is meant only for
+ * single-value fields that might reside in a table that is joined to
+ * the primary table through the join foreign key. It is not
+ * meant for multi-valued fields like collections and maps. The method
+ * checks whether we're using an outer join and if so it deletes the
+ * field's previous value, then if the field is non-null returns an insert
+ * row for the new value. The join foreign key will already be set on
+ * the returned row; mapping strategies just need to set their own values.
+ * Utility method for use by mapping strategies.
+ */
+ public Row getRow(OpenJPAStateManager sm, JDBCStore store, RowManager rm,
+ int action)
+ throws SQLException {
+ Row row = null;
+ boolean newOuterRow = false;
+ if (_fk != null && _outer && action != Row.ACTION_DELETE) {
+ // if updating with outer join, delete old value first, then insert;
+ // we can't just update b/c the row might not exist
+ if (action == Row.ACTION_UPDATE) {
+ // maybe some other field already is updating?
+ row = rm.getRow(getTable(), Row.ACTION_UPDATE, sm, false);
+ if (row == null) {
+ Row del = rm.getRow(getTable(), Row.ACTION_DELETE, sm,
+ true);
+ del.whereForeignKey(_fk, sm);
+ }
+ } else
+ row = rm.getRow(getTable(), Row.ACTION_INSERT, sm, false);
+
+ // only update/insert if the row exists already or the value is
+ // not null/default
+ if (row == null && !isNullValue(sm)) {
+ row = rm.getRow(getTable(), Row.ACTION_INSERT, sm, true);
+ newOuterRow = true;
+ }
+ } else
+ row = rm.getRow(getTable(), action, sm, true);
+
+ // setup fk
+ if (row != null && _fk != null) {
+ if (row.getAction() == Row.ACTION_INSERT)
+ row.setForeignKey(_fk, _io, sm);
+ else
+ row.whereForeignKey(_fk, sm);
+
+ // if this is a new outer joined row, mark it invalid until
+ // some mapping actually sets information on it
+ if (newOuterRow)
+ row.setValid(false);
+ }
+ return row;
+ }
+
+ /**
+ * Return true if this field is null/default in the given instance.
+ */
+ private boolean isNullValue(OpenJPAStateManager sm) {
+ switch (getTypeCode()) {
+ case JavaTypes.BOOLEAN:
+ return !sm.fetchBoolean(getIndex());
+ case JavaTypes.BYTE:
+ return sm.fetchByte(getIndex()) == 0;
+ case JavaTypes.CHAR:
+ return sm.fetchChar(getIndex()) == 0;
+ case JavaTypes.DOUBLE:
+ return sm.fetchDouble(getIndex()) == 0;
+ case JavaTypes.FLOAT:
+ return sm.fetchFloat(getIndex()) == 0;
+ case JavaTypes.INT:
+ return sm.fetchInt(getIndex()) == 0;
+ case JavaTypes.LONG:
+ return sm.fetchLong(getIndex()) == 0;
+ case JavaTypes.SHORT:
+ return sm.fetchShort(getIndex()) == 0;
+ case JavaTypes.STRING:
+ return sm.fetchString(getIndex()) == null;
+ default:
+ return sm.fetchObject(getIndex()) == null;
+ }
+ }
+
+ public Boolean isCustomInsert(OpenJPAStateManager sm, JDBCStore store) {
+ return assertStrategy().isCustomInsert(sm, store);
+ }
+
+ public Boolean isCustomUpdate(OpenJPAStateManager sm, JDBCStore store) {
+ return assertStrategy().isCustomUpdate(sm, store);
+ }
+
+ public Boolean isCustomDelete(OpenJPAStateManager sm, JDBCStore store) {
+ return assertStrategy().isCustomDelete(sm, store);
+ }
+
+ public void customInsert(OpenJPAStateManager sm, JDBCStore store)
+ throws SQLException {
+ assertStrategy().customInsert(sm, store);
+ }
+
+ public void customUpdate(OpenJPAStateManager sm, JDBCStore store)
+ throws SQLException {
+ assertStrategy().customUpdate(sm, store);
+ }
+
+ public void customDelete(OpenJPAStateManager sm, JDBCStore store)
+ throws SQLException {
+ assertStrategy().customDelete(sm, store);
+ }
+
+ public void setFieldMapping(FieldMapping owner) {
+ assertStrategy().setFieldMapping(owner);
+ }
+
+ public int supportsSelect(Select sel, int type, OpenJPAStateManager sm,
+ JDBCStore store, JDBCFetchConfiguration fetch) {
+ return assertStrategy().supportsSelect(sel, type, sm, store, fetch);
+ }
+
+ public void selectEagerParallel(SelectExecutor sel, OpenJPAStateManager sm,
+ JDBCStore store, JDBCFetchState fetchState, int eagerMode) {
+ assertStrategy().selectEagerParallel(sel, sm, store, fetchState,
+ eagerMode);
+ }
+
+ public void selectEagerJoin(Select sel, OpenJPAStateManager sm,
+ JDBCStore store, JDBCFetchState fetchState, int eagerMode) {
+ assertStrategy().selectEagerJoin(sel, sm, store, fetchState,
+ eagerMode);
+ }
+
+ public boolean isEagerSelectToMany() {
+ return assertStrategy().isEagerSelectToMany();
+ }
+
+ public int select(Select sel, OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, int eagerMode) {
+ return assertStrategy().select(sel, sm, store, fetchState, eagerMode);
+ }
+
+ /**
+ * Return any joins needed to get from the primary table to this table.
+ */
+ public Joins join(Select sel) {
+ if (_fk == null)
+ return null;
+
+ Joins joins = sel.newJoins();
+ if (_outer)
+ return joins.outerJoin(_fk, true, false);
+ return joins.join(_fk, true, false);
+ }
+
+ /**
+ * Add a <code>wherePrimaryKey</code> or <code>whereForeignKey</code>
+ * condition to the given select, depending on whether we have a join
+ * foreign key.
+ */
+ public void wherePrimaryKey(Select sel, OpenJPAStateManager sm,
+ JDBCStore store) {
+ if (_fk != null)
+ sel.whereForeignKey(_fk, sm.getObjectId(), getDefiningMapping(),
+ store);
+ else
+ sel.wherePrimaryKey(sm.getObjectId(), getDefiningMapping(),
+ store);
+ }
+
+ /**
+ * Add ordering to the given select for all non-relation order values,
+ * including the synthetic order column, if any.
+ *
+ * @param elem the related type we're fetching, or null
+ * @param joins the joins to this field's table
+ */
+ public void orderLocal(Select sel, ClassMapping elem, Joins joins) {
+ _orderCol.order(sel, elem, joins);
+ JDBCOrder[] orders = (JDBCOrder[]) getOrders();
+ for (int i = 0; i < orders.length; i++)
+ if (!orders[i].isInRelation())
+ orders[i].order(sel, elem, joins);
+ }
+
+ /**
+ * Add ordering to the given select for all relation-based values.
+ *
+ * @param elem the related type we're fetching
+ * @param joins the joins across the relation
+ */
+ public void orderRelation(Select sel, ClassMapping elem, Joins joins) {
+ JDBCOrder[] orders = (JDBCOrder[]) getOrders();
+ for (int i = 0; i < orders.length; i++)
+ if (orders[i].isInRelation())
+ orders[i].order(sel, elem, joins);
+ }
+
+ public Object loadEagerParallel(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, Object res)
+ throws SQLException {
+ return assertStrategy().loadEagerParallel(sm, store, fetchState, res);
+ }
+
+ public void loadEagerJoin(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, Result res)
+ throws SQLException {
+ assertStrategy().loadEagerJoin(sm, store, fetchState, res);
+ }
+
+ public void load(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, Result res)
+ throws SQLException {
+ assertStrategy().load(sm, store, fetchState, res);
+ }
+
+ public void load(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState)
+ throws SQLException {
+ assertStrategy().load(sm, store, fetchState);
+ }
+
+ public Object toDataStoreValue(Object val, JDBCStore store) {
+ return assertStrategy().toDataStoreValue(val, store);
+ }
+
+ public Object toKeyDataStoreValue(Object val, JDBCStore store) {
+ return assertStrategy().toKeyDataStoreValue(val, store);
+ }
+
+ public void appendIsEmpty(SQLBuffer sql, Select sel, Joins joins) {
+ assertStrategy().appendIsEmpty(sql, sel, joins);
+ }
+
+ public void appendIsNotEmpty(SQLBuffer sql, Select sel, Joins joins) {
+ assertStrategy().appendIsNotEmpty(sql, sel, joins);
+ }
+
+ public void appendIsNull(SQLBuffer sql, Select sel, Joins joins) {
+ assertStrategy().appendIsNull(sql, sel, joins);
+ }
+
+ public void appendIsNotNull(SQLBuffer sql, Select sel, Joins joins) {
+ assertStrategy().appendIsNotNull(sql, sel, joins);
+ }
+
+ public void appendSize(SQLBuffer sql, Select sel, Joins joins) {
+ assertStrategy().appendSize(sql, sel, joins);
+ }
+
+ public Joins join(Joins joins, boolean forceOuter) {
+ return assertStrategy().join(joins, forceOuter);
+ }
+
+ public Joins joinKey(Joins joins, boolean forceOuter) {
+ return assertStrategy().joinKey(joins, forceOuter);
+ }
+
+ public Joins joinRelation(Joins joins, boolean forceOuter,
+ boolean traverse) {
+ return assertStrategy().joinRelation(joins, forceOuter, traverse);
+ }
+
+ public Joins joinKeyRelation(Joins joins, boolean forceOuter,
+ boolean traverse) {
+ return assertStrategy().joinKeyRelation(joins, forceOuter, traverse);
+ }
+
+ /**
+ * Joins from the owning class' table to the table where this field lies
+ * using the join foreign key. Utility method for use by mapping strategies.
+ */
+ public Joins join(Joins joins, boolean forceOuter, boolean toMany) {
+ if (_fk == null)
+ return joins;
+ if (_outer || forceOuter)
+ return joins.outerJoin(_fk, true, toMany);
+ return joins.join(_fk, true, toMany);
+ }
+
+ public Object loadProjection(JDBCStore store, JDBCFetchState fetchState,
+ Result res, Joins joins)
+ throws SQLException {
+ return assertStrategy().loadProjection(store, fetchState, res, joins);
+ }
+
+ public Object loadKeyProjection(JDBCStore store,
+ JDBCFetchState fetchState, Result res, Joins joins)
+ throws SQLException {
+ return assertStrategy()
+ .loadKeyProjection(store, fetchState, res, joins);
+ }
+
+ public boolean isVersionable() {
+ return assertStrategy().isVersionable();
+ }
+
+ public void where(OpenJPAStateManager sm, JDBCStore store, RowManager rm,
+ Object prevValue)
+ throws SQLException {
+ assertStrategy().where(sm, store, rm, prevValue);
+ }
+
+ private FieldStrategy assertStrategy() {
+ if (_strategy == null)
+ throw new InternalException();
+ return _strategy;
+ }
+
+ ///////////////////////////////
+ // ValueMapping implementation
+ ///////////////////////////////
+
+ public ValueMappingInfo getValueInfo() {
+ return _val.getValueInfo();
+ }
+
+ public ValueHandler getHandler() {
+ return _val.getHandler();
+ }
+
+ public void setHandler(ValueHandler handler) {
+ _val.setHandler(handler);
+ }
+
+ public FieldMapping getFieldMapping() {
+ return this;
+ }
+
+ public ClassMapping getTypeMapping() {
+ return _val.getTypeMapping();
+ }
+
+ public ClassMapping getDeclaredTypeMapping() {
+ return _val.getDeclaredTypeMapping();
+ }
+
+ public ClassMapping getEmbeddedMapping() {
+ return _val.getEmbeddedMapping();
+ }
+
+ public FieldMapping getValueMappedByMapping() {
+ return _val.getValueMappedByMapping();
+ }
+
+ public Column[] getColumns() {
+ return _val.getColumns();
+ }
+
+ public void setColumns(Column[] cols) {
+ _val.setColumns(cols);
+ }
+
+ public ColumnIO getColumnIO() {
+ return _val.getColumnIO();
+ }
+
+ public void setColumnIO(ColumnIO io) {
+ _val.setColumnIO(io);
+ }
+
+ public ForeignKey getForeignKey() {
+ return _val.getForeignKey();
+ }
+
+ public ForeignKey getForeignKey(ClassMapping target) {
+ return _val.getForeignKey(target);
+ }
+
+ public void setForeignKey(ForeignKey fk) {
+ _val.setForeignKey(fk);
+ }
+
+ public int getJoinDirection() {
+ return _val.getJoinDirection();
+ }
+
+ public void setJoinDirection(int direction) {
+ _val.setJoinDirection(direction);
+ }
+
+ public void setForeignKey(Row row, OpenJPAStateManager sm)
+ throws SQLException {
+ _val.setForeignKey(row, sm);
+ }
+
+ public void whereForeignKey(Row row, OpenJPAStateManager sm)
+ throws SQLException {
+ _val.whereForeignKey(row, sm);
+ }
+
+ public ClassMapping[] getIndependentTypeMappings() {
+ return _val.getIndependentTypeMappings();
+ }
+
+ public int getSelectSubclasses() {
+ return _val.getSelectSubclasses();
+ }
+
+ public Unique getValueUnique() {
+ return _val.getValueUnique();
+ }
+
+ public void setValueUnique(Unique unq) {
+ _val.setValueUnique(unq);
+ }
+
+ public Index getValueIndex() {
+ return _val.getValueIndex();
+ }
+
+ public void setValueIndex(Index idx) {
+ _val.setValueIndex(idx);
+ }
+
+ public boolean getUseClassCriteria() {
+ return _val.getUseClassCriteria();
+ }
+
+ public void setUseClassCriteria(boolean criteria) {
+ _val.setUseClassCriteria(criteria);
+ }
+
+ public int getPolymorphic() {
+ return _val.getPolymorphic();
+ }
+
+ public void setPolymorphic(int poly) {
+ _val.setPolymorphic(poly);
+ }
+
+ public void mapConstraints(String name, boolean adapt) {
+ _val.mapConstraints(name, adapt);
+ }
+
+ public void copyMappingInfo(ValueMapping vm) {
+ _val.copyMappingInfo(vm);
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMappingInfo.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMappingInfo.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMappingInfo.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMappingInfo.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,329 @@
+/*
+ * 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;
+
+import java.util.List;
+
+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.Index;
+import org.apache.openjpa.jdbc.schema.Schema;
+import org.apache.openjpa.jdbc.schema.SchemaGroup;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.jdbc.schema.Unique;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.xml.Commentable;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.util.MetaDataException;
+
+/**
+ * Information about the mapping from a field to the schema, in raw form.
+ * The columns and tables used in mapping info will not be part of the
+ * {@link SchemaGroup} used at runtime. Rather, they will be structs
+ * with the relevant pieces of information filled in.
+ *
+ * @author Abe White
+ */
+public class FieldMappingInfo
+ extends MappingInfo
+ implements Commentable {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (FieldMappingInfo.class);
+
+ private String _tableName = null;
+ private boolean _outer = false;
+ private Column _orderCol = null;
+ private boolean _canOrderCol = true;
+ private String[] _comments = null;
+
+ /**
+ * The user-supplied name of the table for this field.
+ */
+ public String getTableName() {
+ return _tableName;
+ }
+
+ /**
+ * The user-supplied name of the table for this field.
+ */
+ public void setTableName(String tableName) {
+ _tableName = tableName;
+ }
+
+ /**
+ * Whether the field's table is joined to the class table through an
+ * outer join.
+ */
+ public boolean isJoinOuter() {
+ return _outer;
+ }
+
+ /**
+ * Whether the field's table is joined to the class table through an
+ * outer join.
+ */
+ public void setJoinOuter(boolean outer) {
+ _outer = outer;
+ }
+
+ /**
+ * Raw synthetic ordering column.
+ */
+ public Column getOrderColumn() {
+ return _orderCol;
+ }
+
+ /**
+ * Raw synthetic ordering column.
+ */
+ public void setOrderColumn(Column order) {
+ _orderCol = order;
+ }
+
+ /**
+ * Whether we can have an ordering column.
+ */
+ public boolean canOrderColumn() {
+ return _canOrderCol;
+ }
+
+ /**
+ * Whether we can have an ordering column.
+ */
+ public void setCanOrderColumn(boolean canOrder) {
+ _canOrderCol = canOrder;
+ }
+
+ /**
+ * Return the table for the given field, or null if no table given.
+ */
+ public Table getTable(final FieldMapping field, boolean create,
+ boolean adapt) {
+ if (_tableName == null && !create)
+ return null;
+
+ Table table = field.getDefiningMapping().getTable();
+ Schema schema = (table == null) ? null : table.getSchema();
+
+ // if we have no join columns defined, there may be class-level join
+ // information with a more fully-qualified name for our table
+ String tableName = _tableName;
+ if (tableName != null && getColumns().isEmpty())
+ tableName = field.getDefiningMapping().getMappingInfo().
+ getSecondaryTableName(tableName);
+
+ return createTable(field, new TableDefaults() {
+ public String get(Schema schema) {
+ // delay this so that we don't do schema reflection for unique
+ // table name unless necessary
+ return field.getMappingRepository().getMappingDefaults().
+ getTableName(field, schema);
+ }
+ }, schema, tableName, adapt);
+ }
+
+ /**
+ * Return the join from the field table to the owning class table.
+ */
+ public ForeignKey getJoin(final FieldMapping field, Table table,
+ boolean adapt) {
+ // if we have no join columns defined, check class-level join
+ List cols = getColumns();
+ if (cols.isEmpty())
+ cols = field.getDefiningMapping().getMappingInfo().
+ getSecondaryTableJoinColumns(_tableName);
+
+ ForeignKeyDefaults def = new ForeignKeyDefaults() {
+ public ForeignKey get(Table local, Table foreign, boolean inverse) {
+ return field.getMappingRepository().getMappingDefaults().
+ getJoinForeignKey(field, local, foreign);
+ }
+
+ public void populate(Table local, Table foreign, Column col,
+ Object target, boolean inverse, int pos, int cols) {
+ field.getMappingRepository().getMappingDefaults().
+ populateJoinColumn(field, local, foreign, col, target,
+ pos, cols);
+ }
+ };
+ ClassMapping cls = field.getDefiningMapping();
+ return createForeignKey(field, "join", cols, def, table, cls, cls,
+ false, adapt);
+ }
+
+ /**
+ * Unique constraint on the field join.
+ */
+ public Unique getJoinUnique(FieldMapping field, boolean def,
+ boolean adapt) {
+ ForeignKey fk = field.getJoinForeignKey();
+ if (fk == null)
+ return null;
+
+ Unique unq = null;
+ if (fk.getColumns().length > 0)
+ unq = field.getMappingRepository().getMappingDefaults().
+ getJoinUnique(field, fk.getTable(), fk.getColumns());
+ return createUnique(field, "join", unq, fk.getColumns(), adapt);
+ }
+
+ /**
+ * Index on the field join.
+ */
+ public Index getJoinIndex(FieldMapping field, boolean adapt) {
+ ForeignKey fk = field.getJoinForeignKey();
+ if (fk == null)
+ return null;
+
+ Index idx = null;
+ if (fk.getColumns().length > 0)
+ idx = field.getMappingRepository().getMappingDefaults().
+ getJoinIndex(field, fk.getTable(), fk.getColumns());
+ return createIndex(field, "join", idx, fk.getColumns(), adapt);
+ }
+
+ /**
+ * Return the ordering column for this field, or null if none.
+ */
+ public Column getOrderColumn(FieldMapping field, Table table,
+ boolean adapt) {
+ if (_orderCol != null && field.getOrderDeclaration() != null)
+ throw new MetaDataException(_loc.get("order-conflict", field));
+
+ // reset IO
+ setColumnIO(null);
+
+ // has user has explicitly turned ordering off?
+ if (!_canOrderCol || field.getOrderDeclaration() != null)
+ return null;
+
+ // if no defaults return null
+ MappingDefaults def = field.getMappingRepository().
+ getMappingDefaults();
+ if (_orderCol == null && (!adapt && !def.defaultMissingInfo()))
+ return null;
+
+ Column tmplate = new Column();
+ tmplate.setName("ordr");
+ tmplate.setJavaType(JavaTypes.INT);
+ if (!def.populateOrderColumns(field, table, new Column[]{ tmplate })
+ && _orderCol == null)
+ return null;
+
+ if (_orderCol != null && (_orderCol.getFlag(Column.FLAG_UNINSERTABLE)
+ || _orderCol.getFlag(Column.FLAG_UNUPDATABLE))) {
+ ColumnIO io = new ColumnIO();
+ io.setInsertable(0, !_orderCol.getFlag(Column.FLAG_UNINSERTABLE));
+ io.setUpdatable(0, !_orderCol.getFlag(Column.FLAG_UNUPDATABLE));
+ setColumnIO(io);
+ }
+
+ return mergeColumn(field, "order", tmplate, true, _orderCol, table,
+ adapt, def.defaultMissingInfo());
+ }
+
+ /**
+ * Synchronize internal information with the mapping data for the given
+ * field.
+ */
+ public void syncWith(FieldMapping field) {
+ clear(false);
+
+ if (field.getJoinForeignKey() != null)
+ _tableName = field.getMappingRepository().getDBDictionary().
+ getFullName(field.getTable(), true);
+
+ ClassMapping def = field.getDefiningMapping();
+ setColumnIO(field.getJoinColumnIO());
+ if (field.getJoinForeignKey() != null && def.getTable() != null)
+ syncForeignKey(field, field.getJoinForeignKey(),
+ field.getTable(), def.getTable());
+ _outer = field.isJoinOuter();
+
+ syncIndex(field, field.getJoinIndex());
+ syncUnique(field, field.getJoinUnique());
+ syncOrderColumn(field);
+ syncStrategy(field);
+ }
+
+ /**
+ * Synchronize internal mapping strategy information with the given field.
+ */
+ public void syncStrategy(FieldMapping field) {
+ setStrategy(null);
+ if (field.getHandler() != null || field.getStrategy() == null)
+ return;
+
+ // explicit strategy if the strategy isn't the expected default
+ Strategy strat = field.getMappingRepository().defaultStrategy
+ (field, false);
+ if (strat == null || !strat.getAlias().equals(field.getAlias()))
+ setStrategy(field.getAlias());
+ }
+
+ /**
+ * Synchronize internal order column information with the given field.
+ */
+ public void syncOrderColumn(FieldMapping field) {
+ if (field.getOrderColumn() != null)
+ _orderCol = syncColumn(field, field.getOrderColumn(), 1, false,
+ field.getTable(), null, null, false);
+ else
+ _orderCol = null;
+ }
+
+ public boolean hasSchemaComponents() {
+ return super.hasSchemaComponents() || _tableName != null
+ || _orderCol != null;
+ }
+
+ protected void clear(boolean canFlags) {
+ super.clear(canFlags);
+ _tableName = null;
+ _orderCol = null;
+ if (canFlags)
+ _canOrderCol = true;
+ }
+
+ public void copy(MappingInfo info) {
+ super.copy(info);
+ if (!(info instanceof FieldMappingInfo))
+ return;
+
+ FieldMappingInfo finfo = (FieldMappingInfo) info;
+ if (_tableName == null)
+ _tableName = finfo.getTableName();
+ if (!_outer)
+ _outer = finfo.isJoinOuter();
+ if (_canOrderCol && _orderCol == null)
+ _canOrderCol = finfo.canOrderColumn();
+ if (_canOrderCol && finfo.getOrderColumn() != null) {
+ if (_orderCol == null)
+ _orderCol = new Column();
+ _orderCol.copy(finfo.getOrderColumn());
+ }
+ }
+
+ public String[] getComments() {
+ return (_comments == null) ? EMPTY_COMMENTS : _comments;
+ }
+
+ public void setComments(String[] comments) {
+ _comments = comments;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMappingInfo.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldStrategy.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldStrategy.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldStrategy.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,245 @@
+/*
+ * 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;
+
+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.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+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.jdbc.sql.SelectExecutor;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+
+/**
+ * Maps a persistent field to the relational schema.
+ *
+ * @author Abe White
+ * @since 4.0
+ */
+public interface FieldStrategy
+ extends Strategy {
+
+ /**
+ * Set the class mapping using this strategy. This will be called before
+ * use.
+ */
+ public void setFieldMapping(FieldMapping owner);
+
+ /**
+ * Return whether this mapping can perform the given select type.
+ * Return 0 if the given type is not supported. If the given type is an
+ * eager parallel type, return the number of UNIONed selects necessary
+ * to fetch the data. Otherwise, return any positive number if the type
+ * is supported. The given state manager may be null if selecting
+ * multiple instances.
+ *
+ * @see Select
+ */
+ public int supportsSelect(Select sel, int type, OpenJPAStateManager sm,
+ JDBCStore store, JDBCFetchConfiguration fetch);
+
+ /**
+ * Fill in parallel eager select for related objects.
+ *
+ * @see #select
+ */
+ public void selectEagerParallel(SelectExecutor sel, OpenJPAStateManager sm,
+ JDBCStore store, JDBCFetchState fetchState, int eagerMode);
+
+ /**
+ * Fill in joined select to related objects.
+ *
+ * @see #select
+ */
+ public void selectEagerJoin(Select sel, OpenJPAStateManager sm,
+ JDBCStore store, JDBCFetchState fetchState, int eagerMode);
+
+ /**
+ * Whether the eager joins or selects used by this field are to-many.
+ */
+ public boolean isEagerSelectToMany();
+
+ /**
+ * Select the virtual row columns of this mapping.
+ *
+ * @param sel the select to add to
+ * @param sm the instance being loaded, or null if not
+ * initialized yet or selecting for multiple instances
+ * @param store the current store manager
+ * @param fetch fetch configuration
+ * @param eagerMode the eager fetch mode to use; this may be more
+ * restrictive than the mode of the fetch configuration
+ * @return > 0 if this mapping requires the selected data
+ * (if any), 0 if it selected data but does not
+ * require it, or < 0 if no data was selected
+ */
+ public int select(Select sel, OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, int eagerMode);
+
+ /**
+ * Load the batched eager result.
+ *
+ * @param res originally the {@link Result} to load from, but this
+ * method may return a processed result form that will be
+ * passed to subsequent calls
+ */
+ public Object loadEagerParallel(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, Object res)
+ throws SQLException;
+
+ /**
+ * Load the joined eager result.
+ */
+ public void loadEagerJoin(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, Result res)
+ throws SQLException;
+
+ /**
+ * Load virtual row data; the given result is not guaranteed to contain
+ * data for this field, so the field mapping should make sure the
+ * result contains its needed column data before loading.
+ */
+ public void load(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, Result res)
+ throws SQLException;
+
+ /**
+ * Load secondary data using a connection from the store manager.
+ */
+ public void load(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState)
+ throws SQLException;
+
+ ///////////
+ // Queries
+ ///////////
+
+ /**
+ * Translate the given external field value to its datastore equivalent.
+ * If the mapping occupies multiple columns in the datastore, return an
+ * object array, else return a single object. Simply returns the given
+ * object by default.
+ */
+ public Object toDataStoreValue(Object val, JDBCStore store);
+
+ /**
+ * Translate the given key value to its datastore equivalent. If the
+ * mapping occupies multiple columns in the datastore, return an object
+ * array, else return a single object. Simply returns the given object by
+ * default.
+ */
+ public Object toKeyDataStoreValue(Object val, JDBCStore store);
+
+ /**
+ * Append a where clause to the given statement checking if this value
+ * is empty. Appends impossible-to-satisfy SQL by default.
+ */
+ public void appendIsEmpty(SQLBuffer sql, Select sel, Joins joins);
+
+ /**
+ * Append a where clause to the given statement checking if this value
+ * is not empty. Appends always-satisfied SQL by default.
+ */
+ public void appendIsNotEmpty(SQLBuffer sql, Select sel, Joins joins);
+
+ /**
+ * Append a where clause to the given statement checking if this value
+ * is null.
+ */
+ public void appendIsNull(SQLBuffer sql, Select sel, Joins joins);
+
+ /**
+ * Append a where clause to the given statement checking if this value
+ * is not null.
+ */
+ public void appendIsNotNull(SQLBuffer sql, Select sel, Joins joins);
+
+ /**
+ * Append a where clause to the given statement checking the size
+ * of the value.
+ */
+ public void appendSize(SQLBuffer sql, Select sel, Joins joins);
+
+ /**
+ * Join this value to the class table. Does nothing by default.
+ */
+ public Joins join(Joins joins, boolean forceOuter);
+
+ /**
+ * Join the key value to the class table. Does nothing by default.
+ */
+ public Joins joinKey(Joins joins, boolean forceOuter);
+
+ /**
+ * Join this value's table to the table for the related first class object
+ * type, if any. Does nothing by default.
+ *
+ * @param traverse if true, throw proper exception if it is not
+ * possible for this mapping to traverse into the related type
+ */
+ public Joins joinRelation(Joins joins, boolean forceOuter,
+ boolean traverse);
+
+ /**
+ * Join this value's table to the table for the related first class object
+ * key type, if any. Does nothing by default.
+ *
+ * @param traverse if true, throw proper exception if it is not
+ * possible for this mapping to traverse into the related type
+ */
+ public Joins joinKeyRelation(Joins joins, boolean forceOuter,
+ boolean traverse);
+
+ /**
+ * Load this field value using the given result. The result
+ * will contain the columns from {@link ValueMapping#getColumns}.
+ */
+ public Object loadProjection(JDBCStore store, JDBCFetchState fetchState,
+ Result res, Joins joins)
+ throws SQLException;
+
+ /**
+ * Load this field's key value using the given result. The result will
+ * contain the columns from {@link ValueMapping#getColumns}.
+ */
+ public Object loadKeyProjection(JDBCStore store,
+ JDBCFetchState fetchState, Result res, Joins joins)
+ throws SQLException;
+
+ //////////////
+ // Versioning
+ //////////////
+
+ /**
+ * Return true if this field can be used as part of a state image for
+ * optimistic locking.
+ */
+ public boolean isVersionable();
+
+ /**
+ * Add a WHERE condition to the row for this field such that the field's
+ * current DB value must equal the given previous value. Only versionable
+ * mappings must implement this method meaningfully.
+ */
+ public void where(OpenJPAStateManager sm, JDBCStore store, RowManager rm,
+ Object prevValue)
+ throws SQLException;
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldStrategy.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCColumnOrder.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCColumnOrder.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCColumnOrder.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCColumnOrder.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,84 @@
+/*
+ * 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;
+
+import java.util.Comparator;
+
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ColumnIO;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Select;
+
+/**
+ * Order by a synthetic order column.
+ *
+ * @author Abe White
+ */
+class JDBCColumnOrder
+ implements JDBCOrder {
+
+ private Column _col = null;
+ private ColumnIO _io = null;
+
+ /**
+ * The synthetic column.
+ */
+ public Column getColumn() {
+ return _col;
+ }
+
+ /**
+ * The synthetic column.
+ */
+ public void setColumn(Column col) {
+ _col = col;
+ }
+
+ /**
+ * I/O restrictions for the synthetic column.
+ */
+ public ColumnIO getColumnIO() {
+ return (_io == null) ? ColumnIO.UNRESTRICTED : _io;
+ }
+
+ /**
+ * I/O restrictions for the synthetic column.
+ */
+ public void setColumnIO(ColumnIO io) {
+ _io = io;
+ }
+
+ public String getName() {
+ return (_col == null) ? "" : _col.getName();
+ }
+
+ public boolean isAscending() {
+ return true;
+ }
+
+ public Comparator getComparator() {
+ return null;
+ }
+
+ public boolean isInRelation() {
+ return false;
+ }
+
+ public void order(Select sel, ClassMapping elem, Joins joins) {
+ if (_col != null)
+ sel.orderBy(_col, true, joins, true);
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCColumnOrder.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCOrder.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCOrder.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCOrder.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCOrder.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,43 @@
+/*
+ * 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;
+
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.meta.Order;
+
+/**
+ * Order in the datastore using JDBC.
+ *
+ * @author Abe White
+ */
+interface JDBCOrder
+ extends Order {
+
+ /**
+ * Whether the value is a member of the field's related type, rather than
+ * columns of the field itself.
+ */
+ public boolean isInRelation();
+
+ /**
+ * Order by this value.
+ *
+ * @param elem if this value has independent mappings, the mapping
+ * we're selecting
+ */
+ public void order(Select sel, ClassMapping elem, Joins joins);
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCOrder.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCRelatedFieldOrder.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCRelatedFieldOrder.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCRelatedFieldOrder.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCRelatedFieldOrder.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,69 @@
+/*
+ * 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;
+
+import java.util.Comparator;
+
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.MetaDataException;
+
+/**
+ * Use the database to order by a field in the related type.
+ *
+ * @author Abe White
+ */
+class JDBCRelatedFieldOrder
+ implements JDBCOrder {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (JDBCRelatedFieldOrder.class);
+
+ private final FieldMapping _fm;
+ private final boolean _asc;
+
+ public JDBCRelatedFieldOrder(FieldMapping owner, FieldMapping rel,
+ boolean asc) {
+ if (!rel.isInDefaultFetchGroup())
+ throw new MetaDataException(_loc.get("nondfg-field-orderable",
+ owner, rel.getName()));
+
+ _fm = rel;
+ _asc = asc;
+ }
+
+ public String getName() {
+ return _fm.getName();
+ }
+
+ public boolean isAscending() {
+ return _asc;
+ }
+
+ public Comparator getComparator() {
+ return null;
+ }
+
+ public boolean isInRelation() {
+ return true;
+ }
+
+ public void order(Select sel, ClassMapping elem, Joins joins) {
+ FieldMapping fm = elem.getFieldMapping(_fm.getIndex());
+ sel.orderBy(fm.getColumns(), _asc, joins, false);
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCRelatedFieldOrder.java
------------------------------------------------------------------------------
svn:executable = *