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 2007/11/07 22:46:11 UTC

svn commit: r592917 [2/3] - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ openjpa-...

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java?rev=592917&r1=592916&r2=592917&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java Wed Nov  7 13:46:09 2007
@@ -116,6 +116,10 @@
         _tags.put(ColumnResult.class, COLUMN_RESULT);
         _tags.put(DiscriminatorColumn.class, DISCRIM_COL);
         _tags.put(DiscriminatorValue.class, DISCRIM_VAL);
+        _tags.put(ElementColumn.class, ELEM_COL);
+        _tags.put(ElementColumns.class, ELEM_COLS);
+        _tags.put(ElementEmbeddedMapping.class, ELEM_EMBEDDED_MAPPING);
+        _tags.put(ElementStrategy.class, ELEM_STRAT);
         _tags.put(EntityResult.class, ENTITY_RESULT);
         _tags.put(Enumerated.class, ENUMERATED);
         _tags.put(FieldResult.class, FIELD_RESULT);
@@ -123,6 +127,16 @@
         _tags.put(JoinColumn.class, JOIN_COL);
         _tags.put(JoinColumns.class, JOIN_COLS);
         _tags.put(JoinTable.class, JOIN_TABLE);
+        _tags.put(KeyColumn.class, KEY_COL);
+        _tags.put(KeyColumns.class, KEY_COLS);
+        _tags.put(KeyClassCriteria.class, KEY_CLASS_CRIT);
+        _tags.put(KeyEmbeddedMapping.class, KEY_EMBEDDED_MAPPING);
+        _tags.put(KeyForeignKey.class, KEY_FK);
+        _tags.put(KeyIndex.class, KEY_INDEX);
+        _tags.put(KeyJoinColumn.class, KEY_JOIN_COL);
+        _tags.put(KeyJoinColumns.class, KEY_JOIN_COLS);
+        _tags.put(KeyNonpolymorphic.class, KEY_NONPOLY);
+        _tags.put(KeyStrategy.class, KEY_STRAT);
         _tags.put(PrimaryKeyJoinColumn.class, PK_JOIN_COL);
         _tags.put(PrimaryKeyJoinColumns.class, PK_JOIN_COLS);
         _tags.put(SecondaryTable.class, SECONDARY_TABLE);
@@ -157,8 +171,11 @@
         _tags.put(VersionColumn.class, VERSION_COL);
         _tags.put(VersionColumns.class, VERSION_COLS);
         _tags.put(VersionStrategy.class, VERSION_STRAT);
+        _tags.put(XEmbeddedMapping.class, X_EMBEDDED_MAPPING);
         _tags.put(XJoinColumn.class, X_JOIN_COL);
         _tags.put(XJoinColumns.class, X_JOIN_COLS);
+        _tags.put(XMappingOverride.class, X_MAPPING_OVERRIDE);
+        _tags.put(XMappingOverrides.class, X_MAPPING_OVERRIDES);
         _tags.put(XSecondaryTable.class, X_SECONDARY_TABLE);
         _tags.put(XSecondaryTables.class, X_SECONDARY_TABLES);
         _tags.put(XTable.class, X_TABLE);
@@ -338,6 +355,13 @@
                     cm.getVersion().getMappingInfo().setStrategy
                         (((VersionStrategy) anno).value());
                     break;
+                case X_MAPPING_OVERRIDE:
+                    parseMappingOverrides(cm, (XMappingOverride) anno);
+                    break;
+                case X_MAPPING_OVERRIDES:
+                    parseMappingOverrides(cm,
+                        ((XMappingOverrides) anno).value());
+                    break;
                 case X_TABLE:
                 case X_SECONDARY_TABLE:
                 case X_SECONDARY_TABLES:
@@ -746,6 +770,108 @@
     }
 
     /**
+     * Parse class-level @XMappingOverride(s).
+     */
+    private void parseMappingOverrides(ClassMapping cm,
+        XMappingOverride... overs) {
+        FieldMapping sup;
+        for (XMappingOverride over : overs) {
+            if (StringUtils.isEmpty(over.name()))
+                throw new MetaDataException(_loc.get("no-override-name", cm));
+            sup = (FieldMapping) cm.getDefinedSuperclassField(over.name());
+            if (sup == null)
+                sup = (FieldMapping) cm.addDefinedSuperclassField(over.name(),
+                    Object.class, Object.class);
+            populate(sup, over);
+        }
+    }
+
+    /**
+     * Populate the given field from override data.
+     */
+    private void populate(FieldMapping fm, XMappingOverride over) {
+        if (over.containerTable().specified())
+            parseContainerTable(fm, over.containerTable());
+        parseColumns(fm, over.columns());
+        parseXJoinColumns(fm, fm.getValueInfo(), true, over.joinColumns());
+        parseElementColumns(fm, over.elementColumns());
+        parseElementJoinColumns(fm, over.elementJoinColumns());
+        parseKeyColumns(fm, over.keyColumns());
+        parseKeyJoinColumns(fm, over.keyJoinColumns());
+    }
+
+    /**
+     * Parse @ElementColumn(s).
+     */
+    private void parseElementColumns(FieldMapping fm, ElementColumn... pcols) {
+        if (pcols.length == 0)
+            return;
+
+        List<Column> cols = new ArrayList<Column>(pcols.length);
+        int unique = 0;
+        for (int i = 0; i < pcols.length; i++) {
+            cols.add(newColumn(pcols[i]));
+            unique |= (pcols[i].unique()) ? TRUE : FALSE;
+        }
+        setColumns(fm, fm.getElementMapping().getValueInfo(), cols, unique);
+    }
+
+    /**
+     * Create a new schema column with information from the given annotation.
+     */
+    private static Column newColumn(ElementColumn anno) {
+        Column col = new Column();
+        if (!StringUtils.isEmpty(anno.name()))
+            col.setName(anno.name());
+        if (!StringUtils.isEmpty(anno.columnDefinition()))
+            col.setTypeName(anno.columnDefinition());
+        if (anno.precision() != 0)
+            col.setSize(anno.precision());
+        else if (anno.length() != 255)
+            col.setSize(anno.length());
+        col.setNotNull(!anno.nullable());
+        col.setDecimalDigits(anno.scale());
+        col.setFlag(Column.FLAG_UNINSERTABLE, !anno.insertable());
+        col.setFlag(Column.FLAG_UNUPDATABLE, !anno.updatable());
+        return col;
+    }
+
+    /**
+     * Parse @KeyJoinColumn(s).
+     */
+    private void parseKeyJoinColumns(FieldMapping fm, KeyJoinColumn... joins) {
+        if (joins.length == 0)
+            return;
+
+        List<Column> cols = new ArrayList<Column>(joins.length);
+        int unique = 0;
+        for (int i = 0; i < joins.length; i++) {
+            cols.add(newColumn(joins[i]));
+            unique |= (joins[i].unique()) ? TRUE : FALSE;
+        }
+        setColumns(fm, fm.getKeyMapping().getValueInfo(), cols, unique);
+    }
+
+    /**
+     *  Create a new schema column with information from the given annotation.
+     */
+    private static Column newColumn(KeyJoinColumn join) {
+        Column col = new Column();
+        if (!StringUtils.isEmpty(join.name()))
+            col.setName(join.name());
+        if (!StringUtils.isEmpty(join.columnDefinition()))
+            col.setName(join.columnDefinition());
+        if (!StringUtils.isEmpty(join.referencedColumnName()))
+            col.setTarget(join.referencedColumnName());
+        if (!StringUtils.isEmpty(join.referencedAttributeName()))
+            col.setTargetField(join.referencedAttributeName());
+        col.setNotNull(!join.nullable());
+        col.setFlag(Column.FLAG_UNINSERTABLE, !join.insertable());
+        col.setFlag(Column.FLAG_UNUPDATABLE, !join.updatable ());
+        return col;
+    }
+    
+    /**
      * Translate the fetch mode enum value to the internal OpenJPA constant.
      */
     private static int toEagerFetchModeConstant(FetchMode mode) {
@@ -823,6 +949,48 @@
                 case JOIN_TABLE:
                     parseJoinTable(fm, (JoinTable) anno);
                     break;
+                case KEY_CLASS_CRIT:
+                    fm.getKeyMapping().getValueInfo().setUseClassCriteria
+                        (((KeyClassCriteria) anno).value());
+                    break;
+                case KEY_COL:
+                    parseKeyColumns(fm, (KeyColumn) anno);
+                    break;
+                case KEY_COLS:
+                    parseKeyColumns(fm, ((KeyColumns) anno).value());
+                    break;
+                case KEY_EMBEDDED_MAPPING:
+                    KeyEmbeddedMapping kembed = (KeyEmbeddedMapping) anno;
+                    parseEmbeddedMapping(fm.getKeyMapping(),
+                        kembed.nullIndicatorColumnName(),
+                        kembed.nullIndicatorAttributeName(),
+                        kembed.overrides());
+                    break;
+                case KEY_FK:
+                    KeyForeignKey kfk = (KeyForeignKey) anno;
+                    parseForeignKey(fm.getKeyMapping().getValueInfo(),
+                        kfk.name(), kfk.enabled(), kfk.deferred(),
+                        kfk.deleteAction(), kfk.updateAction());
+                    break;
+                case KEY_INDEX:
+                    KeyIndex kidx = (KeyIndex) anno;
+                    parseIndex(fm.getKeyMapping().getValueInfo(), kidx.name(),
+                        kidx.enabled(), kidx.unique());
+                    break;
+                case KEY_JOIN_COL:
+                    parseKeyJoinColumns(fm, (KeyJoinColumn) anno);
+                    break;
+                case KEY_JOIN_COLS:
+                    parseKeyJoinColumns(fm, ((KeyJoinColumns) anno).value());
+                    break;
+                case KEY_NONPOLY:
+                    fm.getKeyMapping().setPolymorphic(toPolymorphicConstant
+                        (((KeyNonpolymorphic) anno).value()));
+                    break;
+                case KEY_STRAT:
+                    fm.getKeyMapping().getValueInfo()
+                        .setStrategy(((KeyStrategy) anno).value());
+                    break;
                 case PK_JOIN_COL:
                     parsePrimaryKeyJoinColumns(fm, (PrimaryKeyJoinColumn) anno);
                     break;
@@ -852,6 +1020,19 @@
                     fm.getElementMapping().getValueInfo().setUseClassCriteria
                         (((ElementClassCriteria) anno).value());
                     break;
+                case ELEM_COL:
+                    parseElementColumns(fm, (ElementColumn) anno);
+                    break;
+                case ELEM_COLS:
+                    parseElementColumns(fm, ((ElementColumns) anno).value());
+                    break;
+                case ELEM_EMBEDDED_MAPPING:
+                    ElementEmbeddedMapping ee = (ElementEmbeddedMapping) anno;
+                    parseEmbeddedMapping(fm.getElementMapping(),
+                        ee.nullIndicatorAttributeName(),
+                        ee.nullIndicatorColumnName(),
+                        ee.overrides());
+                    break;
                 case ELEM_FK:
                     ElementForeignKey efk = (ElementForeignKey) anno;
                     parseForeignKey(fm.getElementMapping().getValueInfo(),
@@ -874,6 +1055,10 @@
                     fm.getElementMapping().setPolymorphic(toPolymorphicConstant
                         (((ElementNonpolymorphic) anno).value()));
                     break;
+                case ELEM_STRAT:
+                    fm.getElementMapping().getValueInfo()
+                        .setStrategy(((ElementStrategy) anno).value());
+                    break;
                 case EMBEDDED_MAPPING:
                     parseEmbeddedMapping(fm, (EmbeddedMapping) anno);
                     break;
@@ -894,9 +1079,14 @@
                     fm.getValueInfo().setStrategy(((Strategy) anno).value());
                     break;
                 case UNIQUE:
-                    parseUnique(fm, 
+                    parseUnique(fm,
                         (org.apache.openjpa.persistence.jdbc.Unique) anno);
                     break;
+                case X_EMBEDDED_MAPPING:
+                    XEmbeddedMapping embed = (XEmbeddedMapping) anno;
+                    parseEmbeddedMapping(fm, embed.nullIndicatorColumnName(),
+                        embed.nullIndicatorAttributeName(), embed.overrides());
+                    break;
                 case X_JOIN_COL:
                     parseXJoinColumns(fm, fm.getValueInfo(), true,
                         (XJoinColumn) anno);
@@ -1197,6 +1387,42 @@
     }
 
     /**
+     * Parse @KeyColumn(s).
+     */
+    private void parseKeyColumns(FieldMapping fm, KeyColumn... pcols) {
+        if (pcols.length == 0)
+            return;
+
+        List<Column> cols = new ArrayList<Column>(pcols.length);
+        int unique = 0;
+        for (int i = 0; i < pcols.length; i++) {
+            cols.add(newColumn(pcols[i]));
+            unique |= (pcols[i].unique()) ? TRUE : FALSE;
+        }
+        setColumns(fm, fm.getKeyMapping().getValueInfo(), cols, unique);
+    }
+
+    /**
+     * Create a new schema column with information from the given annotation.
+     */
+    private static Column newColumn(KeyColumn anno) {
+        Column col = new Column();
+        if (!StringUtils.isEmpty(anno.name()))
+            col.setName(anno.name());
+        if (!StringUtils.isEmpty(anno.columnDefinition()))
+            col.setTypeName(anno.columnDefinition());
+        if (anno.precision() != 0)
+            col.setSize(anno.precision());
+        else if (anno.length() != 255)
+            col.setSize(anno.length());
+        col.setNotNull(!anno.nullable());
+        col.setDecimalDigits(anno.scale());
+        col.setFlag(Column.FLAG_UNINSERTABLE, !anno.insertable());
+        col.setFlag(Column.FLAG_UNUPDATABLE, !anno.updatable());
+        return col;
+    }
+
+    /**
      * Parse given @PrimaryKeyJoinColumn annotations.
      */
     private void parsePrimaryKeyJoinColumns(FieldMapping fm,
@@ -1277,6 +1503,41 @@
             return;
 
         ValueMappingInfo info = fm.getValueInfo();
+        populateNullIndicator(nullInd, info);
+    }
+
+    /**
+     * Parse embedded info for the given mapping.
+     */
+    private void parseEmbeddedMapping(ValueMapping vm, 
+        String nullIndicatorAttribute, String nullIndicatorColumn,
+        XMappingOverride[] overrides) {
+        ClassMapping embed = vm.getEmbeddedMapping();
+        if (embed == null)
+            throw new MetaDataException(_loc.get("not-embedded", vm));
+
+        FieldMapping efm;
+        for (XMappingOverride over : overrides) {
+            efm = embed.getFieldMapping(over.name());
+            if (efm == null)
+                throw new MetaDataException(_loc.get("embed-override-name",
+                    vm, over.name()));
+            populate(efm, over);
+        }
+
+        String nullInd = null;
+        if (!StringUtils.isEmpty(nullIndicatorAttribute))
+            nullInd = nullIndicatorAttribute;
+        else if (!StringUtils.isEmpty(nullIndicatorColumn))
+            nullInd = nullIndicatorColumn;
+        if (nullInd == null)
+            return;
+
+        ValueMappingInfo info = vm.getValueInfo();
+        populateNullIndicator(nullInd, info);
+    }
+
+    private void populateNullIndicator(String nullInd, ValueMappingInfo info) {
         if ("false".equals(nullInd))
             info.setCanIndicateNull(false);
         else {

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementColumn.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementColumn.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementColumn.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementColumn.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Array, collection, or map element column.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface ElementColumn {
+
+    String name() default "";
+
+    boolean unique() default false;
+
+    boolean nullable() default true;
+
+    boolean insertable() default true;
+
+    boolean updatable() default true;
+
+    String columnDefinition() default "";
+
+    int length() default 255;
+
+    int precision() default 0; // decimal precision
+
+    int scale() default 0; // decimal scale
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementColumns.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementColumns.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementColumns.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementColumns.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Allows the specification of multiple element columns for complex
+ * mappings.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface ElementColumns {
+
+    ElementColumn[] value() default {};
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementEmbeddedMapping.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementEmbeddedMapping.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementEmbeddedMapping.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementEmbeddedMapping.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Embedded mapping information for an array, collection, or map
+ * element.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface ElementEmbeddedMapping {
+
+    public static final String TRUE = "true";
+    public static final String FALSE = "false";
+
+    String nullIndicatorColumnName() default "";
+
+    String nullIndicatorAttributeName() default "";
+
+    XMappingOverride[] overrides() default {};
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementStrategy.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementStrategy.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementStrategy.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ElementStrategy.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Array, collection, or map element mapping strategy.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface ElementStrategy {
+
+    String value() default "";
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyClassCriteria.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyClassCriteria.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyClassCriteria.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyClassCriteria.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Marker interface specifying to use the expected class of the map key
+ * relation as criteria in the join.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyClassCriteria {
+
+    boolean value() default true;
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyColumn.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyColumn.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyColumn.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyColumn.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Map key column.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyColumn {
+
+    String name() default "";
+
+    boolean unique() default false;
+
+    boolean nullable() default true;
+
+    boolean insertable() default true;
+
+    boolean updatable() default true;
+
+    String columnDefinition() default "";
+
+    int length() default 255;
+
+    int precision() default 0; // decimal precision
+
+    int scale() default 0; // decimal scale
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyColumns.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyColumns.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyColumns.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyColumns.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Allows the specification of multiple map key columns for complex
+ * mappings.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyColumns {
+
+    KeyColumn[] value() default {};
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyEmbeddedMapping.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyEmbeddedMapping.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyEmbeddedMapping.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyEmbeddedMapping.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Embedded mapping information for a map key.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyEmbeddedMapping {
+
+    public static final String TRUE = "true";
+    public static final String FALSE = "false";
+
+    String nullIndicatorColumnName() default "";
+
+    String nullIndicatorAttributeName() default "";
+
+    XMappingOverride[] overrides() default {};
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyForeignKey.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyForeignKey.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyForeignKey.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyForeignKey.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Foreign key on map key columns.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyForeignKey {
+
+    String name() default "";
+
+    boolean enabled() default true;
+
+    boolean deferred() default false;
+
+    ForeignKeyAction deleteAction() default ForeignKeyAction.RESTRICT;
+
+    ForeignKeyAction updateAction() default ForeignKeyAction.RESTRICT;
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyIndex.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyIndex.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyIndex.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyIndex.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Index on map key columns.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyIndex {
+
+    String name() default "";
+
+    boolean enabled() default true;
+
+    boolean unique() default false;
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyJoinColumn.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyJoinColumn.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyJoinColumn.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyJoinColumn.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Map key join column.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyJoinColumn {
+
+    String name() default "";
+
+    String referencedColumnName() default "";
+
+    String referencedAttributeName() default "";
+
+    boolean unique() default false;
+
+    boolean nullable() default true;
+
+    boolean insertable() default true;
+
+    boolean updatable() default true;
+
+    String columnDefinition() default "";
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyJoinColumns.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyJoinColumns.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyJoinColumns.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyJoinColumns.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Allows the specification of multiple map key columns for compound
+ * joins.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyJoinColumns {
+
+    KeyJoinColumn[] value() default {};
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyNonpolymorphic.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyNonpolymorphic.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyNonpolymorphic.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyNonpolymorphic.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Indicates that the annotated map's keys are not entirely polymorphic.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyNonpolymorphic {
+
+    NonpolymorphicType value() default NonpolymorphicType.EXACT;
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyStrategy.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyStrategy.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyStrategy.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/KeyStrategy.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Map key mapping strategy.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface KeyStrategy {
+
+    String value() default "";
+}

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/MappingTag.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/MappingTag.java?rev=592917&r1=592916&r2=592917&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/MappingTag.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/MappingTag.java Wed Nov  7 13:46:09 2007
@@ -65,14 +65,28 @@
     DISCRIM_STRAT,
     EAGER_FETCH_MODE,
     ELEM_CLASS_CRIT,
+    ELEM_COL,
+    ELEM_COLS,
+    ELEM_EMBEDDED_MAPPING,
     ELEM_FK,
     ELEM_INDEX,
     ELEM_JOIN_COL,
     ELEM_JOIN_COLS,
     ELEM_NONPOLY,
+    ELEM_STRAT,
     EMBEDDED_MAPPING,
     FK,
     INDEX,
+    KEY_COL,
+    KEY_COLS,
+    KEY_CLASS_CRIT,
+    KEY_EMBEDDED_MAPPING,
+    KEY_FK,
+    KEY_INDEX,
+    KEY_JOIN_COL,
+    KEY_JOIN_COLS,
+    KEY_NONPOLY,
+    KEY_STRAT,
     MAPPING_OVERRIDE,
     MAPPING_OVERRIDES,
     NONPOLY,
@@ -83,8 +97,11 @@
     VERSION_COL,
     VERSION_COLS,
     VERSION_STRAT,
+    X_EMBEDDED_MAPPING,
     X_JOIN_COL,
     X_JOIN_COLS,
+    X_MAPPING_OVERRIDE,
+    X_MAPPING_OVERRIDES,
     X_SECONDARY_TABLE,
     X_SECONDARY_TABLES,
     X_TABLE,

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XEmbeddedMapping.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XEmbeddedMapping.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XEmbeddedMapping.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XEmbeddedMapping.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Embedded mapping information.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface XEmbeddedMapping {
+
+    public static final String TRUE = "true";
+    public static final String FALSE = "false";
+
+    String nullIndicatorColumnName() default "";
+
+    String nullIndicatorAttributeName() default "";
+
+    XMappingOverride[] overrides() default {};
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMappingOverride.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMappingOverride.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMappingOverride.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMappingOverride.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+import javax.persistence.Column;
+
+/**
+ * <p>Allows override of complex embedded or superclass mappings.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ TYPE })
+@Retention(RUNTIME)
+public @interface XMappingOverride {
+
+    String name() default "";
+
+    Column[] columns() default {};
+
+    XJoinColumn[] joinColumns() default {};
+
+    ElementColumn[] elementColumns() default {};
+
+    ElementJoinColumn[] elementJoinColumns() default {};
+
+    KeyColumn[] keyColumns() default {};
+
+    KeyJoinColumn[] keyJoinColumns() default {};
+
+    ContainerTable containerTable() default @ContainerTable(specified = false);
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMappingOverrides.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMappingOverrides.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMappingOverrides.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMappingOverrides.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc;
+
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Allows override of complex embedded or superclass mappings.</p>
+ *
+ * @author Abe White
+ * @since 0.4.0, 1.1.0
+ */
+@Target({ TYPE })
+@Retention(RUNTIME)
+public @interface XMappingOverrides {
+
+    XMappingOverride[] value() default {};
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/NonstandardMappingEntity.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/NonstandardMappingEntity.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/NonstandardMappingEntity.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/NonstandardMappingEntity.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc.annotations;
+
+
+import java.awt.*;
+import java.util.*;
+import java.util.List;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.jdbc.meta.strats.*;
+import org.apache.openjpa.persistence.*;
+import org.apache.openjpa.persistence.jdbc.*;
+
+
+@Entity
+@Table(name = "NONSTD_ENTITY")
+@DataStoreIdColumn(name = "OID")
+@DiscriminatorStrategy(ClassNameDiscriminatorStrategy.ALIAS)
+@DiscriminatorColumn(name = "DISCRIM", length = 128)
+@XMappingOverride(name = "superCollection",
+    containerTable = @ContainerTable(name = "SUP_COLL",
+        joinColumns = @XJoinColumn(name = "OWNER")),
+    elementColumns = @ElementColumn(name = "SUP_ELEM"))
+public class NonstandardMappingEntity
+    extends NonstandardMappingMappedSuper {
+
+    @Persistent(fetch = FetchType.LAZY)
+    @Strategy("org.apache.openjpa.persistence.jdbc.annotations.PointHandler")
+    @Columns({
+    @Column(name = "X_COL"),
+    @Column(name = "Y_COL")
+        })
+    @Index(name = "PNT_IDX")
+    private Point custom;
+
+    @PersistentCollection(elementType = String.class)
+    @ContainerTable(name = "STRINGS_COLL",
+        joinColumns = @XJoinColumn(name = "OWNER"),
+        joinIndex = @Index(enabled = false))
+    @ElementColumn(name = "STR_ELEM", length = 127)
+    @OrderColumn(name = "ORDER_COL")
+    @ElementIndex
+    private List stringCollection = new ArrayList();
+
+    @PersistentCollection
+    @ContainerTable(name = "JOIN_COLL",
+        joinColumns = @XJoinColumn(name = "OWNER"),
+        joinForeignKey = @ForeignKey)
+    @ElementJoinColumn(name = "JOIN_ELEM")
+    @ElementForeignKey
+    @ElementNonpolymorphic(NonpolymorphicType.JOINABLE)
+    private List<NonstandardMappingEntity> joinCollection =
+        new ArrayList<NonstandardMappingEntity>();
+
+    @PersistentMap(keyType = String.class, elementType = String.class)
+    @ContainerTable(name = "STRINGS_MAP",
+        joinColumns = @XJoinColumn(name = "OWNER"),
+        joinIndex = @Index(enabled = false))
+    @KeyColumn(name = "STR_KEY", length = 127)
+    @ElementColumn(name = "STR_VAL", length = 127)
+    @KeyIndex
+    @ElementIndex
+    private Map stringMap = new HashMap();
+
+    @PersistentMap
+    @ContainerTable(name = "JOIN_MAP",
+        joinColumns = @XJoinColumn(name = "OWNER"),
+        joinForeignKey = @ForeignKey)
+    @KeyJoinColumn(name = "JOIN_KEY")
+    @KeyForeignKey
+    @KeyNonpolymorphic
+    @ElementJoinColumn(name = "JOIN_VAL")
+    @ElementForeignKey
+    @ElementNonpolymorphic
+    private Map<NonstandardMappingEntity, NonstandardMappingEntity> joinMap =
+        new HashMap<NonstandardMappingEntity, NonstandardMappingEntity>();
+
+    @Embedded
+    @EmbeddedMapping(nullIndicatorAttributeName = "uuid", overrides = {
+    @MappingOverride(name = "rel",
+        joinColumns = @XJoinColumn(name = "EM_REL_ID")),
+    @MappingOverride(name = "eager",
+        containerTable = @ContainerTable(name = "EM_EAGER"),
+        elementJoinColumns = @ElementJoinColumn(name = "ELEM_EAGER_ID"))
+        })
+    private ExtensionsEntity embed;
+
+    @PersistentCollection(elementEmbedded = true)
+    @ContainerTable(name = "EMBED_COLL")
+    @ElementEmbeddedMapping(overrides = {
+    @XMappingOverride(name = "basic", columns = @Column(name = "EM_BASIC"))
+        })
+    private List<EmbedValue2> embedCollection = new ArrayList<EmbedValue2>();
+
+    public Point getCustom() {
+        return this.custom;
+    }
+
+    public void setCustom(Point custom) {
+        this.custom = custom;
+    }
+
+    public List getStringCollection() {
+        return this.stringCollection;
+    }
+
+    public List<NonstandardMappingEntity> getJoinCollection() {
+        return this.joinCollection;
+    }
+
+    public Map getStringMap() {
+        return this.stringMap;
+    }
+
+    public Map<NonstandardMappingEntity,NonstandardMappingEntity> getJoinMap() {
+        return this.joinMap;
+    }
+
+    public ExtensionsEntity getEmbed() {
+        return this.embed;
+    }
+
+    public void setEmbed(ExtensionsEntity embed) {
+        this.embed = embed;
+    }
+
+    public List<EmbedValue2> getEmbedCollection() {
+        return this.embedCollection;
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/NonstandardMappingMappedSuper.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/NonstandardMappingMappedSuper.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/NonstandardMappingMappedSuper.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/NonstandardMappingMappedSuper.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc.annotations;
+
+
+import java.util.*;
+
+import javax.persistence.*;
+
+import org.apache.openjpa.persistence.*;
+import org.apache.openjpa.persistence.jdbc.*;
+
+@MappedSuperclass
+public class NonstandardMappingMappedSuper {
+
+    @PersistentCollection
+    private List<String> superCollection = new ArrayList<String>();
+
+    @ManyToOne
+    @Nonpolymorphic
+    NonstandardMappingEntity superRel;
+
+    public List<String> getSuperCollection() {
+        return this.superCollection;
+    }
+
+    public NonstandardMappingEntity getSuperRel() {
+        return this.superRel;
+    }
+
+    public void setSuperRel(NonstandardMappingEntity superRel) {
+        this.superRel = superRel;
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/PointHandler.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/PointHandler.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/PointHandler.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/PointHandler.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc.annotations;
+
+import java.awt.*;
+
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ValueMapping;
+import org.apache.openjpa.jdbc.meta.strats.AbstractValueHandler;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ColumnIO;
+import org.apache.openjpa.meta.JavaTypes;
+import serp.util.Numbers;
+
+/**
+ * Handler for {@link Point}. This is a sample of how to create custom
+ * handlers, and is in this package for unit testing purposes.
+ */
+public class PointHandler extends AbstractValueHandler {
+
+        /**
+     * Create columns with default names and java type values.  Kodo will
+     * fill in the rest of the information and merge in any information given
+     * in the user's mapping data.  If the user does not give column names,
+     * Kodo will alter your default names as necessary to avoid conflicts and
+     * meet the database's name limitations.
+     *
+     * @param    name    default base name for columns
+     */
+    public Column[] map(ValueMapping vm, String name, ColumnIO io,
+        boolean adapt) {
+        Column xcol = new Column();
+        xcol.setName("X" + name);
+        xcol.setJavaType(JavaTypes.INT);
+        Column ycol = new Column();
+        ycol.setName("Y" + name);
+        ycol.setJavaType(JavaTypes.INT);
+        return new Column[]{ xcol, ycol };
+    }
+
+    /**
+     * Return whether the column value is an exact value that can be used
+     * in state-comparison versioning.
+     */
+    public boolean isVersionable() {
+        return true;
+    }
+
+    /**
+     * Convert the object value to its datastore equivalent.
+     */
+    public Object toDataStoreValue(ValueMapping vm, Object val,
+        JDBCStore store) {
+        if (val == null)
+            return null;
+
+        Point p = (Point) val;
+        return new Object[]{ Numbers.valueOf(p.x), Numbers.valueOf(p.y) };
+    }
+
+    /**
+     *  Convert the datastore value to its object equivalent.
+     */
+    public Object toObjectValue(ValueMapping vm, Object val) {
+        Object[] vals = (Object[]) val;
+        if (vals[0] == null || vals[1] == null)
+            return null;
+
+        int x = ((Number) vals[0]).intValue();
+        int y = ((Number) vals[1]).intValue();
+        return new Point(x, y);
+    }
+}

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestDiscriminator.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestDiscriminator.java?rev=592917&r1=592916&r2=592917&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestDiscriminator.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestDiscriminator.java Wed Nov  7 13:46:09 2007
@@ -20,6 +20,7 @@
 
 import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
 import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.MappingRepository;
 import org.apache.openjpa.jdbc.meta.strats.NoneDiscriminatorStrategy;
 import org.apache.openjpa.jdbc.meta.strats.SubclassJoinDiscriminatorStrategy;
 import org.apache.openjpa.jdbc.meta.strats.ValueMapDiscriminatorStrategy;
@@ -31,11 +32,15 @@
  *
  * @author Abe White
  */
-public abstract class TestDiscriminator
+public class TestDiscriminator
     extends SingleEMFTestCase {
 
-    public void setUp() {
-        //  #####
+    public void setUp() throws Exception {
+        super.setUp(AnnoTest1.class, AnnoTest2.class, Flat1.class,
+            CLEAR_TABLES);
+        // Commented out since OpenJPA does not have Entity1 and Entity2.
+        // These tests should be ported to use classes that are available
+        // in OpenJPA.
 //        setUp(Entity1.class, Entity2.class, AnnoTest1.class, CLEAR_TABLES);
     }
 
@@ -55,8 +60,9 @@
 //    }
 
     public void testJoinedDiscriminatorWithColumn() {
-        ClassMapping cls = ((JDBCConfiguration) emf.getConfiguration()).
-            getMappingRepositoryInstance().getMapping(AnnoTest1.class, 
+        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
+        MappingRepository repo = conf.getMappingRepositoryInstance();
+        ClassMapping cls = repo.getMapping(AnnoTest1.class, 
             null, true);
         assertTrue(cls.getDiscriminator().getStrategy()
             instanceof ValueMapDiscriminatorStrategy);

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestNonstandardMappingAnnotations.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestNonstandardMappingAnnotations.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestNonstandardMappingAnnotations.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestNonstandardMappingAnnotations.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,280 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.jdbc.annotations;
+
+import java.awt.*;
+import java.util.Map;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.Discriminator;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.ValueMapping;
+import org.apache.openjpa.jdbc.meta.strats.ClassNameDiscriminatorStrategy;
+import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * <p>Test the parsing of non-standard mapping annotations.</p>
+ *
+ * @author Abe White
+ */
+public class TestNonstandardMappingAnnotations
+    extends SingleEMFTestCase {
+
+    private ClassMapping _mapping;
+    private DBDictionary _dict;
+
+    public void setUp() {
+        setUp(NonstandardMappingEntity.class, ExtensionsEntity.class,
+            NonstandardMappingMappedSuper.class, EmbedValue2.class,
+            EmbedValue.class,
+            CLEAR_TABLES);
+
+        // trigger complete resolution of metadata etc.
+        emf.createEntityManager().close();
+
+        JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
+        _dict = conf.getDBDictionaryInstance();
+        _mapping = (ClassMapping) JPAFacadeHelper.getMetaData(emf,
+            NonstandardMappingEntity.class);
+    }
+
+    public void testNonpolymorphic() {
+        FieldMapping fm = _mapping.getFieldMapping("superRel");
+        assertEquals(ValueMapping.POLY_FALSE, fm.getPolymorphic());
+
+        ValueMapping vm = _mapping.getFieldMapping("joinCollection").
+            getElementMapping();
+        assertEquals(ValueMapping.POLY_JOINABLE, vm.getPolymorphic());
+
+        vm = _mapping.getFieldMapping("joinMap").getKeyMapping();
+        assertEquals(ValueMapping.POLY_FALSE, vm.getPolymorphic());
+        vm = _mapping.getFieldMapping("joinMap").getElementMapping();
+        assertEquals(ValueMapping.POLY_FALSE, vm.getPolymorphic());
+    }
+
+    public void testDataStoreIdColumn() {
+        assertEquals("NONSTD_ENTITY", _mapping.getTable().getName());
+        assertEquals(ClassMapping.ID_DATASTORE, _mapping.getIdentityType());
+        assertEquals(1, _mapping.getPrimaryKeyColumns().length);
+        assertEquals("OID", _mapping.getPrimaryKeyColumns()[0].getName());
+    }
+
+    public void testDiscriminator() {
+        Discriminator disc = _mapping.getDiscriminator();
+        assertTrue(disc.getStrategy() instanceof
+            ClassNameDiscriminatorStrategy);
+        assertEquals(1, disc.getColumns().length);
+        assertEquals("DISCRIM", disc.getColumns()[0].getName());
+    }
+
+    public void testSuperclassOverride() {
+        FieldMapping fm = _mapping.getFieldMapping("superCollection");
+        assertEquals("SUP_COLL", fm.getTable().getName());
+        assertEquals(1, fm.getJoinForeignKey().getColumns().length);
+        assertEquals("OWNER", fm.getJoinForeignKey().getColumns()[0].
+            getName());
+        assertEquals(1, fm.getElementMapping().getColumns().length);
+        assertEquals("SUP_ELEM", fm.getElementMapping().getColumns()[0].
+            getName());
+        assertNull(fm.getElementMapping().getValueIndex());
+        assertNotNull(fm.getJoinIndex());
+    }
+
+    public void testCustomField() {
+        FieldMapping fm = _mapping.getFieldMapping("custom");
+        assertTrue(fm.getHandler() instanceof PointHandler);
+        assertEquals(2, fm.getColumns().length);
+        assertEquals("X_COL", fm.getColumns()[0].getName());
+        assertEquals("Y_COL", fm.getColumns()[1].getName());
+        assertNotNull(fm.getValueIndex());
+    }
+
+    public void testValueCollection() {
+        FieldMapping fm = _mapping.getFieldMapping("stringCollection");
+        assertEquals("STRINGS_COLL", fm.getTable().getName());
+        assertEquals(1, fm.getJoinForeignKey().getColumns().length);
+        assertEquals("OWNER", fm.getJoinForeignKey().getColumns()[0].
+            getName());
+        assertEquals(1, fm.getElementMapping().getColumns().length);
+        assertEquals("STR_ELEM", fm.getElementMapping().getColumns()[0].
+            getName());
+        assertEquals(127, fm.getElementMapping().getColumns()[0].getSize());
+        assertNotNull(fm.getElementMapping().getValueIndex());
+        assertNull(fm.getJoinIndex());
+    }
+
+    public void testJoinCollection() {
+        FieldMapping fm = _mapping.getFieldMapping("joinCollection");
+        assertEquals("JOIN_COLL", fm.getTable().getName());
+        assertEquals(1, fm.getJoinForeignKey().getColumns().length);
+        assertEquals("OWNER", fm.getJoinForeignKey().getColumns()[0].
+            getName());
+        assertEquals(1, fm.getElementMapping().getColumns().length);
+        assertEquals("JOIN_ELEM", fm.getElementMapping().getColumns()[0].
+            getName());
+        assertForeignKey(fm.getJoinForeignKey());
+        assertForeignKey(fm.getElementMapping().getForeignKey());
+    }
+
+    private void assertForeignKey(ForeignKey fk) {
+        if (_dict.supportsForeignKeys)
+            assertEquals(ForeignKey.ACTION_RESTRICT, fk.getDeleteAction());
+    }
+
+    public void testValueMap() {
+        FieldMapping fm = _mapping.getFieldMapping("stringMap");
+        assertEquals("STRINGS_MAP", fm.getTable().getName());
+        assertEquals(1, fm.getJoinForeignKey().getColumns().length);
+        assertEquals("OWNER", fm.getJoinForeignKey().getColumns()[0].
+            getName());
+        assertEquals(1, fm.getKeyMapping().getColumns().length);
+        assertEquals("STR_KEY", fm.getKeyMapping().getColumns()[0].
+            getName());
+        assertEquals(127, fm.getKeyMapping().getColumns()[0].getSize());
+        assertEquals(1, fm.getElementMapping().getColumns().length);
+        assertEquals("STR_VAL", fm.getElementMapping().getColumns()[0].
+            getName());
+        assertEquals(127, fm.getElementMapping().getColumns()[0].getSize());
+        assertNull(fm.getJoinIndex());
+        assertNotNull(fm.getKeyMapping().getValueIndex());
+        assertNotNull(fm.getElementMapping().getValueIndex());
+    }
+
+    public void testJoinMap() {
+        FieldMapping fm = _mapping.getFieldMapping("joinMap");
+        assertEquals("JOIN_MAP", fm.getTable().getName());
+        assertEquals(1, fm.getJoinForeignKey().getColumns().length);
+        assertEquals("OWNER", fm.getJoinForeignKey().getColumns()[0].
+            getName());
+        assertEquals(1, fm.getKeyMapping().getColumns().length);
+        assertEquals("JOIN_KEY", fm.getKeyMapping().getColumns()[0].
+            getName());
+        assertEquals(1, fm.getElementMapping().getColumns().length);
+        assertEquals("JOIN_VAL", fm.getElementMapping().getColumns()[0].
+            getName());
+        assertForeignKey(fm.getJoinForeignKey());
+        assertForeignKey(fm.getKeyMapping().getForeignKey());
+        assertForeignKey(fm.getElementMapping().getForeignKey());
+    }
+
+    public void testEmbeddedOverride() {
+        FieldMapping fm = _mapping.getFieldMapping("embed");
+        assertTrue(fm.isEmbedded());
+        assertEquals(1, fm.getColumns().length);
+        assertTrue("UUID_HEX".equalsIgnoreCase(fm.getColumns()[0].
+            getName()));
+
+        ClassMapping embed = fm.getEmbeddedMapping();
+        fm = embed.getFieldMapping("rel");
+        assertEquals(1, fm.getColumns().length);
+        assertEquals("EM_REL_ID", fm.getColumns()[0].getName());
+        fm = embed.getFieldMapping("eager");
+        assertEquals("EM_EAGER", fm.getTable().getName());
+        assertEquals(1, fm.getElementMapping().getColumns().length);
+        assertEquals("ELEM_EAGER_ID", fm.getElementMapping().getColumns()[0].
+            getName());
+    }
+
+    public void testEmbeddedElementOverride() {
+        FieldMapping fm = _mapping.getFieldMapping("embedCollection");
+        assertTrue(fm.getElement().isEmbedded());
+        assertEquals("EMBED_COLL", fm.getTable().getName());
+        assertEquals(0, fm.getElementMapping().getColumns().length);
+
+        ClassMapping embed = fm.getElementMapping().getEmbeddedMapping();
+        fm = embed.getFieldMapping("basic");
+        assertEquals(1, fm.getColumns().length);
+        assertEquals("EM_BASIC", fm.getColumns()[0].getName());
+    }
+
+    public void testInsertAndRetrieve() {
+        NonstandardMappingEntity pc = new NonstandardMappingEntity();
+        pc.getSuperCollection().add("super");
+        pc.setCustom(new Point(1, 2));
+        pc.getStringCollection().add("string");
+        NonstandardMappingEntity pc2 = new NonstandardMappingEntity();
+        pc.getJoinCollection().add(pc2);
+        pc.getStringMap().put("stringKey", "stringValue");
+        NonstandardMappingEntity pc3 = new NonstandardMappingEntity();
+        pc.getJoinMap().put(pc2, pc3);
+        ExtensionsEntity embed = new ExtensionsEntity();
+        embed.setExternalValues('M');
+        embed.setExternalizer(String.class);
+        pc.setEmbed(embed);
+        EmbedValue2 embed2 = new EmbedValue2();
+        embed2.setBasic("basic");
+        pc.getEmbedCollection().add(embed2);
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persistAll(new Object[]{ pc, pc2, pc3 });
+        em.getTransaction().commit();
+        Object pcId = em.getObjectId(pc);
+        Object pc2Id = em.getObjectId(pc2);
+        Object pc3Id = em.getObjectId(pc3);
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(NonstandardMappingEntity.class, pcId);
+        assertEquals(1, pc.getSuperCollection().size());
+        assertEquals("super", pc.getSuperCollection().get(0));
+        assertEquals(1, pc.getCustom().x);
+        assertEquals(2, pc.getCustom().y);
+        assertEquals(1, pc.getStringCollection().size());
+        assertEquals("string", pc.getStringCollection().get(0));
+        assertEquals(1, pc.getJoinCollection().size());
+        assertEquals(pc2Id, em.getObjectId(pc.getJoinCollection().get(0)));
+        assertEquals(1, pc.getStringMap().size());
+        assertEquals("stringValue", pc.getStringMap().get("stringKey"));
+        assertEquals(1, pc.getJoinMap().size());
+        Map.Entry entry = pc.getJoinMap().entrySet().iterator().next();
+        assertEquals(pc2Id, em.getObjectId(entry.getKey()));
+        assertEquals(pc3Id, em.getObjectId(entry.getValue()));
+        assertEquals('M', pc.getEmbed().getExternalValues());
+        assertEquals(String.class, pc.getEmbed().getExternalizer());
+        assertEquals(1, pc.getEmbedCollection().size());
+        assertEquals("basic", pc.getEmbedCollection().get(0).getBasic());
+        em.close();
+    }
+
+    public void testInsertAndRetrieveEmbeddedCollection() {
+        NonstandardMappingEntity pc = new NonstandardMappingEntity();
+        EmbedValue2 embed2 = new EmbedValue2();
+        embed2.setBasic("basic");
+        pc.getEmbedCollection().add(embed2);
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(pc);
+        em.getTransaction().commit();
+        Object pcId = em.getObjectId(pc);
+        em.close();
+
+        em = emf.createEntityManager();
+        pc = em.find(NonstandardMappingEntity.class, pcId);
+        assertEquals(1, pc.getEmbedCollection().size());
+        assertEquals("basic", pc.getEmbedCollection().get(0).getBasic());
+        em.close();
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerCollectionInstance.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerCollectionInstance.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerCollectionInstance.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerCollectionInstance.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.relations;
+
+import java.util.Collection;
+import java.util.HashSet;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+import org.apache.openjpa.persistence.PersistentCollection;
+
+@Entity
+public class HandlerCollectionInstance {
+    @Id
+    private int id;
+
+    @PersistentCollection
+    private Collection<String> collection = new HashSet<String>();
+
+    public Collection<String> getCollection() {
+        return collection;
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerToHandlerMapInstance.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerToHandlerMapInstance.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerToHandlerMapInstance.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerToHandlerMapInstance.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.relations;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+import org.apache.openjpa.persistence.PersistentMap;
+import org.apache.openjpa.persistence.jdbc.ContainerTable;
+import org.apache.openjpa.persistence.jdbc.KeyColumn;
+
+@Entity
+public class HandlerToHandlerMapInstance {
+    @Id
+    private int id;
+
+    @PersistentMap
+    @ContainerTable(name="NONSTD_MAPPING_MAP")
+    // needed because we hard-code 'key' in the handler FieldStrategies
+    @KeyColumn(name="key_col") 
+    private Map<String,String> map = new HashMap<String,String>();
+
+    public Map<String,String> getMap() {
+        return map;
+    }
+}
\ No newline at end of file

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerToRelationMapInstance.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerToRelationMapInstance.java?rev=592917&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerToRelationMapInstance.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/HandlerToRelationMapInstance.java Wed Nov  7 13:46:09 2007
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.persistence.relations;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+import org.apache.openjpa.persistence.PersistentMap;
+import org.apache.openjpa.persistence.jdbc.KeyColumn;
+import org.apache.openjpa.persistence.simple.AllFieldTypes;
+
+@Entity
+public class HandlerToRelationMapInstance {
+    @Id
+    private int id;
+
+    @PersistentMap(elementCascade = CascadeType.PERSIST)
+    // needed because we hard-code 'key' in the handler FieldStrategies
+    @KeyColumn(name="key_col")
+    private Map<String,AllFieldTypes> map = new HashMap<String,AllFieldTypes>();
+
+    public Map<String,AllFieldTypes> getMap() {
+        return map;
+    }
+}
\ No newline at end of file