Skip to content

Commit

Permalink
Fix detection of support for generation session beans from entity cla…
Browse files Browse the repository at this point in the history
…sses and support jakarta package names

Closes: #7066
  • Loading branch information
matthiasblaesing committed Feb 18, 2024
1 parent 6a9d501 commit 795f283
Show file tree
Hide file tree
Showing 13 changed files with 238 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ private static boolean isSessionBeanCodeGenerationAlowed(Project project) {
ClassPath classpath = ClassPath.getClassPath(project.getProjectDirectory(), ClassPath.COMPILE);
return !(classpath.findResource("jakarta/ejb/Stateless.class") == null //NOI18N
|| classpath.findResource("jakarta/ejb/Stateful.class") == null //NOI18N
|| classpath.findResource("jakarta/ejb/Singleton.class") == null //NOI18N
|| classpath.findResource("jakarta/ejb/Singleton.class") == null) //NOI18N
|| //NOI18N
!(classpath.findResource("javax/ejb/Stateless.class") == null //NOI18N
|| classpath.findResource("javax/ejb/Stateful.class") == null //NOI18N
|| classpath.findResource("javax/ejb/Singleton.class") == null)); //NOI18N
|| classpath.findResource("javax/ejb/Singleton.class") == null); //NOI18N
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,11 @@ public final class EjbFacadeWizardIterator implements WizardDescriptor.ProgressI
private static final String FACADE_REMOTE_SUFFIX = FACADE_SUFFIX + "Remote"; //NOI18N
private static final String FACADE_LOCAL_SUFFIX = FACADE_SUFFIX + "Local"; //NOI18N
private static final String EJB_LOCAL = "javax.ejb.Local"; //NOI18N
private static final String EJB_LOCAL_JAKARTA = "jakarta.ejb.Local"; //NOI18N
private static final String EJB_REMOTE = "javax.ejb.Remote"; //NOI18N
private static final String EJB_REMOTE_JAKARTA = "jakarta.ejb.Remote"; //NOI18N
protected static final String EJB_STATELESS = "javax.ejb.Stateless"; //NOI18N
protected static final String EJB_STATELESS_JAKARTA = "jakarta.ejb.Stateless"; //NOI18N

