Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCValueOrder.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCValueOrder.java?rev=423615&view=auto ============================================================================== --- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCValueOrder.java (added) +++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCValueOrder.java Wed Jul 19 14:34:44 2006 @@ -0,0 +1,64 @@ +/* + * 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.meta.Order; + +/** + * Order by value columns, which are the primary key columns in the case + * of a relation field. + * + * @author Abe White + */ +class JDBCValueOrder + implements JDBCOrder { + + private final FieldMapping _fm; + private final boolean _asc; + + public JDBCValueOrder(FieldMapping fm, boolean asc) { + _fm = fm; + _asc = asc; + } + + public String getName() { + return Order.ELEMENT; + } + + public boolean isAscending() { + return _asc; + } + + public Comparator getComparator() { + return null; + } + + public boolean isInRelation() { + return _fm.getElement().getTypeMetaData() != null; + } + + public void order(Select sel, ClassMapping elem, Joins joins) { + if (elem != null) + sel.orderBy(elem.getPrimaryKeyColumns(), _asc, joins, false); + else + sel.orderBy(_fm.getElementMapping().getColumns(), _asc, + joins, false); + } +}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JDBCValueOrder.java ------------------------------------------------------------------------------ svn:executable = * Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JavaSQLTypes.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JavaSQLTypes.java?rev=423615&view=auto ============================================================================== --- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JavaSQLTypes.java (added) +++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JavaSQLTypes.java Wed Jul 19 14:34:44 2006 @@ -0,0 +1,161 @@ +/* + * 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.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Time; +import java.sql.Timestamp; + +import org.apache.openjpa.meta.JavaTypes; +import serp.util.Numbers; + +/** + * Java SQL type constants. + * + * @author Abe White + */ +public class JavaSQLTypes + extends JavaTypes { + + // constants for the sql types that aren't directly supported by + // OpenJPA; make sure these don't conflict with our standard metadata types + public static final int SQL_ARRAY = 1000; + public static final int ASCII_STREAM = 1001; + public static final int BINARY_STREAM = 1002; + public static final int BLOB = 1003; + public static final int BYTES = 1004; + public static final int CHAR_STREAM = 1005; + public static final int CLOB = 1006; + public static final int SQL_DATE = 1007; + public static final int SQL_OBJECT = 1008; + public static final int REF = 1009; + public static final int TIME = 1010; + public static final int TIMESTAMP = 1011; + public static final int JDBC_DEFAULT = 1012; + + private static final Byte ZERO_BYTE = new Byte((byte) 0); + private static final Character ZERO_CHAR = new Character((char) 0); + private static final Double ZERO_DOUBLE = new Double(0); + private static final Float ZERO_FLOAT = new Float(0); + private static final Short ZERO_SHORT = new Short((short) 0); + private static final BigDecimal ZERO_BIGDECIMAL = new BigDecimal(0); + + private static final Byte NONZERO_BYTE = new Byte((byte) 1); + private static final Character NONZERO_CHAR = new Character((char) 'a'); + private static final Double NONZERO_DOUBLE = new Double(1); + private static final Float NONZERO_FLOAT = new Float(1); + private static final Short NONZERO_SHORT = new Short((short) 1); + private static final BigInteger NONZERO_BIGINTEGER = new BigInteger("1"); + private static final BigDecimal NONZERO_BIGDECIMAL = new BigDecimal(1); + + /** + * Return the proper date typecode. + */ + public static int getDateTypeCode(Class dtype) { + if (dtype == java.util.Date.class) + return DATE; + if (dtype == java.sql.Date.class) + return SQL_DATE; + if (dtype == Timestamp.class) + return TIMESTAMP; + if (dtype == Time.class) + return TIME; + return OBJECT; + } + + /** + * Return an empty value object for the given type code. + */ + public static Object getEmptyValue(int type) { + switch (type) { + case JavaTypes.STRING: + return ""; + case JavaTypes.BOOLEAN: + case JavaTypes.BOOLEAN_OBJ: + return Boolean.FALSE; + case JavaTypes.BYTE: + case JavaTypes.BYTE_OBJ: + return ZERO_BYTE; + case JavaTypes.CHAR: + case JavaTypes.CHAR_OBJ: + return ZERO_CHAR; + case JavaTypes.DOUBLE: + case JavaTypes.DOUBLE_OBJ: + return ZERO_DOUBLE; + case JavaTypes.FLOAT: + case JavaTypes.FLOAT_OBJ: + return ZERO_FLOAT; + case JavaTypes.INT: + case JavaTypes.INT_OBJ: + return Numbers.valueOf(0); + case JavaTypes.LONG: + case JavaTypes.LONG_OBJ: + return Numbers.valueOf(0L); + case JavaTypes.SHORT: + case JavaTypes.SHORT_OBJ: + return ZERO_SHORT; + case JavaTypes.BIGINTEGER: + return BigInteger.ZERO; + case JavaTypes.BIGDECIMAL: + case JavaTypes.NUMBER: + return ZERO_BIGDECIMAL; + default: + return null; + } + } + + /** + * Return a non-empty value object for the given type code. + */ + public static Object getNonEmptyValue(int type) { + switch (type) { + case JavaTypes.STRING: + return "x"; + case JavaTypes.BOOLEAN: + case JavaTypes.BOOLEAN_OBJ: + return Boolean.TRUE; + case JavaTypes.BYTE: + case JavaTypes.BYTE_OBJ: + return NONZERO_BYTE; + case JavaTypes.CHAR: + case JavaTypes.CHAR_OBJ: + return NONZERO_CHAR; + case JavaTypes.DOUBLE: + case JavaTypes.DOUBLE_OBJ: + return NONZERO_DOUBLE; + case JavaTypes.FLOAT: + case JavaTypes.FLOAT_OBJ: + return NONZERO_FLOAT; + case JavaTypes.INT: + case JavaTypes.INT_OBJ: + return Numbers.valueOf(1); + case JavaTypes.LONG: + case JavaTypes.LONG_OBJ: + return Numbers.valueOf(1L); + case JavaTypes.SHORT: + case JavaTypes.SHORT_OBJ: + return NONZERO_SHORT; + case JavaTypes.BIGINTEGER: + return NONZERO_BIGINTEGER; + case JavaTypes.BIGDECIMAL: + case JavaTypes.NUMBER: + return NONZERO_BIGDECIMAL; + default: + return null; + } + } +} Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/JavaSQLTypes.java ------------------------------------------------------------------------------ svn:executable = * Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Joinable.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Joinable.java?rev=423615&view=auto ============================================================================== --- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Joinable.java (added) +++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Joinable.java Wed Jul 19 14:34:44 2006 @@ -0,0 +1,86 @@ +/* + * 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.ForeignKey; +import org.apache.openjpa.jdbc.sql.Joins; +import org.apache.openjpa.jdbc.sql.Result; +import org.apache.openjpa.kernel.OpenJPAStateManager; + +/** + * Represents a value that can be joined to. Any column that a user + * joins to must be "owned" by an entity that implements this interface. + * The system maps columns to joinables to be able to decompose oids and + * field values into individual join values on a per-column basis. This + * allows us to support joins to only some of the columns of a mapping, and + * to be loose with the ordering of foreign key columns relative to the + * ordering of the joined-to columns. Having a separate interface for + * joinables also allows us to perform tricks such as a vertically-mapped + * application identity subclass transparently transforming columns of its + * foreign key to the corresponding primary key fields in the base class. + * + * @author Abe White + */ +public interface Joinable { + + /** + * Return the field index of this joinable, or -1 if not a field. + */ + public int getFieldIndex(); + + /** + * Return the value for this joinable from the given result, using the + * given columns. If the given foreign key is non-null, use the foreign + * key's columns by translating the given columns through + * [EMAIL PROTECTED] ForeignKey#getColumn}. + */ + public Object getPrimaryKeyValue(Result res, Column[] cols, ForeignKey fk, + Joins joins) + throws SQLException; + + /** + * The columns managed by this joinable. + */ + public Column[] getColumns(); + + /** + * Return the join value of the given column. + * + * @param val the value of the field for this joinable + * @param col the column of this joinable whose value to return + */ + public Object getJoinValue(Object val, Column col, JDBCStore store); + + /** + * Return the join value of the given column. + * + * @param sm the instance from which to get the value + * @param col the column whose value to return + */ + public Object getJoinValue(OpenJPAStateManager sm, Column col, + JDBCStore store); + + /** + * Use the given auto-assigned value to set this join value's field + * on the given instance. + */ + public void setAutoAssignedValue(OpenJPAStateManager sm, JDBCStore store, + Column col, Object autogen); +} Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Joinable.java ------------------------------------------------------------------------------ svn:executable = * Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaults.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaults.java?rev=423615&view=auto ============================================================================== --- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaults.java (added) +++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaults.java Wed Jul 19 14:34:44 2006 @@ -0,0 +1,304 @@ +/* + * 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.schema.Column; +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.Table; +import org.apache.openjpa.jdbc.schema.Unique; + +/** + * Generates default names for tables, columns, indexes, constraints, etc. + * + * @author Abe White + */ +public interface MappingDefaults { + + /** + * Whether to fill in missing mapping information at runtime with the + * default values supplied by this plugin. A value of false means that + * all mapping information must be present at runtime. + */ + public boolean defaultMissingInfo(); + + /** + * The default for whether relations use the related object's + * expected class as part of the join criteria. + */ + public boolean useClassCriteria(); + + /** + * Default mapping strategy when there is no explicit strategy + * and no hierarchy strategy given. + * + * @param cls the class; will not be mapped, but superclass and raw + * [EMAIL PROTECTED] MappingInfo} will be available + * @param adapt whether we can adapt the mapping or schema + * @return the strategy alias or a strategy instance, or null + */ + public Object getStrategy(ClassMapping cls, boolean adapt); + + /** + * Default version mapping strategy when there is no explicit strategy. + * + * @param vers the version; will not be mapped, but raw + * [EMAIL PROTECTED] MappingInfo} will be available + * @param adapt whether we can adapt the mapping or schema + * @return the strategy alias or a strategy instance, or null + */ + public Object getStrategy(Version vers, boolean adapt); + + /** + * Default discriminator mapping strategy when there is no explicit + * strategy. + * + * @param disc the discriminator; will not be mapped, but raw + * [EMAIL PROTECTED] MappingInfo} will be available + * @param adapt whether we can adapt the mapping or schema + * @return the strategy alias or a strategy instance, or null + */ + public Object getStrategy(Discriminator disc, boolean adapt); + + /** + * Custom handler or strategy for the given field, or null if none + * has been registered. + * + * @param vm the value mapping; will not be mapped, but raw + * [EMAIL PROTECTED] MappingInfo} will be available + * @param type the value type + * @param adapt whether we can adapt the mapping or schema + * @return the handler/strategy alias or instance, or null + */ + public Object getStrategy(ValueMapping vm, Class type, boolean adapt); + + /** + * Return the default discriminator value for the given instance. + */ + public Object getDiscriminatorValue(Discriminator disc, boolean adapt); + + /** + * Return the default table name for the given class. This method is + * only called for classes mapped to their own table. + */ + public String getTableName(ClassMapping cls, Schema defaultSchema); + + /** + * Return the default secondary table name for the given field. This + * method is only called for fields whose strategy requires a secondary + * table. + */ + public String getTableName(FieldMapping fm, Schema defaultSchema); + + /** + * Fill in default information for the given datastore identity columns. + * The columns' name and Java type will already be populated with generic + * defaults that may be replaced. + */ + public void populateDataStoreIdColumns(ClassMapping cls, Table table, + Column[] cols); + + /** + * Fill in default information for the given version columns. + * The columns' name and Java type will already be populated with generic + * defaults that may be replaced. + */ + public void populateColumns(Version vers, Table table, Column[] cols); + + /** + * Fill in default information for the given discriminator columns. + * The columns' name and Java type will already be populated with generic + * defaults that may be replaced. + */ + public void populateColumns(Discriminator disc, Table table, + Column[] cols); + + /** + * Fill in default information for the given column used to join a class + * to its superclass table. The column will be a clone of the target + * column, or have its name and Java type set in the case of a constant + * target. + * + * @param target the target of this column in the join; may be + * another column or a constant value + * @param pos the index of this column in the logical foreign key + * @param cols the number of columns in the logical foreign key + */ + public void populateJoinColumn(ClassMapping cm, Table local, Table foreign, + Column col, Object target, int pos, int cols); + + /** + * Fill in default information for the given column used to join a field + * to its defining class' table. The column will be a clone of the target + * column, or have its name and Java type set in the case of a constant + * target. + * + * @param target the target of this column in the join; may be + * another column or a constant value + * @param pos the index of this column in the logical foreign key + * @param cols the number of columns in the logical foreign key + */ + public void populateJoinColumn(FieldMapping fm, Table local, Table foreign, + Column col, Object target, int pos, int cols); + + /** + * Fill in default information for the given column used to join a value + * to its related type. The column will be a clone of the target + * column, or have its name and Java type set in the case of a constant + * target. + * + * @param name base name for value, as decided by mapping + * @param target the target of this column in the join; may be + * another column or a constant value + * @param inverse whether this is an inverse foreign key + * @param pos the index of this column in the logical foreign key + * @param cols the number of columns in the logical foreign key + */ + public void populateForeignKeyColumn(ValueMapping vm, String name, + Table local, Table foreign, Column col, Object target, boolean inverse, + int pos, int cols); + + /** + * Fill in default information for the given value columns. + * The columns' name and Java type will already be populated with generic + * defaults that may be replaced. + * + * @param name base name for value, as decided by mapping + */ + public void populateColumns(ValueMapping vm, String name, Table table, + Column[] cols); + + /** + * Fill in default information for the given order columns. + * The columns' name and Java type will already be populated with generic + * defaults that may be replaced. + * + * @return false if the given field should not have order columns + * by default; fill in default information even when returning + * false in case the user forces ordering + */ + public boolean populateOrderColumns(FieldMapping fm, Table table, + Column[] cols); + + /** + * Fill in default information for the given null indicator columns. + * The columns' name and Java type will already be populated with generic + * defaults that may be replaced. + * + * @param name base name for value, as decided by mapping + * @return false if the given value should not have null indicator + * columns by default; fill in default information even + * when returning false in case the user forces an indicator + */ + public boolean populateNullIndicatorColumns(ValueMapping vm, String name, + Table table, Column[] cols); + + /** + * Return a default foreign key for the join from this class' table to its + * superclass' table, or null for a logical foreign key only. Do not + * add columns to the key or add the key to the table; only fill in + * its information such as name, delete action, etc. + */ + public ForeignKey getJoinForeignKey(ClassMapping cls, Table local, + Table foreign); + + /** + * Return a default foreign key for the join from this field's table to its + * defining class' table, or null for a logical foreign key only. Do not + * add columns to the key or add the key to the table; only fill in + * its information such as name, delete action, etc. + */ + public ForeignKey getJoinForeignKey(FieldMapping fm, Table local, + Table foreign); + + /** + * Return a default foreign key for the join from this value to its + * related type, or null for a logical foreign key only. Do not + * add columns to the key or add the key to the table; only fill in + * its information such as name, delete action, etc. + * + * @param name base name for value, as decided by mapping + * @param inverse whether this is an inverse key + */ + public ForeignKey getForeignKey(ValueMapping vm, String name, Table local, + Table foreign, boolean inverse); + + /** + * Return a default index for the join, or null if the + * join columns should not be indexed by default. Do not + * add columns to the index or add the index to the table; only fill in + * its information such as name, uniqueness, etc. + */ + public Index getJoinIndex(FieldMapping fm, Table table, Column[] cols); + + /** + * Return a default index for the value, or null if the value columns + * should not be indexed by default. Do not add columns to the index or + * add the index to the table; only fill in its information such as name, + * uniqueness, etc. + * + * @param name base name for value, as decided by mapping + */ + public Index getIndex(ValueMapping vm, String name, Table table, + Column[] cols); + + /** + * Return a default index for the version, or null if the + * version columns should not be indexed by default. Do not + * add columns to the index or add the index to the table; only fill in + * its information such as name, uniqueness, etc. + */ + public Index getIndex(Version vers, Table table, Column[] cols); + + /** + * Return a default index for the discriminator, or null if the + * discriminator columns should not be indexed by default. Do not + * add columns to the index or add the index to the table; only fill in + * its information such as name, uniqueness, etc. + */ + public Index getIndex(Discriminator disc, Table table, Column[] cols); + + /** + * Return a default constraint for the join, or null if the join columns + * should not be constrained by default. Do not add columns to the + * constraint or add the constraint to the table; only fill in its + * information such as name, deferrability, etc. + */ + public Unique getJoinUnique(FieldMapping fm, Table table, Column[] cols); + + /** + * Return a default constraint for the value, or null if the value columns + * should not be constrained by default. Do not add columns to the + * constraint or add the constraint to the table; only fill in its + * information such as name, deferrability, etc. + * + * @param name base name for value, as decided by mapping + */ + public Unique getUnique(ValueMapping vm, String name, Table table, + Column[] cols); + + /** + * Return the name of the primary key for the table of the given class, + * or null for database default. + */ + public String getPrimaryKeyName(ClassMapping cm, Table table); + + /** + * If desired, install a primary key on the given secondary table. + */ + public void installPrimaryKey(FieldMapping fm, Table table); +} Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaults.java ------------------------------------------------------------------------------ svn:executable = * Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaultsImpl.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaultsImpl.java?rev=423615&view=auto ============================================================================== --- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaultsImpl.java (added) +++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaultsImpl.java Wed Jul 19 14:34:44 2006 @@ -0,0 +1,703 @@ +/* + * 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.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.openjpa.jdbc.conf.JDBCConfiguration; +import org.apache.openjpa.jdbc.meta.strats.UntypedPCValueHandler; +import org.apache.openjpa.jdbc.schema.Column; +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.Table; +import org.apache.openjpa.jdbc.schema.Unique; +import org.apache.openjpa.jdbc.sql.DBDictionary; +import org.apache.openjpa.lib.conf.Configurable; +import org.apache.openjpa.lib.conf.Configuration; +import org.apache.openjpa.lib.conf.Configurations; +import org.apache.openjpa.lib.util.JavaVersions; +import org.apache.openjpa.meta.JavaTypes; +import serp.util.Strings; + +/** + * Default implementation of [EMAIL PROTECTED] MappingDefaults}. + * + * @author Abe White + */ +public class MappingDefaultsImpl + implements MappingDefaults, Configurable { + + protected DBDictionary dict = null; + private String _baseClassStrategy = null; + private String _subclassStrategy = null; + private String _versionStrategy = null; + private String _discStrategy = null; + private final Map _fieldMap = new HashMap(); + private boolean _defMissing = false; + private boolean _classCriteria = false; + private int _joinFKAction = ForeignKey.ACTION_NONE; + private int _fkAction = ForeignKey.ACTION_NONE; + private boolean _defer = false; + private boolean _indexFK = true; + private boolean _indexDisc = true; + private boolean _indexVers = false; + private boolean _orderLists = true; + private boolean _addNullInd = false; + private boolean _ordinalEnum = false; + private boolean _stringifyUnmapped = false; + private String _dsIdName = null; + private String _versName = null; + private String _discName = null; + private String _orderName = null; + private String _nullIndName = null; + + /** + * Default base class strategy alias. + */ + public String getBaseClassStrategy() { + return _baseClassStrategy; + } + + /** + * Default base class strategy alias. + */ + public void setBaseClassStrategy(String baseClassStrategy) { + _baseClassStrategy = baseClassStrategy; + } + + /** + * Default subclass strategy alias. + */ + public String getSubclassStrategy() { + return _subclassStrategy; + } + + /** + * Default subclass strategy alias. + */ + public void setSubclassStrategy(String subclassStrategy) { + _subclassStrategy = subclassStrategy; + } + + /** + * Default version strategy alias. + */ + public String getVersionStrategy() { + return _versionStrategy; + } + + /** + * Default version strategy alias. + */ + public void setVersionStrategy(String versionStrategy) { + _versionStrategy = versionStrategy; + } + + /** + * Default discriminator strategy alias. + */ + public String getDiscriminatorStrategy() { + return _discStrategy; + } + + /** + * Default discriminator strategy alias. + */ + public void setDiscriminatorStrategy(String discStrategy) { + _discStrategy = discStrategy; + } + + /** + * Property string mapping field type names to value handler or field + * mapping class names. For auto-configuration. + */ + public void setFieldStrategies(String fieldMapString) { + Properties props = Configurations.parseProperties(fieldMapString); + if (props != null) + _fieldMap.putAll(props); + } + + /** + * Association of a field value type name with the handler or strategy + * class name. + */ + public void setFieldStrategy(String valueType, String handlerType) { + if (handlerType == null) + _fieldMap.remove(valueType); + else + _fieldMap.put(valueType, handlerType); + } + + /** + * Association of a field value type name with the handler or strategy + * class name. + */ + public String getFieldStrategy(String valueType) { + return (String) _fieldMap.get(valueType); + } + + /** + * Whether to store enums as the ordinal value rather than the enum name. + * Defaults to false. + */ + public boolean getStoreEnumOrdinal() { + return _ordinalEnum; + } + + /** + * Whether to store enums as the ordinal value rather than the enum name. + * Defaults to false. + */ + public void setStoreEnumOrdinal(boolean ordinal) { + _ordinalEnum = ordinal; + } + + /** + * Whether to store a relation to an unmapped class by stringifying the + * oid of the related object, rather than storing primary key values. + */ + public boolean getStoreUnmappedObjectIdString() { + return _stringifyUnmapped; + } + + /** + * Whether to store a relation to an unmapped class by stringifying the + * oid of the related object, rather than storing primary key values. + */ + public void setStoreUnmappedObjectIdString(boolean stringify) { + _stringifyUnmapped = stringify; + } + + /** + * Default foreign key action for join keys. Defaults to logical keys. + */ + public int getJoinForeignKeyDeleteAction() { + return _joinFKAction; + } + + /** + * Default foreign key action for join keys. Defaults to logical keys. + */ + public void setJoinForeignKeyDeleteAction(int joinFKAction) { + _joinFKAction = joinFKAction; + } + + /** + * Default foreign key action name for join keys. Used in auto + * configuration. + */ + public void setJoinForeignKeyDeleteAction(String joinFKAction) { + _joinFKAction = ForeignKey.getAction(joinFKAction); + } + + /** + * Default foreign key action for relation keys. Defaults to logical keys. + */ + public int getForeignKeyDeleteAction() { + return _fkAction; + } + + /** + * Default foreign key action for relation keys. Defaults to logical keys. + */ + public void setForeignKeyDeleteAction(int fkAction) { + _fkAction = fkAction; + } + + /** + * Default foreign key action name for relation keys. Used in auto + * configuration. + */ + public void setForeignKeyDeleteAction(String fkAction) { + _fkAction = ForeignKey.getAction(fkAction); + } + + /** + * Whether to index logical foreign keys by default. Defaults to true. + */ + public boolean getIndexLogicalForeignKeys() { + return _indexFK; + } + + /** + * Whether to index logical foreign keys by default. Defaults to true. + */ + public void setIndexLogicalForeignKeys(boolean indexFK) { + _indexFK = indexFK; + } + + /** + * Whether to index discriminator columns by default. Defaults to true. + */ + public boolean getIndexDiscriminator() { + return _indexDisc; + } + + /** + * Whether to index discriminator columns by default. Defaults to true. + */ + public void setIndexDiscriminator(boolean indexDisc) { + _indexDisc = indexDisc; + } + + /** + * Whether to index version columns by default. Defaults to true. + */ + public boolean getIndexVersion() { + return _indexVers; + } + + /** + * Whether to index version columns by default. Defaults to true. + */ + public void setIndexVersion(boolean indexVers) { + _indexVers = indexVers; + } + + /** + * Whether to order lists and arrays using a dedicated ordering column + * by default. + */ + public boolean getOrderLists() { + return _orderLists; + } + + /** + * Whether to order lists and arrays using a dedicated ordering column + * by default. + */ + public void setOrderLists(boolean orderLists) { + _orderLists = orderLists; + } + + /** + * Whether to add a synthetic null indicator column to embedded mappings + * by default. + */ + public boolean getAddNullIndicator() { + return _addNullInd; + } + + /** + * Whether to add a synthetic null indicator column to embedded mappings + * by default. + */ + public void setAddNullIndicator(boolean addNullInd) { + _addNullInd = addNullInd; + } + + /** + * Whether to defer constraints by default. Defaults to false. + */ + public boolean getDeferConstraints() { + return _defer; + } + + /** + * Whether to defer constraints by default. Defaults to false. + */ + public void setDeferConstraints(boolean defer) { + _defer = defer; + } + + /** + * Default base name for datastore identity columns, or null to the + * mapping's built-in name. + */ + public String getDataStoreIdColumnName() { + return _dsIdName; + } + + /** + * Default base name for datastore identity columns, or null to the + * mapping's built-in name. + */ + public void setDataStoreIdColumnName(String dsIdName) { + _dsIdName = dsIdName; + } + + /** + * Default base name for version identity columns, or null to the mapping's + * built-in name. This name may be combined with lock group names. + */ + public String getVersionColumnName() { + return _versName; + } + + /** + * Default base name for version identity columns, or null to the mapping's + * built-in name. This name may be combined with lock group names. + */ + public void setVersionColumnName(String versName) { + _versName = versName; + } + + /** + * Default base name for discriminator columns, or null to the mapping's + * built-in name. + */ + public String getDiscriminatorColumnName() { + return _discName; + } + + /** + * Default base name for discriminator columns, or null to the mapping's + * built-in name. + */ + public void setDiscriminatorColumnName(String discName) { + _discName = discName; + } + + /** + * Default base name for order columns, or null to the mapping's + * built-in name. + */ + public String getOrderColumnName() { + return _orderName; + } + + /** + * Default base name for order columns, or null to the mapping's + * built-in name. + */ + public void setOrderColumnName(String orderName) { + _orderName = orderName; + } + + /** + * Default base name for null indicator columns, or null to the mapping's + * built-in name. + */ + public String getNullIndicatorColumnName() { + return _nullIndName; + } + + /** + * Default base name for null indicator columns, or null to the mapping's + * built-in name. + */ + public void setNullIndicatorColumnName(String nullIndName) { + _nullIndName = nullIndName; + } + + public boolean defaultMissingInfo() { + return _defMissing; + } + + public void setDefaultMissingInfo(boolean defMissing) { + _defMissing = defMissing; + } + + public boolean useClassCriteria() { + return _classCriteria; + } + + public void setUseClassCriteria(boolean classCriteria) { + _classCriteria = classCriteria; + } + + public Object getStrategy(ClassMapping cls, boolean adapt) { + if (adapt || defaultMissingInfo()) + return (cls.getMappedPCSuperclassMapping() == null) + ? _baseClassStrategy : _subclassStrategy; + return null; + } + + public Object getStrategy(Version vers, boolean adapt) { + ClassMapping cls = vers.getClassMapping(); + if ((adapt || defaultMissingInfo()) + && cls.getJoinablePCSuperclassMapping() == null + && cls.getVersionField() == null) + return _versionStrategy; + return null; + } + + public Object getStrategy(Discriminator disc, boolean adapt) { + ClassMapping cls = disc.getClassMapping(); + if ((adapt || defaultMissingInfo()) + && cls.getJoinablePCSuperclassMapping() == null + && disc.getMappingInfo().getValue() == null) + return _discStrategy; + return null; + } + + public Object getStrategy(ValueMapping vm, Class type, boolean adapt) { + Object ret = _fieldMap.get(type.getName()); + if (ret != null) + return ret; + if (_stringifyUnmapped && vm.getTypeMapping() != null + && !vm.getTypeMapping().isMapped()) + return UntypedPCValueHandler.getInstance(); + if (_ordinalEnum && !vm.isSerialized() + && JavaVersions.isEnumeration(type)) + return "org.apache.openjpa.jdbc.meta.strats.EnumValueHandler(StoreOrdinal=true)"; + return null; + } + + public Object getDiscriminatorValue(Discriminator disc, boolean adapt) { + if (!adapt && !defaultMissingInfo()) + return null; + + // WARNING: CHANGING THIS WILL INVALIDATE EXISTING DATA IF DEFAULTING + // MISSING MAPPING INFO + return Strings.getClassName(disc.getClassMapping(). + getDescribedType()); + } + + public String getTableName(ClassMapping cls, Schema schema) { + String name = Strings.getClassName(cls.getDescribedType()). + replace('$', '_'); + if (!_defMissing) + name = dict.getValidTableName(name, schema); + return name; + } + + public String getTableName(FieldMapping fm, Schema schema) { + String name = fm.getName(); + Table table = fm.getDefiningMapping().getTable(); + if (table != null) { + String tableName = table.getName(); + if (tableName.length() > 5) + tableName = tableName.substring(0, 5); + name = tableName + "_" + name; + } + if (!_defMissing) + name = dict.getValidTableName(name, schema); + return name; + } + + public void populateDataStoreIdColumns(ClassMapping cls, Table table, + Column[] cols) { + for (int i = 0; i < cols.length; i++) { + if (_dsIdName != null && cols.length == 1) + cols[i].setName(_dsIdName); + else if (_dsIdName != null) + cols[i].setName(_dsIdName + i); + correctName(table, cols[i]); + } + } + + /** + * Correct the given column's name. + */ + protected void correctName(Table table, Column col) { + if (!_defMissing) + col.setName(dict.getValidColumnName(col.getName(), table)); + } + + public void populateColumns(Version vers, Table table, Column[] cols) { + for (int i = 0; i < cols.length; i++) { + if (_versName != null && cols.length == 1) + cols[i].setName(_versName); + else if (_versName != null) { + if (i == 0) + cols[i].setName(_versName); + else + cols[i].setName(_versName + "_" + i); + } else if (_versName != null) + cols[i].setName(_versName + i); + correctName(table, cols[i]); + } + } + + public void populateColumns(Discriminator disc, Table table, + Column[] cols) { + for (int i = 0; i < cols.length; i++) { + if (_discName != null && cols.length == 1) + cols[i].setName(_discName); + else if (_discName != null) + cols[i].setName(_discName + i); + correctName(table, cols[i]); + } + } + + public void populateJoinColumn(ClassMapping cm, Table local, Table foreign, + Column col, Object target, int pos, int cols) { + correctName(local, col); + } + + public void populateJoinColumn(FieldMapping fm, Table local, Table foreign, + Column col, Object target, int pos, int cols) { + correctName(local, col); + } + + public void populateForeignKeyColumn(ValueMapping vm, String name, + Table local, Table foreign, Column col, Object target, boolean inverse, + int pos, int cols) { + if (cols == 1) + col.setName(name); + else if (target instanceof Column) + col.setName(name + "_" + ((Column) target).getName()); + correctName(local, col); + } + + public void populateColumns(ValueMapping vm, String name, Table table, + Column[] cols) { + for (int i = 0; i < cols.length; i++) + correctName(table, cols[i]); + } + + public boolean populateOrderColumns(FieldMapping fm, Table table, + Column[] cols) { + for (int i = 0; i < cols.length; i++) { + if (_orderName != null && cols.length == 1) + cols[i].setName(_orderName); + else if (_orderName != null) + cols[i].setName(_orderName + i); + correctName(table, cols[i]); + } + return _orderLists && (JavaTypes.ARRAY == fm.getTypeCode() + || List.class.isAssignableFrom(fm.getType())); + } + + public boolean populateNullIndicatorColumns(ValueMapping vm, String name, + Table table, Column[] cols) { + for (int i = 0; i < cols.length; i++) { + if (_nullIndName != null && cols.length == 1) + cols[i].setName(_nullIndName); + else if (_nullIndName != null) + cols[i].setName(_nullIndName + i); + correctName(table, cols[i]); + } + return _addNullInd; + } + + public ForeignKey getJoinForeignKey(ClassMapping cls, Table local, + Table foreign) { + if (_joinFKAction == ForeignKey.ACTION_NONE) + return null; + ForeignKey fk = new ForeignKey(); + fk.setDeleteAction(_joinFKAction); + fk.setDeferred(_defer); + return fk; + } + + public ForeignKey getJoinForeignKey(FieldMapping fm, Table local, + Table foreign) { + if (_joinFKAction == ForeignKey.ACTION_NONE) + return null; + ForeignKey fk = new ForeignKey(); + fk.setDeleteAction(_joinFKAction); + fk.setDeferred(_defer); + return fk; + } + + public ForeignKey getForeignKey(ValueMapping vm, String name, Table local, + Table foreign, boolean inverse) { + if (_fkAction == ForeignKey.ACTION_NONE) + return null; + ForeignKey fk = new ForeignKey(); + fk.setDeleteAction(_fkAction); + fk.setDeferred(_defer); + return fk; + } + + public Index getJoinIndex(FieldMapping fm, Table table, Column[] cols) { + if (!_indexFK || fm.getJoinForeignKey() == null + || !fm.getJoinForeignKey().isLogical()) + return null; + if (areAllPrimaryKeyColumns(cols)) + return null; + + Index idx = new Index(); + idx.setName(getIndexName(null, table, cols)); + return idx; + } + + /** + * Return whether all the given columns are primary key columns. + */ + protected boolean areAllPrimaryKeyColumns(Column[] cols) { + for (int i = 0; i < cols.length; i++) + if (!cols[i].isPrimaryKey()) + return false; + return true; + } + + /** + * Generate an index name. + */ + protected String getIndexName(String name, Table table, Column[] cols) { + // always use dict for index names because no spec mandates them + // based on defaults + if (name == null) + name = cols[0].getName(); + return dict.getValidIndexName(name, table); + } + + public Index getIndex(ValueMapping vm, String name, Table table, + Column[] cols) { + if (!_indexFK || vm.getForeignKey() == null + || !vm.getForeignKey().isLogical()) + return null; + if (areAllPrimaryKeyColumns(cols)) + return null; + + Index idx = new Index(); + idx.setName(getIndexName(name, table, cols)); + return idx; + } + + public Index getIndex(Version vers, Table table, Column[] cols) { + if (!_indexVers) + return null; + Index idx = new Index(); + idx.setName(getIndexName(_versName, table, cols)); + return idx; + } + + public Index getIndex(Discriminator disc, Table table, Column[] cols) { + if (!_indexDisc) + return null; + Index idx = new Index(); + idx.setName(getIndexName(_discName, table, cols)); + return idx; + } + + public Unique getJoinUnique(FieldMapping fm, Table table, Column[] cols) { + return null; + } + + public Unique getUnique(ValueMapping vm, String name, Table table, + Column[] cols) { + return null; + } + + public String getPrimaryKeyName(ClassMapping cm, Table table) { + return null; + } + + public void installPrimaryKey(FieldMapping fm, Table table) { + } + + /////////////////////////////// + // Configurable implementation + /////////////////////////////// + + public void setConfiguration(Configuration conf) { + dict = ((JDBCConfiguration) conf).getDBDictionaryInstance(); + } + + public void startConfiguration() { + } + + public void endConfiguration() { + } +} Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaultsImpl.java ------------------------------------------------------------------------------ svn:executable = *