OPENJPA-9

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@595508 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Patrick Linskey 2007-11-16 00:51:07 +00:00
parent 4a8d0b798b
commit 634bdc5c92
23 changed files with 687 additions and 100 deletions

View File

@ -168,14 +168,20 @@ public class ClassTableJDBCSeq
*/
public static void main(String[] args) throws Exception {
Options opts = new Options();
args = opts.setFromCmdLine(args);
JDBCConfiguration conf = new JDBCConfigurationImpl();
try {
if (!run(conf, args, opts))
System.out.println(_loc.get("clstable-seq-usage"));
} finally {
conf.close();
}
final String[] arguments = opts.setFromCmdLine(args);
boolean ret = Configurations.runAgainstAllAnchors(opts,
new Configurations.Runnable() {
public boolean run(Options opts) throws Exception {
JDBCConfiguration conf = new JDBCConfigurationImpl();
try {
return ClassTableJDBCSeq.run(conf, arguments, opts);
} finally {
conf.close();
}
}
});
if (!ret)
System.out.println(_loc.get("clstable-seq-usage"));
}
/**

View File

@ -315,14 +315,20 @@ public class NativeJDBCSeq
public static void main(String[] args)
throws Exception {
Options opts = new Options();
args = opts.setFromCmdLine(args);
JDBCConfiguration conf = new JDBCConfigurationImpl();
try {
if (!run(conf, args, opts))
System.out.println(_loc.get("native-seq-usage"));
} finally {
conf.close();
}
final String[] arguments = opts.setFromCmdLine(args);
boolean ret = Configurations.runAgainstAllAnchors(opts,
new Configurations.Runnable() {
public boolean run(Options opts) throws Exception {
JDBCConfiguration conf = new JDBCConfigurationImpl();
try {
return NativeJDBCSeq.run(conf, arguments, opts);
} finally {
conf.close();
}
}
});
if (!ret)
System.out.println(_loc.get("native-seq-usage"));
}
/**

View File

@ -614,14 +614,20 @@ public class TableJDBCSeq
public static void main(String[] args)
throws Exception {
Options opts = new Options();
args = opts.setFromCmdLine(args);
JDBCConfiguration conf = new JDBCConfigurationImpl();
try {
if (!run(conf, args, opts))
System.out.println(_loc.get("seq-usage"));
} finally {
conf.close();
}
final String[] arguments = opts.setFromCmdLine(args);
boolean ret = Configurations.runAgainstAllAnchors(opts,
new Configurations.Runnable() {
public boolean run(Options opts) throws Exception {
JDBCConfiguration conf = new JDBCConfigurationImpl();
try {
return TableJDBCSeq.run(conf, arguments, opts);
} finally {
conf.close();
}
}
});
if (!ret)
System.out.println(_loc.get("seq-usage"));
}
/**

View File

@ -120,14 +120,20 @@ public class ValueTableJDBCSeq
public static void main(String[] args)
throws Exception {
Options opts = new Options();
args = opts.setFromCmdLine(args);
JDBCConfiguration conf = new JDBCConfigurationImpl();
try {
if (!run(conf, args, opts))
System.out.println(_loc.get("clstable-seq-usage"));
} finally {
conf.close();
}
final String[] arguments = opts.setFromCmdLine(args);
boolean ret = Configurations.runAgainstAllAnchors(opts,
new Configurations.Runnable() {
public boolean run(Options opts) throws Exception {
JDBCConfiguration conf = new JDBCConfigurationImpl();
try {
return ValueTableJDBCSeq.run(conf, arguments, opts);
} finally {
conf.close();
}
}
});
if (!ret)
System.out.println(_loc.get("clstable-seq-usage"));
}
/**

View File

@ -912,17 +912,23 @@ public class MappingTool
* -f mypackage.orm -a export mypackage.jdo</code></li>
* </ul>
*/
public static void main(String[] args)
public static void main(String[] arguments)
throws IOException, SQLException {
Options opts = new Options();
args = opts.setFromCmdLine(args);
JDBCConfiguration conf = new JDBCConfigurationImpl();
try {
if (!run(conf, args, opts))
System.err.println(_loc.get("tool-usage"));
} finally {
conf.close();
}
final String[] args = opts.setFromCmdLine(arguments);
boolean ret = Configurations.runAgainstAllAnchors(opts,
new Configurations.Runnable() {
public boolean run(Options opts) throws IOException, SQLException {
JDBCConfiguration conf = new JDBCConfigurationImpl();
try {
return MappingTool.run(conf, args, opts);
} finally {
conf.close();
}
}
});
if (!ret)
System.err.println(_loc.get("tool-usage"));
}
/**

View File

@ -1819,14 +1819,20 @@ public class ReverseMappingTool
public static void main(String[] args)
throws IOException, SQLException {
Options opts = new Options();
args = opts.setFromCmdLine(args);
JDBCConfiguration conf = new JDBCConfigurationImpl();
try {
if (!run(conf, args, opts))
System.out.println(_loc.get("revtool-usage"));
} finally {
conf.close();
}
final String[] arguments = opts.setFromCmdLine(args);
boolean ret = Configurations.runAgainstAllAnchors(opts,
new Configurations.Runnable() {
public boolean run(Options opts) throws Exception {
JDBCConfiguration conf = new JDBCConfigurationImpl();
try {
return ReverseMappingTool.run(conf, arguments, opts);
} finally {
conf.close();
}
}
});
if (!ret)
System.out.println(_loc.get("revtool-usage"));
}
/**

View File

@ -1333,14 +1333,20 @@ public class SchemaTool {
public static void main(String[] args)
throws IOException, SQLException {
Options opts = new Options();
args = opts.setFromCmdLine(args);
JDBCConfiguration conf = new JDBCConfigurationImpl();
try {
if (!run(conf, args, opts))
System.out.println(_loc.get("tool-usage"));
} finally {
conf.close();
}
final String[] arguments = opts.setFromCmdLine(args);
boolean ret = Configurations.runAgainstAllAnchors(opts,
new Configurations.Runnable() {
public boolean run(Options opts) throws Exception {
JDBCConfiguration conf = new JDBCConfigurationImpl();
try {
return SchemaTool.run(conf, arguments, opts);
} finally {
conf.close();
}
}
});
if (!ret)
System.out.println(_loc.get("tool-usage"));
}
/**

View File

@ -449,14 +449,20 @@ public class TableSchemaFactory
public static void main(String[] args)
throws IOException, SQLException {
Options opts = new Options();
args = opts.setFromCmdLine(args);
JDBCConfiguration conf = new JDBCConfigurationImpl();
try {
if (!run(conf, args, opts))
System.out.println(_loc.get("sch-usage"));
} finally {
conf.close();
}
final String[] arguments = opts.setFromCmdLine(args);
boolean ret = Configurations.runAgainstAllAnchors(opts,
new Configurations.Runnable() {
public boolean run(Options opts) throws Exception {
JDBCConfiguration conf = new JDBCConfigurationImpl();
try {
return TableSchemaFactory.run(conf, arguments, opts);
} finally {
conf.close();
}
}
});
if (!ret)
System.out.println(_loc.get("sch-usage"));
}
/**

View File

@ -75,7 +75,7 @@ public class ApplicationIdTool {
private static final String TOKENIZER_CUSTOM = "Tokenizer";
private static final String TOKENIZER_STD = "StringTokenizer";
private static Localizer _loc = Localizer.forPackage
private static final Localizer _loc = Localizer.forPackage
(ApplicationIdTool.class);
private final Log _log;
@ -1282,14 +1282,21 @@ public class ApplicationIdTool {
public static void main(String[] args)
throws IOException, ClassNotFoundException {
Options opts = new Options();
args = opts.setFromCmdLine(args);
OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
try {
if (!run(conf, args, opts))
System.err.println(_loc.get("appid-usage"));
} finally {
conf.close();
}
final String[] arguments = opts.setFromCmdLine(args);
boolean ret = Configurations.runAgainstAllAnchors(opts,
new Configurations.Runnable() {
public boolean run(Options opts)
throws ClassNotFoundException, IOException {
OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
try {
return ApplicationIdTool.run(conf, arguments, opts);
} finally {
conf.close();
}
}
});
if (!ret)
System.err.println(_loc.get("appid-usage"));
}
/**

View File

@ -4254,17 +4254,29 @@ public class PCEnhancer {
* not be enhanced. Thus, it is safe to invoke the enhancer on classes
* that are already enhanced.
*/
public static void main(String[] args)
throws IOException {
public static void main(String[] args) {
Options opts = new Options();
args = opts.setFromCmdLine(args);
OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
try {
if (!run(conf, args, opts))
System.err.println(_loc.get("enhance-usage"));
} finally {
conf.close();
}
if (!run(args, opts))
System.err.println(_loc.get("enhance-usage"));
}
/**
* Run the tool. Returns false if invalid options given. Runs against all
* the persistence units defined in the resource to parse.
*/
public static boolean run(final String[] args, Options opts) {
return Configurations.runAgainstAllAnchors(opts,
new Configurations.Runnable() {
public boolean run(Options opts) throws IOException {
OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
try {
return PCEnhancer.run(conf, args, opts);
} finally {
conf.close();
}
}
});
}
/**
@ -4287,8 +4299,12 @@ public class PCEnhancer {
("enforcePropertyRestrictions", "epr",
flags.enforcePropertyRestrictions);
// for unit testing
BytecodeWriter writer = (BytecodeWriter) opts.get(
PCEnhancer.class.getName() + "#bytecodeWriter");
Configurations.populateConfiguration(conf, opts);
return run(conf, args, flags, null, null, null);
return run(conf, args, flags, null, writer, null);
}
/**
@ -4312,7 +4328,7 @@ public class PCEnhancer {
Log log = conf.getLog(OpenJPAConfiguration.LOG_TOOL);
Collection classes;
if (args.length == 0) {
if (args == null || args.length == 0) {
log.info(_loc.get("running-all-classes"));
classes = repos.getPersistentTypeNames(true, loader);
if (classes == null) {
@ -4327,7 +4343,7 @@ public class PCEnhancer {
for (int i = 0; i < args.length; i++)
classes.addAll(Arrays.asList(cap.parseTypes(args[i])));
}
Project project = new Project();
BCClass bc;
PCEnhancer enhancer;

View File

@ -250,14 +250,20 @@ public class MetaDataTool
public static void main(String[] args)
throws IOException {
Options opts = new Options();
args = opts.setFromCmdLine(args);
OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
try {
if (!run(conf, args, opts))
System.err.println(_loc.get("tool-usage"));
} finally {
conf.close();
}
final String[] arguments = opts.setFromCmdLine(args);
boolean ret = Configurations.runAgainstAllAnchors(opts,
new Configurations.Runnable() {
public boolean run(Options opts) throws Exception {
OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
try {
return MetaDataTool.run(conf, arguments, opts);
} finally {
conf.close();
}
}
});
if (!ret)
System.err.println(_loc.get("tool-usage"));
}
/**

View File

@ -19,6 +19,8 @@
package org.apache.openjpa.lib.conf;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
* Abstract no-op product derivation for easy extension.
@ -58,6 +60,18 @@ public abstract class AbstractProductDerivation
return null;
}
public String getDefaultResourceLocation() {
return null;
}
public List getAnchorsInFile(File file) throws Exception {
return null;
}
public List getAnchorsInResource(String resource) throws Exception {
return null;
}
public boolean beforeConfigurationConstruct(ConfigurationProvider cp) {
return false;
}

View File

@ -21,14 +21,15 @@ package org.apache.openjpa.lib.conf;
import java.io.File;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.TreeSet;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
@ -43,7 +44,6 @@ import org.apache.openjpa.lib.util.ParseException;
import org.apache.openjpa.lib.util.StringDistance;
import org.apache.openjpa.lib.util.concurrent.ConcurrentHashMap;
import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
import serp.util.Strings;
/**
@ -57,7 +57,7 @@ public class Configurations {
private static final Localizer _loc = Localizer.forPackage
(Configurations.class);
private static ConcurrentReferenceHashMap _loaders = new
private static final ConcurrentReferenceHashMap _loaders = new
ConcurrentReferenceHashMap(ConcurrentReferenceHashMap.WEAK,
ConcurrentReferenceHashMap.HARD);
@ -277,6 +277,35 @@ public class Configurations {
return loader;
}
/**
* Return a List<String> of all the fully-qualified anchors specified in the
* properties location listed in <code>opts</code>. If no properties
* location is listed in <code>opts</code>, this returns whatever the
* product derivations can find in their default configurations.
* If the properties location specified in <code>opts</code> already
* contains an anchor spec, this returns that anchor. Note that in this
* fully-qualified-input case, the logic involving product derivations
* and resource parsing is short-circuited, so this method
* should not be used as a means to test that a particular anchor is
* defined in a given location by invoking with a fully-qualified anchor.
*
* This does not mutate <code>opts</code>.
*
* @since 1.1.0
*/
public static List getFullyQualifiedAnchorsInPropertiesLocation(
Options opts) {
String props = opts.getProperty("properties", "p", null);
if (props != null) {
int anchorPosition = props.indexOf("#");
if (anchorPosition > -1)
return Arrays.asList(new String[] { props });
}
return ProductDerivations.getFullyQualifiedAnchorsInPropertiesLocation(
props);
}
/**
* Set the given {@link Configuration} instance from the command line
* options provided. All property names of the given configuration are
@ -630,4 +659,43 @@ public class Configurations {
return props.remove(ProductDerivations.getConfigurationKey(partialKey,
props));
}
/**
* Runs <code>runnable</code> against all the anchors in the configuration
* pointed to by <code>opts</code>. Each invocation gets a fresh clone of
* <code>opts</code> with the <code>properties</code> option set
* appropriately.
*
* @since 1.1.0
*/
public static boolean runAgainstAllAnchors(Options opts,
Configurations.Runnable runnable) {
List anchors =
Configurations.getFullyQualifiedAnchorsInPropertiesLocation(opts);
// We use 'properties' below; get rid of 'p' to avoid conflicts. This
// relies on knowing what getFullyQualifiedAnchorsInPropertiesLocation
// looks for.
if (opts.containsKey("p"))
opts.remove("p");
boolean ret = true;
for (Iterator iter = anchors.iterator(); iter.hasNext(); ) {
Options clonedOptions = (Options) opts.clone();
clonedOptions.setProperty("properties", iter.next().toString());
try {
ret &= runnable.run(clonedOptions);
} catch (Exception e) {
if (!(e instanceof RuntimeException))
throw new RuntimeException(e);
else
throw (RuntimeException) e;
}
}
return ret;
}
public interface Runnable {
public boolean run(Options opts) throws Exception;
}
}