private int index;
private WizardDescriptor wizard;
Expand Down Expand Up @@ -232,6 +235,16 @@ Set<FileObject> generate(final Project project, final FileObject targetFolder, f
final String entitySimpleName = JavaIdentifiers.unqualify(entityFQN);
final String variableName = entitySimpleName.toLowerCase().charAt(0) + entitySimpleName.substring(1);

final boolean jakartaVariant;
final ClassPath targetClassPath = ClassPath.getClassPath(targetFolder, ClassPath.COMPILE);
if (targetClassPath != null) {
final FileObject javaxStatelessFo = targetClassPath.findResource(EJB_STATELESS.replace(".", "/") + ".class");
final FileObject jakartaStatelessFo = targetClassPath.findResource(EJB_STATELESS_JAKARTA.replace(".", "/") + ".class");
jakartaVariant = javaxStatelessFo == null || jakartaStatelessFo != null;
} else {
jakartaVariant = true;
}

//create the abstract facade class
Task<CompilationController> waiter = null;
final String afName = pkg.isEmpty() ? FACADE_ABSTRACT : pkg + "." + FACADE_ABSTRACT; //NOI18N
Expand All @@ -253,7 +266,7 @@ public void run(WorkingCopy workingCopy) throws Exception {
TypeElement classElement = (TypeElement)workingCopy.getTrees().getElement(classTreePath);

String genericsTypeName = "T"; //NOI18N
List<GenerationOptions> methodOptions = getAbstractFacadeMethodOptions(genericsTypeName, "entity"); //NOI18N
List<GenerationOptions> methodOptions = getAbstractFacadeMethodOptions(genericsTypeName, "entity", jakartaVariant); //NOI18N
List<Tree> members = new ArrayList<Tree>();
String entityClassVar = "entityClass"; //NOI18N
Tree classObjectTree = genUtils.createType("java.lang.Class<" + genericsTypeName + ">", classElement); //NOI18N
Expand Down Expand Up @@ -333,7 +346,7 @@ public void run(CompilationController cc) throws Exception {

// generate methods for the facade
EntityManagerGenerator generator = new EntityManagerGenerator(facade, entityFQN);
List<GenerationOptions> methodOptions = getMethodOptions(entityFQN, variableName);
List<GenerationOptions> methodOptions = getMethodOptions(entityFQN, variableName, jakartaVariant);
for (GenerationOptions each : methodOptions){
generator.generate(each, strategyClass);
}
Expand All @@ -342,12 +355,12 @@ public void run(CompilationController cc) throws Exception {
final String localInterfaceFQN = pkg + "." + getUniqueClassName(entitySimpleName + FACADE_LOCAL_SUFFIX, targetFolder);
final String remoteInterfaceFQN = pkg + "." + getUniqueClassName(entitySimpleName + FACADE_REMOTE_SUFFIX, targetFolder);

List<GenerationOptions> intfOptions = getAbstractFacadeMethodOptions(entityFQN, variableName);
List<GenerationOptions> intfOptions = getAbstractFacadeMethodOptions(entityFQN, variableName, jakartaVariant);
if (hasLocal) {
final SourceGroup[] groups = ProjectUtils.getSources(project).getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
String simpleName = JavaIdentifiers.unqualify(localInterfaceFQN);
if (!interfaceExists(groups, pkg, simpleName)) {
FileObject local = createInterface(simpleName, EJB_LOCAL, targetFolder);
FileObject local = createInterface(simpleName, jakartaVariant ? EJB_LOCAL_JAKARTA : EJB_LOCAL, targetFolder);
addMethodToInterface(intfOptions, local);
createdFiles.add(local);
}
Expand All @@ -357,7 +370,7 @@ public void run(CompilationController cc) throws Exception {
String simpleName = JavaIdentifiers.unqualify(remoteInterfaceFQN);
if (!interfaceExists(groups, pkg, simpleName)) {
FileObject remotePackage = SessionGenerator.createRemoteInterfacePackage(remoteProject, pkg, targetFolder);
FileObject remote = createInterface(simpleName, EJB_REMOTE, remotePackage);
FileObject remote = createInterface(simpleName, jakartaVariant ? EJB_REMOTE_JAKARTA : EJB_REMOTE, remotePackage);
addMethodToInterface(intfOptions, remote);
createdFiles.add(remote);
if (entityProject != null && !entityProject.getProjectDirectory().equals(remoteProject.getProjectDirectory())) {
Expand Down Expand Up @@ -434,7 +447,7 @@ public void run(WorkingCopy wc) throws Exception {
DeclaredType declaredType = wc.getTypes().getDeclaredType(abstactFacadeElement, entityElement.asType());
Tree extendsClause = maker.Type(declaredType);
ClassTree newClassTree = maker.Class(
maker.addModifiersAnnotation(classTree.getModifiers(), genUtils.createAnnotation(EJB_STATELESS)),
maker.addModifiersAnnotation(classTree.getModifiers(), genUtils.createAnnotation(jakartaVariant ? EJB_STATELESS_JAKARTA : EJB_STATELESS)),
classTree.getSimpleName(),
classTree.getTypeParameters(),
extendsClause,
Expand Down Expand Up @@ -476,24 +489,24 @@ public void run(WorkingCopy wc) throws Exception {
* @return the options representing the methods for a facade, i.e. create/edit/
* find/remove/findAll.
*/
private List<GenerationOptions> getMethodOptions(String entityFQN, String variableName){
private List<GenerationOptions> getMethodOptions(String entityFQN, String variableName, boolean jakartaVariant){

GenerationOptions getEMOptions = new GenerationOptions();
getEMOptions.setAnnotation("java.lang.Override"); //NOI18N
getEMOptions.setMethodName("getEntityManager"); //NOI18N
getEMOptions.setOperation(GenerationOptions.Operation.GET_EM);
getEMOptions.setReturnType("javax.persistence.EntityManager");//NOI18N
getEMOptions.setReturnType(jakartaVariant ? "jakarta.persistence.EntityManager" : "javax.persistence.EntityManager");//NOI18N
getEMOptions.setModifiers(EnumSet.of(Modifier.PROTECTED));

return Arrays.<GenerationOptions>asList(getEMOptions);
}

private List<GenerationOptions> getAbstractFacadeMethodOptions(String entityFQN, String variableName){
private List<GenerationOptions> getAbstractFacadeMethodOptions(String entityFQN, String variableName, boolean jakartaVariant){
//abstract methods

GenerationOptions getEMOptions = new GenerationOptions();
getEMOptions.setMethodName("getEntityManager"); //NOI18N
getEMOptions.setReturnType("javax.persistence.EntityManager");//NOI18N
getEMOptions.setReturnType(jakartaVariant ? "jakarta.persistence.EntityManager" : "javax.persistence.EntityManager");//NOI18N
getEMOptions.setModifiers(EnumSet.of(Modifier.PROTECTED, Modifier.ABSTRACT));

//implemented methods
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
import org.openide.util.NbBundle;
import org.openide.util.Utilities;

import static org.netbeans.modules.j2ee.ejbcore.ejb.wizard.jpa.dao.EjbFacadeWizardIterator.EJB_STATELESS;
import static org.netbeans.modules.j2ee.ejbcore.ejb.wizard.jpa.dao.EjbFacadeWizardIterator.EJB_STATELESS_JAKARTA;

public class EjbFacadeWizardPanel2 implements WizardDescriptor.Panel, ChangeListener {

/**
Expand Down Expand Up @@ -120,8 +123,11 @@ public boolean isValid() {
}
if (!statelessIfaceOnProjectCP()) {
wizardDescriptor.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE,
NbBundle.getMessage(EjbFacadeWizardPanel2.class, "ERR_SessionIfaceNotOnProjectClasspath", //NOI18N
EjbFacadeWizardIterator.EJB_STATELESS));
NbBundle.getMessage(
EjbFacadeWizardPanel2.class,
"ERR_SessionIfaceNotOnProjectClasspath", //NOI18N
EJB_STATELESS_JAKARTA + "/" + EJB_STATELESS_JAKARTA //NOI18N
));
return false;
}

Expand Down Expand Up @@ -231,13 +237,12 @@ public Project getEntityProject() {

private boolean statelessIfaceOnProjectCP() {
ClassPath cp = ClassPath.getClassPath(project.getProjectDirectory(), ClassPath.COMPILE);
ClassLoader cl = cp.getClassLoader(true);
try {
Class.forName(EjbFacadeWizardIterator.EJB_STATELESS, false, cl);
} catch (ClassNotFoundException cnfe) {
if(cp == null) {
return false;
}
return true;
FileObject javaxStatelessFo = cp.findResource(EJB_STATELESS.replace(".", "/") + ".class");
FileObject jakartaStatelessFo = cp.findResource(EJB_STATELESS_JAKARTA.replace(".", "/") + ".class");
return javaxStatelessFo != null || jakartaStatelessFo != null;
}

private static boolean isValidPackageName(String str) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import java.io.IOException;
import javax.lang.model.element.TypeElement;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.java.source.CompilationController;
import org.netbeans.api.java.source.ui.ScanDialog;
import org.netbeans.modules.j2ee.api.ejbjar.EjbJar;
Expand Down Expand Up @@ -49,7 +50,7 @@ public AbstractAddMethodStrategy(String name) {
this.name = name;
}

protected abstract MethodModel getPrototypeMethod();
protected abstract MethodModel getPrototypeMethod(boolean jakartaVariant);

/** Describes method type handled by this action. */
public abstract MethodType.Kind getPrototypeMethodKind();
Expand All @@ -69,7 +70,14 @@ public void addMethod(final FileObject fileObject, final String className) throw
if (className == null) {
return;
}
final MethodModel methodModel = getPrototypeMethod();

boolean jakartaVariant = true;
ClassPath cp = ClassPath.getClassPath(fileObject, ClassPath.COMPILE);
if (cp != null) {
jakartaVariant = cp.findResource("javax/ejb/Stateless.class") == null // NOI18N
|| cp.findResource("jakarta/ejb/Stateless.class") != null; // NOI18N
}
final MethodModel methodModel = getPrototypeMethod(jakartaVariant);
ScanDialog.runWhenScanFinished(new Runnable() {
@Override
public void run() {
Expand Down Expand Up @@ -106,18 +114,16 @@ protected static MethodsNode getMethodsNode() {
* Gets whether the type of given {@code TypeElement} is Entity bean.
* @param compilationController compilationController
* @param typeElement examined element
* @return {@code true} if the element is subtype of {@code javax.ejb.EntityBean}, {@code false} otherwise
* @return {@code true} if the element is subtype of {@code jakarta.ejb.EntityBean} or {@code javax.ejb.EntityBean}, {@code false} otherwise
*/
protected static boolean isEntity(CompilationController compilationController, TypeElement typeElement) {
Parameters.notNull("compilationController", compilationController);
Parameters.notNull("typeElement", typeElement);

TypeElement entity = compilationController.getElements().getTypeElement("javax.ejb.EntityBean");
if (entity != null) {
typeElement.getKind().getDeclaringClass().isAssignableFrom(entity.getKind().getDeclaringClass());
return (compilationController.getTypes().isSubtype(typeElement.asType(), entity.asType()));
}
return false;
TypeElement entityJakarta = compilationController.getElements().getTypeElement("jakarta.ejb.EntityBean");
return (entity != null && (compilationController.getTypes().isSubtype(typeElement.asType(), entity.asType())))
|| (entityJakarta != null && (compilationController.getTypes().isSubtype(typeElement.asType(), entityJakarta.asType())));
}

/**
Expand All @@ -134,12 +140,15 @@ protected static boolean isSession(CompilationController compilationController,
TypeElement stateless = compilationController.getElements().getTypeElement("javax.ejb.Stateless");
TypeElement stateful = compilationController.getElements().getTypeElement("javax.ejb.Stateful");
TypeElement singleton = compilationController.getElements().getTypeElement("javax.ejb.Singleton");
if (stateful != null && stateless != null && singleton != null) {
return (compilationController.getTypes().isSubtype(typeElement.asType(), stateless.asType())
|| compilationController.getTypes().isSubtype(typeElement.asType(), stateful.asType())
|| compilationController.getTypes().isSubtype(typeElement.asType(), singleton.asType()));
}
return false;
TypeElement statelessJakarta = compilationController.getElements().getTypeElement("jakarta.ejb.Stateless");
TypeElement statefulJakarta = compilationController.getElements().getTypeElement("jakarta.ejb.Stateful");
TypeElement singletonJakarta = compilationController.getElements().getTypeElement("jakarta.ejb.Singleton");
return (stateless != null && compilationController.getTypes().isSubtype(typeElement.asType(), stateless.asType()))
|| (stateful != null && compilationController.getTypes().isSubtype(typeElement.asType(), stateful.asType()))
|| (singleton != null && compilationController.getTypes().isSubtype(typeElement.asType(), singleton.asType()))
|| (statelessJakarta != null && compilationController.getTypes().isSubtype(typeElement.asType(), statelessJakarta.asType()))
|| (statefulJakarta != null && compilationController.getTypes().isSubtype(typeElement.asType(), statefulJakarta.asType()))
|| (singletonJakarta != null && compilationController.getTypes().isSubtype(typeElement.asType(), singletonJakarta.asType()));
}

/**
Expand All @@ -153,10 +162,9 @@ protected static boolean isStateful(CompilationController compilationController,
Parameters.notNull("typeElement", typeElement);

TypeElement stateful = compilationController.getElements().getTypeElement("javax.ejb.Stateful");
if (stateful != null) {
return (compilationController.getTypes().isSubtype(typeElement.asType(), stateful.asType()));
}
return false;
TypeElement statefulJakarta = compilationController.getElements().getTypeElement("jakarta.ejb.Stateful");
return (stateful != null && compilationController.getTypes().isSubtype(typeElement.asType(), stateful.asType()))
|| (statefulJakarta != null && compilationController.getTypes().isSubtype(typeElement.asType(), statefulJakarta.asType()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public AddBusinessMethodStrategy() {
super(NbBundle.getMessage(AddBusinessMethodStrategy.class, "LBL_AddBusinessMethodAction"));
}

protected MethodModel getPrototypeMethod() {
protected MethodModel getPrototypeMethod(boolean jakartaVariant) {
return MethodModel.create(
"businessMethod",
"void",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ public AddCreateMethodStrategy() {
super(NbBundle.getMessage(AddCreateMethodStrategy.class, "LBL_AddCreateMethodAction"));
}

protected MethodModel getPrototypeMethod() {
protected MethodModel getPrototypeMethod(boolean jakartaVariant) {
return MethodModel.create(
"create",
"void",
"",
Collections.<MethodModel.Variable>emptyList(),
Collections.singletonList("javax.ejb.CreateException"),
Collections.singletonList(jakartaVariant ? "jakarta.ejb.CreateException" : "javax.ejb.CreateException"),
Collections.<Modifier>emptySet()
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ public AddFinderMethodStrategy () {
super (NbBundle.getMessage(AddFinderMethodStrategy.class, "LBL_AddFinderMethodAction"));
}

protected MethodModel getPrototypeMethod() {
return getFinderPrototypeMethod();
protected MethodModel getPrototypeMethod(boolean jakartaVariant) {
return getFinderPrototypeMethod(jakartaVariant);
}

protected MethodCustomizer createDialog(FileObject fileObject, final MethodModel methodModel) throws IOException {
Expand Down Expand Up @@ -127,13 +127,13 @@ public void run(CompilationController cc) throws Exception {
return isEntity.get();
}

private static MethodModel getFinderPrototypeMethod() {
private static MethodModel getFinderPrototypeMethod(boolean jakartaVariant) {
return MethodModel.create(
"findBy",
"void",
"",
Collections.<MethodModel.Variable>emptyList(),
Collections.singletonList("javax.ejb.FinderException"),
Collections.singletonList(jakartaVariant ? "jakarta.ejb.FinderException" : "javax.ejb.FinderException"),
Collections.<Modifier>emptySet()
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public AddHomeMethodStrategy () {
super(NbBundle.getMessage(AddHomeMethodStrategy.class, "LBL_AddHomeMethodAction"));
}

protected MethodModel getPrototypeMethod() {
protected MethodModel getPrototypeMethod(boolean jakartaVariant) {
return MethodModel.create(
"homeMethod",
"void",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ public AddSelectMethodStrategy(String name) {
}

@Override
public MethodModel getPrototypeMethod() {
public MethodModel getPrototypeMethod(boolean jakartaVariant) {
Set<Modifier> modifiers = EnumSet.of(Modifier.PUBLIC, Modifier.ABSTRACT);
return MethodModel.create(
"ejbSelectBy",
"int",
"",
Collections.<MethodModel.Variable>emptyList(),
Collections.singletonList("javax.ejb.FinderException"),
Collections.singletonList(jakartaVariant ? "jakarta.ejb.FinderException" : "javax.ejb.FinderException"),
modifiers
);
}
Expand Down
Loading

0 comments on commit 795f283

Please sign in to comment.