OPENJPA-2366 Committing code and unit tests contributed by Austin Dorenkamp

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1519550 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jeremy Bauer 2013-09-03 04:18:09 +00:00
parent 7a9815a15f
commit 9f8a682a03
11 changed files with 270 additions and 4 deletions

View File

@ -46,6 +46,7 @@ import org.apache.tools.ant.types.EnumeratedAttribute;
* <li><code>package</code></li>
* <li><code>directory</code></li>
* <li><code>useSchemaName</code></li>
* <li><code>useSchemaElement</code></li>
* <li><code>useForeignKeyName</code></li>
* <li><code>nullableAsObject</code></li>
* <li><code>blobAsObject</code></li>
@ -103,6 +104,13 @@ public class ReverseMappingToolTask
public void setUseSchemaName(boolean useSchemaName) {
flags.useSchemaName = useSchemaName;
}
/**
* Set whether to use the schema name in generated files
*/
public void setUseSchemaElement(boolean useSchemaElement) {
flags.useSchemaElement = useSchemaElement;
}
/**
* Set whether to use foreign key names to name relations.

View File

@ -206,6 +206,7 @@ public class ReverseMappingTool
private ReverseCustomizer _custom = null;
private String _discStrat = null;
private String _versStrat = null;
private boolean _useSchemaElement = true;
// we have to track field names that were created but then abandoned by
// the customizer so that we don't attempt to use them again; doing so can
@ -576,6 +577,25 @@ public class ReverseMappingTool
customizer.setTool(this);
_custom = customizer;
}
/**
* Returns whether or not the schema name will be included in the @Table
* annotation within the generated class for each table, as well as the
* corresponding XML mapping files. The initialized value is true (in order
* to preserve backwards compatibility).
*/
public boolean getUseSchemaElement() {
return _useSchemaElement;
}
/**
* Sets whether or not the schema name will be included in the @Table
* annotation within the generated class for each table, as well as the
* corresponding XML mapping files.
*/
public void setUseSchemaElement(boolean useSchemaElement) {
_useSchemaElement = useSchemaElement;
}
/**
* Return the mapping repository used to hold generated mappings. You
@ -906,8 +926,10 @@ public class ReverseMappingTool
// pretend mappings are all resolved
ClassMapping[] mappings = getMappings();
for (int i = 0; i < mappings.length; i++)
{
mappings[i].setResolve(MODE_META | MODE_MAPPING, true);
mappings[i].setUseSchemaElement(getUseSchemaElement());
}
// store in user's configured IO
MetaDataFactory mdf = _conf.newMetaDataFactoryInstance();
mdf.setRepository(getRepository());
@ -929,8 +951,10 @@ public class ReverseMappingTool
// pretend mappings are all resolved
ClassMapping[] mappings = getMappings();
for (int i = 0; i < mappings.length; i++)
{
mappings[i].setResolve(MODE_META | MODE_MAPPING, true);
mappings[i].setUseSchemaElement(getUseSchemaElement());
}
// store in user's configured IO
MetaDataFactory mdf = _conf.newMetaDataFactoryInstance();
mdf.setRepository(getRepository());
@ -1727,6 +1751,7 @@ public class ReverseMappingTool
tool.setGenerateAnnotations(getGenerateAnnotations());
tool.setCustomizer(getCustomizer());
tool.setCodeFormat(getCodeFormat());
tool.setUseSchemaElement(getUseSchemaElement());
return tool;
}
@ -1757,6 +1782,12 @@ public class ReverseMappingTool
* <li><i>-useSchemaName/-sn &lt;true/t | false/f&gt;</i>: Set this flag to
* true to include the schema name as part of the generated class name
* for each table.</li>
* <li><i>-useSchemaElement/-se &lt;true/t | false/f&gt;</i>: Set this
* flag to false to exclude the schema name from the @Table annotation
* in the generated class for each table. If set to false, the schema
* name will also be removed from the corresponding XML mapping files
* (orm.xml) that are generated by the tool. The initialized value is
* true (in order to preserve backwards compatibility). </li>
* <li><i>-useForeignKeyName/-fkn &lt;true/t | false/f&gt;</i>: Set this
* flag to true to use the foreign key name to generate fields
* representing relations between classes.</li>
@ -1887,6 +1918,8 @@ public class ReverseMappingTool
("annotations", "ann", flags.generateAnnotations);
flags.accessType = opts.removeProperty
("accessType", "access", flags.accessType);
flags.useSchemaElement = opts.removeBooleanProperty
("useSchemaElement", "se", flags.useSchemaElement);
String typeMap = opts.removeProperty("typeMap", "typ", null);
if (typeMap != null)
@ -2009,6 +2042,7 @@ public class ReverseMappingTool
tool.setAccessType(flags.accessType);
tool.setCustomizer(flags.customizer);
tool.setCodeFormat(flags.format);
tool.setUseSchemaElement(flags.useSchemaElement);
// run
log.info(_loc.get("revtool-map"));
@ -2052,6 +2086,7 @@ public class ReverseMappingTool
public String versionStrategy = null;
public ReverseCustomizer customizer = null;
public CodeFormat format = null;
public boolean useSchemaElement = true;
}
/**

View File

@ -223,6 +223,7 @@ public class ClassMetaData
private Boolean inverseManagedFields = null;
private List<FieldMetaData> _mappedByIdFields;
private boolean _mappedByIdFieldsSet = false;
private boolean _useSchemaElement = true;
/**
* Constructor. Supply described type and repository.
@ -2823,4 +2824,18 @@ public class ClassMetaData
}
return _mappedByIdFields;
}
/**
* Set whether to include schema name in generated class files
*/
public boolean getUseSchemaElement() {
return _useSchemaElement;
}
/**
* Get whether to include schema name in generated class files
*/
public void setUseSchemaElement(boolean useSchemaElement) {
this._useSchemaElement = useSchemaElement;
}
}

