Skip to content

Commit

Permalink
Update cannonical model for persistence 3.2
Browse files Browse the repository at this point in the history
Signed-off-by: Lukas Jungmann <lukas.jungmann@oracle.com>
  • Loading branch information
lukasj committed Mar 14, 2024
1 parent c5aed35 commit d5e3966
Show file tree
Hide file tree
Showing 8 changed files with 518 additions and 195 deletions.

Large diffs are not rendered by default.

Expand Up @@ -15,6 +15,23 @@
// - 531305: Canonical model generator fails to run on JDK9
package org.eclipse.persistence.jpa.test.modelgen;

import jakarta.annotation.Generated;
import jakarta.persistence.Entity;
import org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor;
import org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProperties;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
Expand All @@ -32,24 +49,6 @@
import java.util.Collections;
import java.util.List;

import jakarta.annotation.Generated;
import jakarta.persistence.Entity;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;

import org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor;
import org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProperties;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

public class TestProcessor {

public TestProcessor() {}
Expand All @@ -58,8 +57,11 @@ public TestProcessor() {}
public static void prepare() throws IOException {
File testRoot = new File(System.getProperty("run.dir"));
if (testRoot.exists() && testRoot.isDirectory()) {
for (File testDir: testRoot.listFiles()) {
delete(testDir);
File[] files = testRoot.listFiles();
if (files != null) {
for (File testDir : files) {
delete(testDir);
}
}
}
}
Expand Down Expand Up @@ -88,6 +90,24 @@ public void testTypeUse() throws Exception {
testTypeUse("testTypeUse3031", PXML30, OXML31);
}

@Test
public void testAnnotationProcessing() throws Exception {
String output = testEntity("org.foo.MyEnt", ENTITY, PXML32, OXML32);
Assert.assertFalse(output.contains("import org.foo"));
Assert.assertTrue(output.contains("public static volatile EntityType<MyEnt> class_;"));

Assert.assertTrue(output.contains("public static final String QUERY_FIND_ALL = \"findAll\";"));
Assert.assertTrue(output.contains("public static final String QUERY_NATIVE_DELETE_ALL = \"native.deleteAll\";"));
Assert.assertTrue(output.contains("public static final String GRAPH_MY_ENT = \"MyEnt\";"));
Assert.assertTrue(output.contains("public static final String MAPPING_M_CUSTOM_RESULT = \"m.customResult\";"));

Assert.assertTrue(output.contains("public static volatile TypedQueryReference<ResultClassType> _findById_;"));

Assert.assertTrue(output.contains("public static volatile EntityGraph<MyEnt> _MyEnt;"));

Assert.assertTrue(output.contains("public static final String CUSTOM_ATTRIBUTE_ = \"customAttribute\";"));
}

@Test
public void testProcessorLoggingOffFromCmdLine() throws Exception {
verifyLogging("testProcessorLoggingOffFromCmdLine", PXML30, false,
Expand Down Expand Up @@ -197,6 +217,22 @@ private void testGenerate(String name, String pxml, String oxml) throws Exceptio
Assert.assertTrue("Compilation failed", result.success);
}

private String testEntity(String name, String template, String pxml, String oxml) throws Exception {
TestFO entity = new TestFO(name,
template.replace("$PKG", name.substring(0, name.lastIndexOf('.')))
.replace("$NAME", name.substring(name.lastIndexOf('.') + 1)));
Result result = runProject(name.replace('.', '_'),
getJavacOptions("-A" + CanonicalModelProperties.CANONICAL_MODEL_GENERATE_GENERATED + "=false",
"-Aeclipselink.logging.level.processor=OFF"),
Arrays.asList(entity), pxml, oxml);

File outputFile = new File(result.srcOut, name.replace('.', '/') + "_.java");
Assert.assertTrue("Model file not generated", outputFile.exists());
Assert.assertTrue(Files.lines(outputFile.toPath()).noneMatch(s -> s.contains("Generated")));
Assert.assertTrue("Compilation failed", result.success);
return Files.readString(outputFile.toPath());
}

public void testTypeUse(String name, String pxml, String oxml) throws Exception {
TestFO entity = new TestFO("org.Ent",
"package org; @jakarta.persistence.Entity public class Ent { @org.ann.NotNull private byte[] bytes;}");
Expand Down Expand Up @@ -354,6 +390,20 @@ private static class Result {
</persistence-unit>
</persistence>""";

private static final String PXML32 = """
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence
https://jakarta.ee/xml/ns/persistence/persistence_3_2.xsd"
version="3.2">
<persistence-unit name="sample-pu" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
</properties>
</persistence-unit>
</persistence>""";

private static final String OXML30 = """
<entity-mappings xmlns="https://jakarta.ee/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Expand All @@ -366,6 +416,12 @@ private static class Result {
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence/orm https://jakarta.ee/xml/ns/persistence/orm/orm_3_1.xsd"
version="3.1"></entity-mappings>""";

private static final String OXML32 = """
<entity-mappings xmlns="https://jakarta.ee/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence/orm https://jakarta.ee/xml/ns/persistence/orm/orm_3_2.xsd"
version="3.2"></entity-mappings>""";

private static final String PXML_LOG_BEG =
"""
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
Expand All @@ -389,6 +445,34 @@ private static class Result {
</persistence-unit>
</persistence>""";

private static final String ENTITY =
"""
package $PKG;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.NamedEntityGraph;
import jakarta.persistence.NamedNativeQuery;
import jakarta.persistence.NamedQuery;
import jakarta.persistence.SqlResultSetMapping;
@Entity
@NamedQuery(name = "findAll", query="select xy from $NAME xy")
@NamedQuery(name = "findById", query="select xy from $NAME xy WHERE xy.id = :id", resultClass = ResultClassType.class)
@NamedNativeQuery(name = "native.deleteAll", query = "DELETE FROM $NAME")
@NamedNativeQuery(name = "native.deleteById", query = "DELETE FROM $NAME WHERE id = ?1", resultClass = ResultClassType.class)
@NamedEntityGraph
@SqlResultSetMapping(name = "m.customResult")
public class $NAME {
@Id
public int id;
public int customAttribute;
public $NAME() {}
public int getCustomAttribute() { return customAttribute; }
public int setCustomAttribute(int customAttribute) { this.customAttribute = customAttribute; }
interface A {}
};
class ResultClassType {}
""";

/**
* Simple property holding class.
*/
Expand Down Expand Up @@ -428,7 +512,7 @@ private static String buildPU(final String name, Property ... properties) {
}

private static void delete(File dir) throws IOException {
Files.walkFileTree(dir.toPath(), new SimpleFileVisitor<Path>() {
Files.walkFileTree(dir.toPath(), new SimpleFileVisitor<>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
Expand Down
Expand Up @@ -124,6 +124,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import jakarta.persistence.SharedCacheMode;
import jakarta.persistence.spi.PersistenceUnitInfo;
Expand All @@ -135,6 +136,7 @@
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.MetadataAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ClassAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ConverterAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EmbeddableAccessor;
Expand All @@ -148,6 +150,7 @@
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataClass;
import org.eclipse.persistence.internal.jpa.metadata.converters.AbstractConverterMetadata;
import org.eclipse.persistence.internal.jpa.metadata.converters.StructConverterMetadata;
import org.eclipse.persistence.internal.jpa.metadata.graphs.NamedEntityGraphMetadata;
import org.eclipse.persistence.internal.jpa.metadata.listeners.EntityListenerMetadata;
import org.eclipse.persistence.internal.jpa.metadata.partitioning.AbstractPartitioningMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.ComplexTypeMetadata;
Expand Down Expand Up @@ -284,6 +287,9 @@ public class MetadataProject {
// Query metadata.
private Map<String, NamedQueryMetadata> m_queries;

// Entity Graph metadata.
private Map<String, NamedEntityGraphMetadata> m_entityGraphs;

// SQL result set mapping
private Map<String, SQLResultSetMappingMetadata> m_sqlResultSetMappings;

Expand Down Expand Up @@ -352,6 +358,7 @@ public MetadataProject(PersistenceUnitInfo puInfo, AbstractSession session, bool
m_defaultListeners = new LinkedHashSet<>();

m_queries = new HashMap<>();
m_entityGraphs = new HashMap<>();
m_sqlResultSetMappings = new HashMap<>();
m_allAccessors = new HashMap<>();
m_entityAccessors = new HashMap<>();
Expand Down Expand Up @@ -657,6 +664,13 @@ public void addMetamodelMappedSuperclass(MappedSuperclassAccessor accessor, Meta
}
}

/**
* INTERNAL: Add the Entity Graph by name.
*/
public void addNamedEntityGraph(String name, NamedEntityGraphMetadata entityGraphMetadata) {
m_entityGraphs.put(name, entityGraphMetadata);
}

/**
* INTERNAL:
* Add the partitioning policy by name.
Expand Down Expand Up @@ -1012,13 +1026,13 @@ public ConverterAccessor getAutoApplyConverter(MetadataClass cls) {
ca = m_autoApplyConvertAccessors.get(wrapperType);
}
}

return ca;
}

private String resolvePrimitiveWrapper(MetadataClass cls) {
String wrapperType = null;

if (cls.isPrimitive() && !cls.isArray() && !m_autoApplyConvertAccessors.isEmpty()) {
// Look for Converters for the Wrapper equivalent of the primitive
switch (cls.getTypeName()) {
Expand Down Expand Up @@ -1227,6 +1241,36 @@ public Collection<MappedSuperclassAccessor> getMetamodelMappedSuperclasses() {
return m_metamodelMappedSuperclasses.values();
}

/**
* INTERNAL: Return Collection of {@code NamedEntityGraph}s defined in given {@code accessor}.
*/
public Set<NamedEntityGraphMetadata> getNamedEntityGraphs(MetadataAccessor accessor) {
return m_entityGraphs.values()
.stream()
.filter(v -> v.getAccessibleObject() == accessor.getAccessibleObject())
.collect(Collectors.toSet());
}

/**
* INTERNAL: Return Collection of {@code NamedQueries} (all variants) defined in given {@code accessor}.
*/
public Set<NamedQueryMetadata> getNamedQueries(MetadataAccessor accessor) {
return m_queries.values()
.stream()
.filter(v -> v.getAccessibleObject() == accessor.getAccessibleObject())
.collect(Collectors.toSet());
}

/**
* INTERNAL: Return Collection of {@code SQLResultSetMapping}s defined in given {@code accessor}.
*/
public Set<SQLResultSetMappingMetadata> getNamedSQLResultSetMappings(MetadataAccessor accessor) {
return m_sqlResultSetMappings.values()
.stream()
.filter(v -> v.getAccessibleObject() == accessor.getAccessibleObject())
.collect(Collectors.toSet());
}

/**
* INTERNAL:
* Return the named partitioning policy.
Expand Down Expand Up @@ -1341,7 +1385,7 @@ protected String getSharedCacheModeName() {

/**
* INTERNAL:
* Sets the SharedCacheMode value.
* Sets the SharedCacheMode value.
*/
public void setSharedCacheMode(SharedCacheMode m_sharedCacheMode) {
this.m_sharedCacheMode = m_sharedCacheMode;
Expand Down Expand Up @@ -1393,7 +1437,7 @@ public boolean hasAutoApplyConverter(MetadataClass cls) {
hasCA = m_autoApplyConvertAccessors.containsKey(wrapperType);
}
}

return hasCA;
}

Expand Down Expand Up @@ -2105,6 +2149,6 @@ public boolean hasVirtualClasses() {
}
return false;
}
}
}


Expand Up @@ -652,8 +652,13 @@ public void preProcessForCanonicalModel() {
}
}

processEntity();

// Process our parents metadata after processing our own.
super.preProcessForCanonicalModel();

// Process the entity graph metadata.
processEntityGraphs();
}

/**
Expand Down
Expand Up @@ -746,6 +746,33 @@ public void preProcess() {
super.preProcess();
}

@Override
public void preProcessForCanonicalModel() {

// Process the named query metadata.
processNamedQueries();

// Process the named native query metadata.
processNamedNativeQueries();

// Process the named stored procedure query metadata
processNamedStoredProcedureQueries();

// Process the named stored function query metadata
processNamedStoredFunctionQueries();

// Process the named PLSQL stored procedure query metadata
processNamedPLSQLStoredProcedureQueries();

// Process the named PLSQL stored function query metadata
processNamedPLSQLStoredFunctionQueries();

// Process the sql result set mapping metadata
processSqlResultSetMappings();

super.preProcessForCanonicalModel();
}

/**
* INTERNAL:
* Process the items of interest on a mapped superclass.
Expand Down
Expand Up @@ -244,6 +244,7 @@ public void process(EntityAccessor entityAccessor) {

// Finally, add the entity graph to the project.
getProject().addEntityGraph(entityGraph);
getProject().addNamedEntityGraph(entityGraphName, this);
}
}

Expand Down

0 comments on commit d5e3966

Please sign in to comment.