Skip to content

Commit ce8d0ee

Browse files
closes #56 Migrate all properties to @stateless when migrating ejb-jar.xml to annotation (#123)
Co-authored-by: Ravi Gupta <[email protected]>
1 parent 465f97f commit ce8d0ee

File tree

2 files changed

+250
-15
lines changed

2 files changed

+250
-15
lines changed

components/sbm-recipes-jee-to-boot/src/main/java/org/springframework/sbm/jee/ejb/actions/MigrateEjbDeploymentDescriptor.java

Lines changed: 87 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.springframework.sbm.java.api.JavaSource;
2020
import org.springframework.sbm.java.api.Type;
2121
import org.springframework.sbm.engine.context.ProjectContext;
22+
import org.springframework.sbm.jee.ejb.api.DescriptionType;
2223
import org.springframework.sbm.jee.ejb.api.SessionBeanType;
2324
import org.springframework.sbm.jee.ejb.api.EjbJarXml;
2425
import org.springframework.sbm.jee.ejb.filter.EjbJarXmlResourceFilter;
@@ -89,23 +90,99 @@ private void handleStatelessSessionBean(ProjectContext context, SessionBeanType
8990
}
9091

9192
// add @Stateless annotation as defined in deployment descriptor
92-
String snippet = "@Stateless";
93-
if (ejbNameGiven(sbt)) {
94-
// TODO: #470
95-
snippet += "(name=\"" + getEjbName(sbt) + "\")";
96-
}
97-
type.addAnnotation(snippet, "javax.ejb.Stateless");
93+
final StringBuilder statelessSnippet =
94+
new StringBuilder("@Stateless(")
95+
.append(getEjbName(sbt)
96+
.map(n -> "name = \"" + n + "\"")
97+
.orElse("")
98+
).append(getMappedName(sbt)
99+
.map(m -> ", mappedName = \"" + m + "\"")
100+
.orElse("")
101+
).append(getDescription(sbt)
102+
.map(d -> ", description = \"" + d + "\"")
103+
.orElse("")
104+
).append(")");
105+
106+
if(statelessSnippet.length() == "@Statlesss()".length())
107+
statelessSnippet.deleteCharAt("@Statlesss".length() - 1);
108+
109+
type.addAnnotation(statelessSnippet.toString(), "javax.ejb.Stateless");
110+
111+
getRemote(sbt)
112+
.map( r -> "@Remote(" + r + ".class)")
113+
.ifPresent( a -> type.addAnnotation(a,"javax.ejb.Remote"));
114+
115+
getRemoteHome(sbt)
116+
.map( r -> "@RemoteHome(" + r + ".class)")
117+
.ifPresent( a -> type.addAnnotation(a,"javax.ejb.RemoteHome"));
118+
119+
getLocal(sbt)
120+
.map( r -> "@Local(" + r + ".class)")
121+
.ifPresent( a -> type.addAnnotation(a,"javax.ejb.Local"));
122+
123+
getLocalHome(sbt)
124+
.map( r -> "@LocalHome(" + r + ".class)")
125+
.ifPresent( a -> type.addAnnotation(a,"javax.ejb.LocalHome"));
126+
127+
getTransactionType(sbt)
128+
.map( r -> "@TransactionManagement(javax.ejb.TransactionManagementType." + r.toUpperCase() + ")")
129+
.ifPresent( a -> type.addAnnotation(a,"javax.ejb.TransactionManagement"));
98130

99131
} else {
100132
throw new RuntimeException("Could not find any Java file declaring type '" + fqName + "'");
101133
}
102134
}
103135