View File

@ -19,6 +19,8 @@
package org.apache.openjpa.lib.conf;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
* Hooks for deriving products with additional functionality.
@ -90,6 +92,39 @@ public interface ProductDerivation {
*/
public ConfigurationProvider load(File file, String anchor)
throws Exception;
/**
* Return a string identifying the default resource location for this
* product derivation, if one exists. If there is no default location,
* returns <code>null</code>.
*
* @since 1.1.0
*/
public String getDefaultResourceLocation();
/**
* Return a List<String> of all the anchors defined in <code>file</code>.
* The returned names are not fully-qualified, so must be used in
* conjunction with <code>file</code> in calls
* to {@link #load(java.io.File, String)}.
*
* Returns <code>null</code> or an empty list if no anchors could be found.
*
* @since 1.1.0
*/
public List getAnchorsInFile(File file) throws IOException, Exception;
/**
* Return a List<String> of all the anchors defined in
* <code>resource</code>. The returned names are not
* fully-qualified, so must be used in conjunction with
* <code>resource</code> in calls to {@link #load(java.io.File, String)}.
*
* Returns <code>null</code> or an empty list if no anchors could be found.
*
* @since 1.1.0
*/
public List getAnchorsInResource(String resource) throws Exception;
/**
* Provides the instance with a callback to mutate the initial properties

View File

@ -22,8 +22,10 @@ import java.io.File;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
@ -352,6 +354,66 @@ public class ProductDerivations {
ProductDerivations.class.getName(), resource);
}
/**
* Return a List<String> of all the fully-qualified anchors specified in
* <code>propertiesLocation</code>. The return values must be used in
* conjunction with <code>propertiesLocation</code>. If there are no
* product derivations or if no product derivations could find anchors,
* this returns an empty list.
*
* @since 1.1.0
*/
public static List getFullyQualifiedAnchorsInPropertiesLocation(
final String propertiesLocation) {
List fqAnchors = new ArrayList();
StringBuffer errs = null;
for (int i = _derivations.length - 1; i >= 0; i--) {
try {
if (propertiesLocation == null) {
String loc = _derivations[i].getDefaultResourceLocation();
addAll(fqAnchors, loc,
_derivations[i].getAnchorsInResource(loc));
continue;
}
File f = new File(propertiesLocation);
if (((Boolean) J2DoPrivHelper.isFileAction(f).run())
.booleanValue()) {
addAll(fqAnchors, propertiesLocation,
_derivations[i].getAnchorsInFile(f));
} else {
f = new File("META-INF" + File.separatorChar
+ propertiesLocation);
if (((Boolean) J2DoPrivHelper.isFileAction(f).run())
.booleanValue()) {
addAll(fqAnchors, propertiesLocation,
_derivations[i].getAnchorsInFile(f));
} else {
addAll(fqAnchors, propertiesLocation,
_derivations[i].getAnchorsInResource(
propertiesLocation));
}
}
} catch (Throwable t) {
errs = (errs == null) ? new StringBuffer() : errs.append("\n");
errs.append(_derivations[i].getClass().getName() + ":" + t);
}
}
reportErrors(errs, propertiesLocation);
return fqAnchors;
}
private static void addAll(Collection collection, String base,
Collection newMembers) {
if (newMembers == null || collection == null)
return;
for (Iterator iter = newMembers.iterator(); iter.hasNext(); ) {
String fqLoc = base + "#" + iter.next();
if (!collection.contains(fqLoc))
collection.add(fqLoc);
}
}
/**
* Compare {@link ProductDerivation}s.
*/

View File

@ -0,0 +1,151 @@
/*
* 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.enhance;
import java.io.IOException;
import java.security.AccessController;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.util.BytecodeWriter;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Options;
import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.persistence.test.PersistenceTestCase;
import serp.bytecode.BCClass;
import serp.bytecode.Project;
public class TestEnhancementWithMultiplePUs
extends PersistenceTestCase {
public void testExplicitEnhancementWithClassNotInFirstPU()
throws ClassNotFoundException {
OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
Configurations.populateConfiguration(conf, new Options());
MetaDataRepository repos = conf.getMetaDataRepositoryInstance();
ClassLoader loader = (ClassLoader) AccessController
.doPrivileged(J2DoPrivHelper.newTemporaryClassLoaderAction(
getClass().getClassLoader()));
Project project = new Project();
String className =
"org.apache.openjpa.enhance.UnenhancedBootstrapInstance";
BCClass bc = assertNotPC(loader, project, className);
PCEnhancer enhancer = new PCEnhancer(conf, bc, repos, loader);
assertEquals(PCEnhancer.ENHANCE_PC, enhancer.run());
assertTrue(Arrays.asList(bc.getInterfaceNames()).contains(
PersistenceCapable.class.getName()));
}
private BCClass assertNotPC(ClassLoader loader, Project project,
String className) {
BCClass bc = project.loadClass(className, loader);
assertFalse(className + " must not be enhanced already; it was.",
Arrays.asList(bc.getInterfaceNames()).contains(
PersistenceCapable.class.getName()));
return bc;
}
public void testEnhancementOfSecondPUWithClassNotInFirstPU()
throws IOException {
OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
Options opts = new Options();
opts.setProperty("p",
"META-INF/persistence.xml#second-persistence-unit");
Configurations.populateConfiguration(conf, opts);
MetaDataRepository repos = conf.getMetaDataRepositoryInstance();
ClassLoader loader = (ClassLoader) AccessController
.doPrivileged(J2DoPrivHelper.newTemporaryClassLoaderAction(
getClass().getClassLoader()));
Project project = new Project();
// make sure that the class is not already enhanced for some reason
String className =
"org.apache.openjpa.enhance.UnenhancedBootstrapInstance";
BCClass bc = assertNotPC(loader, project, className);
// build up a writer that just stores to a list so that we don't
// mutate the disk.
final List<String> written = new ArrayList<String>();
BytecodeWriter writer = new BytecodeWriter() {
public void write(BCClass type) throws IOException {
assertTrue(Arrays.asList(type.getInterfaceNames()).contains(
PersistenceCapable.class.getName()));
written.add(type.getName());
}
};
PCEnhancer.run(conf, null, new PCEnhancer.Flags(), repos, writer,
loader);
// ensure that we don't attempt to process classes listed in other PUs
assertEquals(1, written.size());
// ensure that we do process the classes listed in the PU
assertTrue(written.contains(className));
}
public void testEnhancementOfAllPUsWithinAResource()
throws IOException {
OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
Options opts = new Options();
opts.setProperty("p", "META-INF/persistence.xml");
Configurations.populateConfiguration(conf, opts);
MetaDataRepository repos = conf.getMetaDataRepositoryInstance();
ClassLoader loader = (ClassLoader) AccessController
.doPrivileged(J2DoPrivHelper.newTemporaryClassLoaderAction(
getClass().getClassLoader()));
Project project = new Project();
// make sure that the classes is not already enhanced for some reason
assertNotPC(loader, project,
"org.apache.openjpa.enhance.UnenhancedBootstrapInstance");
assertNotPC(loader, project,
"org.apache.openjpa.enhance.UnenhancedBootstrapInstance2");
// build up a writer that just stores to a list so that we don't
// mutate the disk.
final List<String> written = new ArrayList<String>();
BytecodeWriter writer = new BytecodeWriter() {
public void write(BCClass type) throws IOException {
assertTrue(Arrays.asList(type.getInterfaceNames()).contains(
PersistenceCapable.class.getName()));
written.add(type.getName());
}
};
opts = new Options();
opts.put(PCEnhancer.class.getName() + "#bytecodeWriter", writer);
PCEnhancer.run(null, opts);
// ensure that we do process the classes listed in the PUs
assertTrue(written.contains(
"org.apache.openjpa.enhance.UnenhancedBootstrapInstance"));
assertTrue(written.contains(
"org.apache.openjpa.enhance.UnenhancedBootstrapInstance2"));
}
}

View File

@ -0,0 +1,28 @@
/*
* 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.enhance;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class UnenhancedBootstrapInstance {
@Id
private int id;
}

View File

@ -0,0 +1,28 @@
/*
* 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.enhance;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class UnenhancedBootstrapInstance2 {
@Id
private int id;
}

View File

@ -0,0 +1,63 @@
/*
* 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.lib.conf;
import java.util.List;
import junit.framework.TestCase;
import org.apache.openjpa.lib.util.Options;
public class TestAnchorParsing extends TestCase {
public void testFQAnchor() {
String fqLoc = "META-INF/persistence.xml#test";
Options opts = new Options();
opts.setProperty("p", fqLoc);
List locs =
Configurations.getFullyQualifiedAnchorsInPropertiesLocation(opts);
assertNotNull(locs);
assertEquals(1, locs.size());
assertEquals(fqLoc, locs.get(0));
}
public void testNoResource() {
allHelper(null);
}
public void testNoAnchor() {
allHelper("META-INF/persistence.xml");
}
private void allHelper(String resource) {
Options opts = new Options();
if (resource != null)
opts.setProperty("p", resource);
List locs =
Configurations.getFullyQualifiedAnchorsInPropertiesLocation(opts);
assertNotNull(locs);
// approximate so that if someone adds more units, this doesn't break
assertTrue(locs.size() >= 4);
assertTrue(locs.contains("META-INF/persistence.xml#test"));
assertTrue(locs.contains(
"META-INF/persistence.xml#second-persistence-unit"));
assertTrue(locs.contains(
"META-INF/persistence.xml#third-persistence-unit"));
assertTrue(locs.contains("META-INF/persistence.xml#invalid"));
}
}

View File

@ -52,10 +52,24 @@ public abstract class PersistenceTestCase
* this list to tell the test framework to delete all table contents
* before running the tests.
*
* @param props list of persistent types used in testing and/or
* @param props list of persistent types used in testing and/or
* configuration values in the form key,value,key,value...
*/
protected OpenJPAEntityManagerFactorySPI createEMF(Object... props) {
return createNamedEMF("test", props);
}
/**
* Create an entity manager factory for persistence unit <code>pu</code>.
* Put {@link #CLEAR_TABLES} in
* this list to tell the test framework to delete all table contents
* before running the tests.
*
* @param props list of persistent types used in testing and/or
* configuration values in the form key,value,key,value...
*/
protected OpenJPAEntityManagerFactorySPI createNamedEMF(String pu,
Object... props) {
Map map = new HashMap(System.getProperties());
List<Class> types = new ArrayList<Class>();
boolean prop = false;
@ -85,7 +99,7 @@ public abstract class PersistenceTestCase
}
return (OpenJPAEntityManagerFactorySPI) Persistence.
createEntityManagerFactory("test", map);
createEntityManagerFactory(pu, map);
}
public void tearDown() throws Exception {

View File

@ -54,7 +54,15 @@
value="buildSchema(ForeignKeys=true)"/>
</properties>
</persistence-unit>
<persistence-unit name="second-persistence-unit">
<class>org.apache.openjpa.enhance.UnenhancedBootstrapInstance</class>
</persistence-unit>
<persistence-unit name="third-persistence-unit">
<class>org.apache.openjpa.enhance.UnenhancedBootstrapInstance2</class>
</persistence-unit>
<persistence-unit name="invalid">
<properties>
<property name="openjpa.ConnectionDriverName"

View File

@ -199,6 +199,33 @@ public class PersistenceProductDerivation
parser.getResults(), anchor, null), null);
}
@Override
public String getDefaultResourceLocation() {
return RSRC_DEFAULT;
}
@Override
public List getAnchorsInFile(File file) throws IOException {
ConfigurationParser parser = new ConfigurationParser(null);
parser.parse(file);
return getUnitNames(parser);
}
private List<String> getUnitNames(ConfigurationParser parser) {
List<PersistenceUnitInfoImpl> units = parser.getResults();
List<String> names = new ArrayList<String>();
for (PersistenceUnitInfoImpl unit : units)
names.add(unit.getPersistenceUnitName());
return names;
}
@Override
public List getAnchorsInResource(String resource) throws Exception {
ConfigurationParser parser = new ConfigurationParser(null);
parser.parse(resource);
return getUnitNames(parser);
}
@Override
public ConfigurationProvider loadGlobals(ClassLoader loader)
throws IOException {

View File

@ -167,6 +167,18 @@ META-INF/my-persistence.xml</filename>, you can use:
</para>
<programlisting>
&lt;tool&gt; -p my-persistence.xml
</programlisting>
<para>
If you want to run a tool against just one particular persistence unit in
a configuration file, you can do so by specifying an anchor along with the
resource. If you do not specify an anchor, the tools will run against all
the persistence units defined within the specified resource, or the default
resource if none is specified. If the persistence unit is defined within
the default resource location, then you can just specify the raw anchor itself:
</para>
<programlisting>
&lt;tool&gt; -p my-persistence.xml#sales-persistence-unit
&lt;tool&gt; -p #invoice-persistence-unit
</programlisting>
</listitem>
<listitem>