diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/ant/ApplicationIdToolTask.java b/openjpa-kernel/src/main/java/org/apache/openjpa/ant/ApplicationIdToolTask.java
index df19c3566..634f0d852 100755
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/ant/ApplicationIdToolTask.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/ant/ApplicationIdToolTask.java
@@ -110,5 +110,5 @@ public class ApplicationIdToolTask
: Files.getFile(dirName, getClassLoader());
ApplicationIdTool.run((OpenJPAConfiguration) getConfiguration(), files,
flags, getClassLoader ());
- }
+ }
}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ApplicationIdTool.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ApplicationIdTool.java
index 922b558bb..680991c04 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ApplicationIdTool.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ApplicationIdTool.java
@@ -57,12 +57,12 @@ import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.meta.MetaDataFactory;
import org.apache.openjpa.meta.MetaDataModes;
import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.util.GeneratedClasses;
import org.apache.openjpa.util.InvalidStateException;
import org.apache.openjpa.util.UserException;
-
-import serp.bytecode.BCClass;
-import serp.bytecode.BCClassLoader;
-import serp.bytecode.Project;
+import org.apache.xbean.asm9.ClassWriter;
+import org.apache.xbean.asm9.Opcodes;
+import org.apache.xbean.asm9.Type;
/**
* Generates a class appropriate for use as an application identity class.
@@ -116,8 +116,7 @@ public class ApplicationIdTool {
* Constructs a new tool instance capable of generating an
* object id class for meta
.
*/
- public ApplicationIdTool(OpenJPAConfiguration conf, Class type,
- ClassMetaData meta) {
+ public ApplicationIdTool(OpenJPAConfiguration conf, Class type, ClassMetaData meta) {
_log = conf.getLog(OpenJPAConfiguration.LOG_ENHANCE);
_type = type;
@@ -828,8 +827,8 @@ public class ApplicationIdTool {
append(name).closeParen().closeParen();
} else if (type == char[].class) {
// ((name == null && other.name == null)
- // || (name != null && String.valueOf (name).
- // equals (String.valueOf (other.name))))
+ // || (name != null && String.valueOf (name).
+ // equals (String.valueOf (other.name))))
code.append("(").openParen(false).append(name).
append(" == null && other.").append(name).
append(" == null").closeParen().endl();
@@ -843,7 +842,7 @@ public class ApplicationIdTool {
closeParen().append(")");
} else {
// ((name == null && other.name == null)
- // || (name != null && name.equals (other.name)))
+ // || (name != null && name.equals (other.name)))
code.append("(").openParen(false).append(name).
append(" == null && other.").append(name).
append(" == null").closeParen().endl();
@@ -1375,14 +1374,12 @@ public class ApplicationIdTool {
ApplicationIdTool tool;
Class cls;
ClassMetaData meta;
- BCClassLoader bc = AccessController
- .doPrivileged(J2DoPrivHelper.newBCClassLoaderAction(new Project()));
for (Object aClass : classes) {
cls = (Class) aClass;
log.info(_loc.get("appid-running", cls));
meta = repos.getMetaData(cls, null, false);
- setObjectIdType(meta, flags, bc);
+ setObjectIdType(meta, flags);
tool = new ApplicationIdTool(conf, cls, meta);
tool.setDirectory(flags.directory);
@@ -1396,15 +1393,13 @@ public class ApplicationIdTool {
else
log.info(_loc.get("appid-norun"));
}
- bc.getProject().clear();
return true;
}
/**
* Set the object id type of the given metadata.
*/
- private static void setObjectIdType(ClassMetaData meta, Flags flags,
- BCClassLoader bc)
+ private static void setObjectIdType(ClassMetaData meta, Flags flags)
throws ClassNotFoundException {
if (meta == null || (meta.getObjectIdType() != null
&& (!meta.isOpenJPAIdentity() || flags.name == null))
@@ -1413,18 +1408,19 @@ public class ApplicationIdTool {
Class desc = meta.getDescribedType();
Class cls = null;
- if (flags.name != null)
- cls = loadClass(desc, flags.name, bc);
- else if (flags.suffix != null)
- cls = loadClass(desc, desc.getName() + flags.suffix, bc);
+ if (flags.name != null) {
+ cls = loadClass(desc, flags.name);
+ }
+ else if (flags.suffix != null) {
+ cls = loadClass(desc, desc.getName() + flags.suffix);
+ }
meta.setObjectIdType(cls, false);
}
/**
* Load the given class name even if it does not exist.
*/
- private static Class loadClass(Class context, String name,
- BCClassLoader bc)
+ private static Class loadClass(Class context, String name)
throws ClassNotFoundException {
if (name.indexOf('.') == -1 && context.getName().indexOf('.') != -1)
name = ClassUtil.getPackageName(context) + "." + name;
@@ -1441,9 +1437,16 @@ public class ApplicationIdTool {
}
// create class
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ cw.visit(Opcodes.V11, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, name.replace(".", "/"),
+ null, Type.getInternalName(Object.class), null);
+
+ return GeneratedClasses.loadAsmClass(name, cw.toByteArray(), context, context.getClassLoader());
+/*X TODO DELETE
BCClass oid = bc.getProject().loadClass(name, null);
oid.addDefaultConstructor();
return Class.forName(name, false, bc);
+*/
}
/**
@@ -1479,11 +1482,11 @@ public class ApplicationIdTool {
* object id classes.
*/
public interface ObjectIdLoader
- {
- /**
+ {
+ /**
* Turn on the loading of all identity classes, even if they don't
* exist.
- */
- void setLoadObjectIds ();
- }
+ */
+ void setLoadObjectIds ();
+ }
}
diff --git a/openjpa-persistence-jdbc/src/main/ant/enhancer.xml b/openjpa-persistence-jdbc/src/main/ant/enhancer.xml
index 6168491c3..8fed7664c 100644
--- a/openjpa-persistence-jdbc/src/main/ant/enhancer.xml
+++ b/openjpa-persistence-jdbc/src/main/ant/enhancer.xml
@@ -87,6 +87,7 @@
+
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestEnhancementWithMultiplePUs.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestEnhancementWithMultiplePUs.java
index adb9fdb65..a6c63ac33 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestEnhancementWithMultiplePUs.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestEnhancementWithMultiplePUs.java
@@ -149,7 +149,8 @@ public class TestEnhancementWithMultiplePUs
// not attempt to enhance.
opts.setProperty("MetaDataRepository",
"org.apache.openjpa.enhance.RestrictedMetaDataRepository(excludedTypes=" +
- "org.apache.openjpa.persistence.jdbc.annotations.UnenhancedMixedAccess)");
+ "\"org.apache.openjpa.persistence.jdbc.annotations.UnenhancedMixedAccess," +
+ "org.apache.openjpa.idtool.RecordsPerYear\")");
opts.put(PCEnhancer.class.getName() + "#bytecodeWriter", writer);
PCEnhancer.run(null, opts);
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/idtool/RecordsPerYear.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/idtool/RecordsPerYear.java
new file mode 100644
index 000000000..0cbeb5c2c
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/idtool/RecordsPerYear.java
@@ -0,0 +1,59 @@
+/*
+ * 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.idtool;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+
+/**
+ * Entity for testing the {@link org.apache.openjpa.enhance.ApplicationIdTool}.
+ */
+@Entity
+public class RecordsPerYear {
+
+ @Id
+ private String user;
+
+ @Id
+ private int year;
+
+ private long counter;
+
+ public String getUser() {
+ return user;
+ }
+
+ public void setUser(String user) {
+ this.user = user;
+ }
+
+ public int getYear() {
+ return year;
+ }
+
+ public void setYear(int year) {
+ this.year = year;
+ }
+
+ public long getCounter() {
+ return counter;
+ }
+
+ public void setCounter(long counter) {
+ this.counter = counter;
+ }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/idtool/TestApplicationIdTool.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/idtool/TestApplicationIdTool.java
new file mode 100644
index 000000000..62af2914b
--- /dev/null
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/idtool/TestApplicationIdTool.java
@@ -0,0 +1,65 @@
+/*
+ * 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.idtool;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+
+import org.apache.openjpa.enhance.ApplicationIdTool;
+import org.apache.openjpa.persistence.jdbc.common.apps.AutoIncrementPC3;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test for the ApplicationIdTool from openjpa-kernel.
+ * We cannot test it over in the openjpa-kernel package as
+ * we'd not be able to also test JPA features.
+ */
+public class TestApplicationIdTool {
+
+ @Test
+ public void testApplicationIdTool_wIdClassAnnotation() throws Exception{
+ String entityJavaFile = "./src/test/java/" + AutoIncrementPC3.class.getName().replace(".", "/") + ".java";
+ final String outputDir = "./target/idtooltest/";
+ ApplicationIdTool.main(new String[]{"-s","Id", entityJavaFile, "-d", outputDir});
+
+ String idJavaFile = outputDir + AutoIncrementPC3.class.getName().replace(".", "/") + "Id.java";
+
+ assertTrue(new File(idJavaFile).exists());
+ }
+
+ @Test
+ public void testApplicationIdTool_freshClass() throws Exception{
+ String entityJavaFile = "./src/test/java/" + RecordsPerYear.class.getName().replace(".", "/") + ".java";
+ final String outputDir = "./target/idtooltest/";
+ ApplicationIdTool.main(new String[]{"-s","Id", entityJavaFile, "-d", outputDir});
+
+ String idJavaFile = outputDir + RecordsPerYear.class.getName().replace(".", "/") + "Id.java";
+
+ final File generatedIdFile = new File(idJavaFile);
+ assertTrue(generatedIdFile.exists());
+ assertContains(generatedIdFile, "public class RecordsPerYearId");
+ assertContains(generatedIdFile, "public RecordsPerYearId(String str)");
+ }
+
+ private void assertContains(File file, String find) throws IOException {
+ final byte[] bytes = Files.readAllBytes(file.toPath());
+ assertTrue(new String(bytes).contains(find));
+ }
+}
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC3.java
index 7de213c19..05751ecf8 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/AutoIncrementPC3.java
@@ -41,70 +41,71 @@ import jakarta.persistence.Table;
@Table(name="AUTOINCPC3")
public class AutoIncrementPC3
{
- @Id
- private long id = 0;
+ @Id
+ private long id = 0;
+
private Set setField = new HashSet ();
- @Column(name="strngfld", length=50)
- private String stringField = null;
+ @Column(name="strngfld", length=50)
+ private String stringField = null;
- @OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
- private AutoIncrementPC3 oneOne = null;
+ @OneToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
+ private AutoIncrementPC3 oneOne = null;
- public AutoIncrementPC3()
- {
- }
+ public AutoIncrementPC3()
+ {
+ }
- public AutoIncrementPC3(int id)
- {
- this.id = id;
- }
+ public AutoIncrementPC3(int id)
+ {
+ this.id = id;
+ }
- public long getId ()
- {
- return this.id;
- }
+ public long getId ()
+ {
+ return this.id;
+ }
- public void setId (long id)
- {
- this.id = id;
- }
+ public void setId (long id)
+ {
+ this.id = id;
+ }
- public Set getSetField ()
- {
- return this.setField;
- }
+ public Set getSetField ()
+ {
+ return this.setField;
+ }
- public void setSetField (Set setField)
- {
- this.setField = setField;
- }
+ public void setSetField (Set setField)
+ {
+ this.setField = setField;
+ }
- public String getStringField ()
- {
- return this.stringField;
- }
+ public String getStringField ()
+ {
+ return this.stringField;
+ }
- public void setStringField (String stringField)
- {
- this.stringField = stringField;
- }
+ public void setStringField (String stringField)
+ {
+ this.stringField = stringField;
+ }
- public AutoIncrementPC3 getOneOne ()
- {
- return this.oneOne;
- }
+ public AutoIncrementPC3 getOneOne ()
+ {
+ return this.oneOne;
+ }
- public void setOneOne (AutoIncrementPC3 oneOne)
- {
- this.oneOne = oneOne;
- }
+ public void setOneOne (AutoIncrementPC3 oneOne)
+ {
+ this.oneOne = oneOne;
+ }
}