View File

@ -187,6 +187,7 @@ public class FieldMetaData
private Boolean _lobField = null;
private Boolean _serializableField = null;
private boolean _generated = false;
private boolean _useSchemaElement = true;
// Members aren't serializable. Use a proxy that can provide a Member
// to avoid writing the full Externalizable implementation.
@ -2032,6 +2033,7 @@ public class FieldMetaData
_isElementCollection = field._isElementCollection;
_access = field._access;
_orderDec = field._orderDec;
_useSchemaElement = field._useSchemaElement;
// embedded fields can't be versions
if (_owner.getEmbeddingMetaData() == null && _version == null)
@ -2430,4 +2432,18 @@ public class FieldMetaData
public void setDelayCapable(Boolean delayCapable) {
_delayCapable = delayCapable;
}
/**
* Whether to include schema name in generated files
*/
public boolean getUseSchemaElement() {
return _useSchemaElement;
}
/**
* Whether to include schema name in generated files
*/
public void setUseSchemaElement(boolean _useSchemaElement) {
this._useSchemaElement = _useSchemaElement;
}
}

View File

@ -282,7 +282,16 @@ public class AnnotationPersistenceMappingSerializer
if (index < 0)
ab.add("name", table);
else {
ab.add("schema", table.substring(0, index));
Map<String, ClassMetaData> classMetaData = getClassMetaData();
Object[] keySet = null;
if(classMetaData != null)
{
keySet = classMetaData.keySet().toArray();
}
if((keySet != null) && (keySet.length > 0) && classMetaData.get(keySet[0]).getUseSchemaElement())
{
ab.add("schema", table.substring(0, index));
}
ab.add("name", table.substring(index + 1));
}
}

View File

@ -241,7 +241,16 @@ public class XMLPersistenceMappingSerializer
if (index < 0)
addAttribute("name", table);
else {
addAttribute("schema", table.substring(0, index));
Map<String, ClassMetaData> classMetaData = getClassMetaData();
Object[] keySet = null;
if(classMetaData != null)
{
keySet = classMetaData.keySet().toArray();
}
if((keySet != null) && (keySet.length > 0) && classMetaData.get(keySet[0]).getUseSchemaElement())
{
addAttribute("schema", table.substring(0, index));
}
addAttribute("name", table.substring(index + 1));
}
}

View File