104-
private String getEjbName(SessionBeanType sbt) {
105-
return sbt.getEjbName().getValue();
136+
private Optional<String> getEjbName(SessionBeanType sbt) {
137+
return sbt.getEjbName() != null && !sbt.getEjbName().getValue().isEmpty()
138+
? Optional.ofNullable(sbt.getEjbName().getValue())
139+
: Optional.empty();
140+
}
141+
private Optional<String> getMappedName(SessionBeanType sbt){
142+
return sbt.getMappedName() != null && !sbt.getMappedName().getValue().isEmpty()
143+
? Optional.ofNullable(sbt.getMappedName().getValue())
144+
: Optional.empty();
145+
146+
}
147+
148+
//FIXME Add support for other languages in description. Currently description attribute of
149+
// @Stateless annotation is not a list
150+
private Optional<String> getDescription(SessionBeanType sbt) {
151+
return sbt.getDescription() != null ? sbt.getDescription()
152+
.stream()
153+
.filter( d ->"en".equalsIgnoreCase(d.getLang()))
154+
.map(DescriptionType::getValue)
155+
.findFirst()
156+
: Optional.empty();
157+
}
158+
159+
private Optional<String> getRemote(SessionBeanType sbt){
160+
return sbt.getRemote() != null && !sbt.getRemote().getValue().isEmpty()
161+
? Optional.ofNullable(sbt.getRemote().getValue())
162+
: Optional.empty();
163+
}
164+
165+
private Optional<String> getRemoteHome(SessionBeanType sbt){
166+
return sbt.getHome() != null && !sbt.getHome().getValue().isEmpty()
167+
? Optional.ofNullable(sbt.getHome().getValue())
168+
: Optional.empty();
169+
}
170+
171+
private Optional<String> getLocal(SessionBeanType sbt){
172+
return sbt.getLocal() != null && !sbt.getLocal().getValue().isEmpty()
173+
? Optional.ofNullable(sbt.getLocal().getValue())
174+
: Optional.empty();
175+
}
176+
177+
private Optional<String> getLocalHome(SessionBeanType sbt){
178+
return sbt.getLocalHome() != null && !sbt.getLocalHome().getValue().isEmpty()
179+
? Optional.ofNullable(sbt.getLocalHome().getValue())
180+
: Optional.empty();
106181
}
107182

108-
private boolean ejbNameGiven(SessionBeanType sbt) {
109-
return sbt.getEjbName() != null && !sbt.getEjbName().getValue().isEmpty();
183+
private Optional<String> getTransactionType(SessionBeanType sbt){
184+
return sbt.getTransactionType() != null && !sbt.getTransactionType().getValue().isEmpty()
185+
? Optional.ofNullable(sbt.getTransactionType().getValue())
186+
: Optional.empty();
110187
}
111188
}

components/sbm-recipes-jee-to-boot/src/test/java/org/springframework/sbm/jee/ejb/actions/MigrateEjbDeploymentDescriptorTest.java

Lines changed: 163 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,23 @@ class MigrateEjbDeploymentDescriptorTest {
3232
public static final String EJB_CLASS_FQNAME = "com.example.jee.ejb.stateless.local.deploymentdescriptor.NoInterfaceViewBean";
3333
public static final String EJB_TYPE = "Stateless";
3434
private static final String EJB_NAME = "noInterfaceView";
35+
private static final String EJB_WITH_MAPPED_NAME = "MappedNameView";
36+
private static final String EJB_WITH_MAPPED_CLASS_FQNAME = "com.example.jee.ejb.stateless.local.deploymentdescriptor.MappedNameView";
37+
private static final String MAPPED_NAME = "java:comp/env/ejb/MappedNameViewBean";
38+
private static final String EJB_WITH_REMOTE_INTERFACE_NAME = "RemoteInterfaceView";
39+
public static final String EJB_WITH_REMOTE_INTERFACE_FQDN = "com.example.jee.ejb.stateless.local.deploymentdescriptor.RemoteInterfaceView";
40+
private static final String REMOTE_EJB_INTERFACE = "com.example.jee.ejb.stateless.local.deploymentdescriptor.RemoteInterface";
41+
private static final String EJB_WITH_LOCAL_INTERFACE_NAME = "LocalInterfaceView";
42+
public static final String EJB_WITH_LOCAL_INTERFACE_FQDN = "com.example.jee.ejb.stateless.local.deploymentdescriptor.LocalInterfaceView";
43+
private static final String LOCAL_EJB_INTERFACE = "com.example.jee.ejb.stateless.local.deploymentdescriptor.LocalInterface";
3544

3645
@Test
3746
void givenDeploymentDescriptorContainsEjbWhenMatchingClassIsFoundThenStatelessAnnotationShouldBeOverwritten() {
3847
// setup fixture
39-
String javaSource =
40-
"package com.example.jee.ejb.stateless.local.deploymentdescriptor;\n" +
41-
"import javax.ejb.Stateless;\n" +
42-
"@Stateless(name=\"banana\")\n" +
43-
"public class NoInterfaceViewBean {}";
48+
String javaSource = "package com.example.jee.ejb.stateless.local.deploymentdescriptor;\n" +
49+
"import javax.ejb.Stateless;\n" +
50+
"@Stateless(name=\"banana\")\n" +
51+
"public class NoInterfaceViewBean {}";
4452

4553
String expected = "package com.example.jee.ejb.stateless.local.deploymentdescriptor;\n" +
4654
"\n" +
@@ -71,6 +79,156 @@ void givenDeploymentDescriptorContainsEjbWhenMatchingClassIsFoundThenStatelessAn
7179
.build();
7280

7381

82+
// call SUT
83+
MigrateEjbDeploymentDescriptor sut = new MigrateEjbDeploymentDescriptor();
84+
sut.apply(projectContext);
85+
86+
// verify...
87+
assertThat(projectContext.getProjectJavaSources().list().size()).isEqualTo(1);
88+
assertThat(projectContext.getProjectJavaSources().list().get(0).print()).isEqualTo(expected);
89+
List<EjbJarXml> deploymentDescriptors = projectContext.search(new GenericTypeListFilter<>(EjbJarXml.class));
90+
assertThat(deploymentDescriptors).isEmpty();
91+
}
92+
93+
@Test
94+
void givenDeploymentDescriptorContainsEjbWithMappedName_whenMatchingClassIsFound_thenStatelessAnnotationShouldBeOverwritten() {
95+
// setup fixture
96+
String javaSource =
97+
"package com.example.jee.ejb.stateless.local.deploymentdescriptor;\n" +
98+
"import javax.ejb.Stateless;\n" +
99+
"@Stateless(name=\"banana\")\n" +
100+
"public class MappedNameView {}";
101+
102+
String expected = "package com.example.jee.ejb.stateless.local.deploymentdescriptor;\n" +
103+
"\n" +
104+
"import javax.ejb.Stateless;\n" +
105+
"\n" +
106+
"@Stateless(name = \"" + EJB_WITH_MAPPED_NAME + "\", mappedName = \"" + MAPPED_NAME + "\")\n" +
107+
"public class MappedNameView {}";
108+
109+
String deploymentDescriptorXml = "<ejb-jar xmlns=\"http://xmlns.jcp.org/xml/ns/javaee\"\n" +
110+
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
111+
" xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/javaee\n" +
112+
" http://xmlns.jcp.org/xml/ns/javaee/ejb-jar_3_2.xsd\"\n" +
113+
" version=\"3.2\">\n" +
114+
" <enterprise-beans>\n" +
115+
" <session>\n" +
116+
" <ejb-name>" + EJB_WITH_MAPPED_NAME + "</ejb-name>\n" +
117+
" <ejb-class>" + EJB_WITH_MAPPED_CLASS_FQNAME + "</ejb-class>\n" +
118+
" <mapped-name>" + MAPPED_NAME + "</mapped-name>\n" +
119+
" <session-type>" + EJB_TYPE + "</session-type>\n" +
120+
" </session>\n" +
121+
" </enterprise-beans>\n" +
122+
"</ejb-jar>";
123+
124+
ProjectContext projectContext = TestProjectContext.buildProjectContext()
125+
.addProjectResource(Path.of("./src/main/resources/META-INF/ejb-jar.xml"), deploymentDescriptorXml)
126+
.withJavaSources(javaSource)
127+
.withBuildFileHavingDependencies("javax.ejb:javax.ejb-api:3.2")
128+
.addRegistrar(new JeeEjbJarXmlProjectResourceRegistrar())
129+
.build();
130+
131+
132+
// call SUT
133+
MigrateEjbDeploymentDescriptor sut = new MigrateEjbDeploymentDescriptor();
134+
sut.apply(projectContext);
135+
136+
// verify...
137+
assertThat(projectContext.getProjectJavaSources().list().size()).isEqualTo(1);
138+
assertThat(projectContext.getProjectJavaSources().list().get(0).print()).isEqualTo(expected);
139+
List<EjbJarXml> deploymentDescriptors = projectContext.search(new GenericTypeListFilter<>(EjbJarXml.class));
140+
assertThat(deploymentDescriptors).isEmpty();
141+
}
142+
143+
@Test
144+
void givenDeploymentDescriptorContainsEjbWithRemoteInterface_whenMatchingClassIsFound_thenStatelessRemoteAnnotationShouldBeGenerated() {
145+
// setup fixture
146+
String javaSource =
147+
"package com.example.jee.ejb.stateless.local.deploymentdescriptor;\n" +
148+
"import javax.ejb.Stateless;\n" +
149+
"public class RemoteInterfaceView implements RemoteInterface{}";
150+
151+
String expected = "package com.example.jee.ejb.stateless.local.deploymentdescriptor;\n" +
152+
"import javax.ejb.Remote;\n" +
153+
"import javax.ejb.Stateless;\n" +
154+
"\n" +
155+
"@Stateless(name = \"" + EJB_WITH_REMOTE_INTERFACE_NAME + "\")\n" +
156+
"@Remote(" + REMOTE_EJB_INTERFACE + ".class)\n" +
157+
"public class RemoteInterfaceView implements RemoteInterface {}";
158+
159+
String deploymentDescriptorXml = "<ejb-jar xmlns=\"http://xmlns.jcp.org/xml/ns/javaee\"\n" +
160+
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
161+
" xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/javaee\n" +
162+
" http://xmlns.jcp.org/xml/ns/javaee/ejb-jar_3_2.xsd\"\n" +
163+
" version=\"3.2\">\n" +
164+
" <enterprise-beans>\n" +
165+
" <session>\n" +
166+
" <ejb-name>" + EJB_WITH_REMOTE_INTERFACE_NAME + "</ejb-name>\n" +
167+
" <ejb-class>" + EJB_WITH_REMOTE_INTERFACE_FQDN + "</ejb-class>\n" +
168+
" <remote>" + REMOTE_EJB_INTERFACE + "</remote>\n" +
169+
" <session-type>" + EJB_TYPE + "</session-type>\n" +
170+
" </session>\n" +
171+
" </enterprise-beans>\n" +
172+
"</ejb-jar>";
173+
174+
ProjectContext projectContext = TestProjectContext.buildProjectContext()
175+
.addProjectResource(Path.of("./src/main/resources/META-INF/ejb-jar.xml"), deploymentDescriptorXml)
176+
.withJavaSources(javaSource)
177+
.withBuildFileHavingDependencies("javax.ejb:javax.ejb-api:3.2")
178+
.addRegistrar(new JeeEjbJarXmlProjectResourceRegistrar())
179+
.build();
180+
181+
182+
// call SUT
183+
MigrateEjbDeploymentDescriptor sut = new MigrateEjbDeploymentDescriptor();
184+
sut.apply(projectContext);
185+
186+
// verify...
187+
assertThat(projectContext.getProjectJavaSources().list().size()).isEqualTo(1);
188+
assertThat(projectContext.getProjectJavaSources().list().get(0).print()).isEqualTo(expected);
189+
List<EjbJarXml> deploymentDescriptors = projectContext.search(new GenericTypeListFilter<>(EjbJarXml.class));
190+
assertThat(deploymentDescriptors).isEmpty();
191+
}
192+
193+
@Test
194+
void givenDeploymentDescriptorContainsEjbWithLocalInterface_whenMatchingClassIsFound_thenStatelessLocalAnnotationShouldBeGenerated() {
195+
// setup fixture
196+
String javaSource =
197+
"package com.example.jee.ejb.stateless.local.deploymentdescriptor;\n" +
198+
"import javax.ejb.Stateless;\n" +
199+
"public class LocalInterfaceView implements LocalInterface{}";
200+
201+
String expected = "package com.example.jee.ejb.stateless.local.deploymentdescriptor;\n" +
202+
"import javax.ejb.Local;\n" +
203+
"import javax.ejb.Stateless;\n" +
204+
"\n" +
205+
"@Stateless(name = \"" + EJB_WITH_LOCAL_INTERFACE_NAME + "\")\n" +
206+
"@Local(" + LOCAL_EJB_INTERFACE + ".class)\n" +
207+
"public class LocalInterfaceView implements LocalInterface {}";
208+
209+
String deploymentDescriptorXml = "<ejb-jar xmlns=\"http://xmlns.jcp.org/xml/ns/javaee\"\n" +
210+
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
211+
" xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/javaee\n" +
212+
" http://xmlns.jcp.org/xml/ns/javaee/ejb-jar_3_2.xsd\"\n" +
213+
" version=\"3.2\">\n" +
214+
" <enterprise-beans>\n" +
215+
" <session>\n" +
216+
" <ejb-name>" + EJB_WITH_LOCAL_INTERFACE_NAME + "</ejb-name>\n" +
217+
" <ejb-class>" + EJB_WITH_LOCAL_INTERFACE_FQDN + "</ejb-class>\n" +
218+
" <local>" + LOCAL_EJB_INTERFACE + "</local>\n" +
219+
" <session-type>" + EJB_TYPE + "</session-type>\n" +
220+
" </session>\n" +
221+
" </enterprise-beans>\n" +
222+
"</ejb-jar>";
223+
224+
ProjectContext projectContext = TestProjectContext.buildProjectContext()
225+
.addProjectResource(Path.of("./src/main/resources/META-INF/ejb-jar.xml"), deploymentDescriptorXml)
226+
.withJavaSources(javaSource)
227+
.withBuildFileHavingDependencies("javax.ejb:javax.ejb-api:3.2")
228+
.addRegistrar(new JeeEjbJarXmlProjectResourceRegistrar())
229+
.build();
230+
231+
74232
// call SUT
75233
MigrateEjbDeploymentDescriptor sut = new MigrateEjbDeploymentDescriptor();
76234
sut.apply(projectContext);

0 commit comments

Comments
 (0)