@ -0,0 +1,143 @@
/*
* 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.meta;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Scanner;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import junit.textui.TestRunner;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.meta.ReverseMappingTool;
import org.apache.openjpa.lib.util.Files;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
/**
* Tests the added useSchemaElement functionality of the
* ReverseMappingTool and CodeGenerator classes.
*
* @author Austin Dorenkamp (ajdorenk)
*/
public class TestUseSchemaElement extends /*TestCase*/ SingleEMFTestCase {
public void setUp() throws Exception {
super.setUp();
setSupportedDatabases(org.apache.openjpa.jdbc.sql.DerbyDictionary.class);
}
@Override
public String getPersistenceUnitName(){
return "rev-mapping-pu";
}
public void testGettersAndSetters() {
JDBCConfiguration conf = (JDBCConfiguration) ((OpenJPAEntityManagerFactory) emf).getConfiguration();
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Query q = em.createNativeQuery("CREATE TABLE USCHEMA.USCHANTBL (ID INTEGER PRIMARY KEY)");
try {
q.executeUpdate();
em.getTransaction().commit();
} catch (Throwable t) {
em.getTransaction().rollback();
System.out.println(t.toString());
}
try {
ReverseMappingTool.Flags flags = new ReverseMappingTool.Flags();
flags.metaDataLevel = "package";
flags.generateAnnotations = true;
flags.accessType = "property";
flags.nullableAsObject = true;
flags.useSchemaName = false;
flags.useSchemaElement = false;
flags.packageName = "";
flags.directory = Files.getFile("./target", null);
ReverseMappingTool.run(conf, new String[0], flags, null);
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} catch (Throwable t) {
t.printStackTrace();
}
/* Now that the tool has been run, we will test it by reading the generated files */
// This tests the removal of the schema annotation in the Uschantbl.java file
File uschantbl = new File("./target/Uschantbl.java");
Scanner inFile = new Scanner("");
String currentLine;
try {
inFile = new Scanner(uschantbl);
} catch (FileNotFoundException e) {
fail("Uschantbl.java not generated in ./target by ReverseMappingTool");
}
while(inFile.hasNextLine())
{
currentLine = inFile.nextLine();
if((currentLine.length()) > 0 && (currentLine.charAt(0) != '@'))
{
continue;
}
if(currentLine.contains("Table(schema="))
{
fail("Uschantbl.java still contains schema name");
}
}
inFile.close();
// Delete file to clean up workspace
assertTrue(uschantbl.delete());
// This tests the removal of the schema name from the orm.xml file
File orm = new File("./orm.xml");
try {
inFile = new Scanner(orm);
} catch (FileNotFoundException e) {
fail("Orm.xml not generated in root directory by ReverseMappingTool");
}
while(inFile.hasNextLine())
{
if(inFile.nextLine().contains("<table schema="))
{
fail("Orm.xml still contains schema name");
}
}
inFile.close();
// Delete file to clean up workspace. Also, test will break with
// org.apache.openjpa.util.UserException if orm.xml exists prior to running
// assertTrue(orm.delete());
}
public static void main(String[] args) {
TestRunner.run(TestUseSchemaElement.class);
}
}

View File

@ -470,4 +470,11 @@
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)" />
</properties>
</persistence-unit>
<persistence-unit name="rev-mapping-pu">
<properties>
<property name="openjpa.jdbc.Schemas" value="USCHEMA.USCHANTBL"/>
</properties>
</persistence-unit>
</persistence>

View File

@ -1545,4 +1545,11 @@ public class AnnotationPersistenceMetaDataSerializer
return fmd1.compareTo(fmd2);
}
}
/**
* Returns the stored ClassMetaData
*/
public Map<String, ClassMetaData> getClassMetaData() {
return _metas;
}
}

View File

@ -1496,4 +1496,11 @@ public class XMLPersistenceMetaDataSerializer
return fmd1.compareTo(fmd2);
}
}
/**
* Returns the stored ClassMetaData
*/
public Map<String, ClassMetaData> getClassMetaData() {
return _metas;
}
}

View File

@ -578,6 +578,16 @@ schemas with same-named tables.
</listitem>
<listitem>
<para>
<literal>-useSchemaElement/-se &lt;true/t | false/f&gt;</literal>: Set this
flag to <literal>false</literal> to exclude the schema name from the
<literal>@Table</literal> annotation in the generated class for each table.
If set to <literal>false</literal>, the schema name will also be removed from
the corresponding XML mapping files (orm.xml) that are generated by the tool.
The initialized value is true (in order to preserve backwards compatibility).
</para>
</listitem>
<listitem>
<para>
<literal>-useForeignKeyName/-fkn &lt;true/t | false/f&gt;</literal>: Set this
flag to <literal>true</literal> if you would like field names for relations to
be based on the database foreign key name. By default, relation field names are