Skip to content

Commit 7271f37

Browse files
authored
added XML parsing test (#2293)
* added XML parsing test * refactor * refactor * refactor
1 parent 5c00eed commit 7271f37

19 files changed

Lines changed: 1051 additions & 425 deletions
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.predic8.membrane.annot;
2+
3+
import com.predic8.membrane.annot.util.CompilerHelper;
4+
import org.junit.jupiter.api.Test;
5+
6+
import static com.predic8.membrane.annot.SpringConfigurationXSDGeneratingAnnotationProcessorTest.MC_MAIN_DEMO;
7+
import static com.predic8.membrane.annot.util.CompilerHelper.*;
8+
9+
public class ParsingTest {
10+
11+
private String wrapSpring(String content) {
12+
return """
13+
<spring:beans xmlns="http://membrane-soa.org/demo/1/"
14+
xmlns:spring="http://www.springframework.org/schema/beans"
15+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
16+
xsi:schemaLocation="http://www.springframework.org/schema/beans
17+
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
18+
http://membrane-soa.org/demo/1/ http://membrane-soa.org/schemas/demo-1.xsd">
19+
""" + content + """
20+
</spring:beans>
21+
""";
22+
}
23+
24+
@Test
25+
public void simple() {
26+
var sources = splitSources(MC_MAIN_DEMO + """
27+
package com.predic8.membrane.demo;
28+
import com.predic8.membrane.annot.*;
29+
import java.util.List;
30+
@MCElement(name="demo")
31+
public class DemoElement {
32+
}
33+
""");
34+
var result = CompilerHelper.compile(sources, false);
35+
assertCompilerResult(true, result);
36+
37+
parse(result, wrapSpring("""
38+
<demo />
39+
"""));
40+
}
41+
42+
@Test
43+
public void childElements() {
44+
var sources = splitSources(MC_MAIN_DEMO + """
45+
package com.predic8.membrane.demo;
46+
import com.predic8.membrane.annot.*;
47+
import java.util.List;
48+
@MCElement(name="root")
49+
public class DemoElement {
50+
@MCChildElement
51+
public void setChild(AbstractDemoChildElement s) {}
52+
}
53+
---
54+
package com.predic8.membrane.demo;
55+
public abstract class AbstractDemoChildElement {
56+
}
57+
---
58+
package com.predic8.membrane.demo;
59+
import com.predic8.membrane.annot.*;
60+
@MCElement(name="child1")
61+
public class Child1 extends AbstractDemoChildElement {
62+
}
63+
---
64+
package com.predic8.membrane.demo;
65+
import com.predic8.membrane.annot.*;
66+
@MCElement(name="child2")
67+
public class Child2 extends AbstractDemoChildElement {
68+
}
69+
""");
70+
var result = CompilerHelper.compile(sources, false);
71+
assertCompilerResult(true, result);
72+
73+
parse(result, wrapSpring("""
74+
<root>
75+
<child1 />
76+
</root>
77+
"""));
78+
}
79+
}

annot/src/test/java/com/predic8/membrane/annot/SpringConfigXSDErrorsTest.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
public class SpringConfigXSDErrorsTest {
2828
@Test
2929
public void mcMainMissing() {
30-
List<JavaFileObject> sources = splitSources("""
30+
var sources = splitSources("""
3131
package com.predic8.membrane.demo;
3232
public class Demo {
3333
}
@@ -47,7 +47,7 @@ public class DemoElement {
4747

4848
@Test
4949
public void mcElementNameMissing() {
50-
List<JavaFileObject> sources = splitSources("""
50+
var sources = splitSources("""
5151
package com.predic8.membrane.demo;
5252
import com.predic8.membrane.annot.MCElement;
5353
@MCElement
@@ -63,7 +63,7 @@ public class DemoElement {
6363

6464
@Test
6565
public void mcElementMissing() {
66-
List<JavaFileObject> sources = splitSources(MC_MAIN_DEMO);
66+
var sources = splitSources(MC_MAIN_DEMO);
6767
var result = CompilerHelper.compile(sources, false);
6868

6969
assertCompilerResult(false, of(
@@ -74,7 +74,7 @@ public void mcElementMissing() {
7474

7575
@Test
7676
public void duplicateMcElementId() {
77-
List<JavaFileObject> sources = splitSources(MC_MAIN_DEMO + """
77+
var sources = splitSources(MC_MAIN_DEMO + """
7878
package com.predic8.membrane.demo;
7979
import com.predic8.membrane.annot.MCElement;
8080
@MCElement(name="demo")
@@ -97,7 +97,7 @@ public class DemoElement2 {
9797

9898
@Test
9999
public void duplicateMcElementName() {
100-
List<JavaFileObject> sources = splitSources(MC_MAIN_DEMO + """
100+
var sources = splitSources(MC_MAIN_DEMO + """
101101
package com.predic8.membrane.demo;
102102
import com.predic8.membrane.annot.MCElement;
103103
@MCElement(name="demo", id="demo1")
@@ -123,7 +123,7 @@ class NoEnvelope {
123123

124124
@Test
125125
public void topLevel() {
126-
List<JavaFileObject> sources = splitSources(MC_MAIN_DEMO + """
126+
var sources = splitSources(MC_MAIN_DEMO + """
127127
package com.predic8.membrane.demo;
128128
import com.predic8.membrane.annot.MCElement;
129129
@MCElement(name="demo", noEnvelope=true)
@@ -139,7 +139,7 @@ public class DemoElement {
139139

140140
@Test
141141
public void mixed() {
142-
List<JavaFileObject> sources = splitSources(MC_MAIN_DEMO + """
142+
var sources = splitSources(MC_MAIN_DEMO + """
143143
package com.predic8.membrane.demo;
144144
import com.predic8.membrane.annot.MCElement;
145145
@MCElement(name="demo", noEnvelope=true, topLevel=false, mixed=true)
@@ -155,7 +155,7 @@ public class DemoElement {
155155

156156
@Test
157157
public void noChildElements() {
158-
List<JavaFileObject> sources = splitSources(MC_MAIN_DEMO + """
158+
var sources = splitSources(MC_MAIN_DEMO + """
159159
package com.predic8.membrane.demo;
160160
import com.predic8.membrane.annot.MCElement;
161161
@MCElement(name="demo", noEnvelope=true, topLevel=false)
@@ -171,7 +171,7 @@ public class DemoElement {
171171

172172
@Test
173173
public void twoChildElements() {
174-
List<JavaFileObject> sources = splitSources(MC_MAIN_DEMO + """
174+
var sources = splitSources(MC_MAIN_DEMO + """
175175
package com.predic8.membrane.demo;
176176
import com.predic8.membrane.annot.MCElement;
177177
import com.predic8.membrane.annot.MCChildElement;
@@ -193,7 +193,7 @@ public void setChild2(List<DemoElement> s) {}
193193

194194
@Test
195195
public void childIsNotAList() {
196-
List<JavaFileObject> sources = splitSources(MC_MAIN_DEMO + """
196+
var sources = splitSources(MC_MAIN_DEMO + """
197197
package com.predic8.membrane.demo;
198198
import com.predic8.membrane.annot.MCElement;
199199
import com.predic8.membrane.annot.MCChildElement;
@@ -212,7 +212,7 @@ public void setChild1(DemoElement s) {}
212212

213213
@Test
214214
public void hasAttributes() {
215-
List<JavaFileObject> sources = splitSources(MC_MAIN_DEMO + """
215+
var sources = splitSources(MC_MAIN_DEMO + """
216216
package com.predic8.membrane.demo;
217217
import com.predic8.membrane.annot.*;
218218
import java.util.List;
@@ -233,7 +233,7 @@ public void setAttribute1(String s) {}
233233

234234
@Test
235235
public void otherAttributes() {
236-
List<JavaFileObject> sources = splitSources(MC_MAIN_DEMO + """
236+
var sources = splitSources(MC_MAIN_DEMO + """
237237
package com.predic8.membrane.demo;
238238
import com.predic8.membrane.annot.*;
239239
import java.util.List;
@@ -255,7 +255,7 @@ public void setAttributes(Map<String, String> attributes) {}
255255

256256
@Test
257257
public void textContent() {
258-
List<JavaFileObject> sources = splitSources(MC_MAIN_DEMO + """
258+
var sources = splitSources(MC_MAIN_DEMO + """
259259
package com.predic8.membrane.demo;
260260
import com.predic8.membrane.annot.*;
261261
import java.util.List;
@@ -280,7 +280,7 @@ public void setContent(String content) {}
280280
class TextContent {
281281
@Test
282282
public void mcTextContentMissing() {
283-
List<JavaFileObject> sources = splitSources(MC_MAIN_DEMO + """
283+
var sources = splitSources(MC_MAIN_DEMO + """
284284
package com.predic8.membrane.demo;
285285
import com.predic8.membrane.annot.*;
286286
@MCElement(name="demo", mixed=true)
@@ -295,7 +295,7 @@ public class DemoElement {
295295
}
296296
@Test
297297
public void mixedMissing() {
298-
List<JavaFileObject> sources = splitSources(MC_MAIN_DEMO + """
298+
var sources = splitSources(MC_MAIN_DEMO + """
299299
package com.predic8.membrane.demo;
300300
import com.predic8.membrane.annot.*;
301301
@MCElement(name="demo")
@@ -315,7 +315,7 @@ public void setContent(String content) {}
315315

316316
@Test
317317
public void noConcreteChildMcElement() {
318-
List<JavaFileObject> sources = splitSources(MC_MAIN_DEMO + """
318+
var sources = splitSources(MC_MAIN_DEMO + """
319319
package com.predic8.membrane.demo;
320320
import com.predic8.membrane.annot.*;
321321
import java.util.List;
@@ -338,7 +338,7 @@ public abstract class AbstractDemoChildElement {
338338

339339
@Test
340340
public void childNameNotUnique() {
341-
List<JavaFileObject> sources = splitSources(MC_MAIN_DEMO + """
341+
var sources = splitSources(MC_MAIN_DEMO + """
342342
package com.predic8.membrane.demo;
343343
import com.predic8.membrane.annot.*;
344344
import java.util.List;

annot/src/test/java/com/predic8/membrane/annot/SpringConfigurationXSDGeneratingAnnotationProcessorTest.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323
public class SpringConfigurationXSDGeneratingAnnotationProcessorTest {
2424

2525
public static final String MC_MAIN_DEMO = """
26+
resource META-INF/spring.handlers
27+
http\\://membrane-soa.org/demo/1/=com.predic8.membrane.demo.config.spring.NamespaceHandler
28+
---
29+
resource META-INF/spring.schemas
30+
http\\://membrane-soa.org/schemas/demo-1.xsd=com/predic8/membrane/demo/config/spring/router-conf.xsd
31+
---
2632
package com.predic8.membrane.demo;
2733
import com.predic8.membrane.annot.MCMain;
2834
@MCMain(
@@ -45,7 +51,7 @@ public void init() {
4551

4652
@Test
4753
public void simpleTest() {
48-
List<JavaFileObject> sources = splitSources(MC_MAIN_DEMO + """
54+
var sources = splitSources(MC_MAIN_DEMO + """
4955
package com.predic8.membrane.demo;
5056
import com.predic8.membrane.annot.MCElement;
5157
@MCElement(name="demo")

annot/src/test/java/com/predic8/membrane/annot/util/CompilerHelper.java

Lines changed: 87 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,52 +18,131 @@
1818
import org.hamcrest.collection.IsIterableContainingInAnyOrder;
1919

2020
import javax.tools.*;
21+
import java.io.IOException;
22+
import java.io.PrintWriter;
2123
import java.util.ArrayList;
2224
import java.util.List;
2325
import java.util.regex.Matcher;
2426
import java.util.regex.Pattern;
2527
import java.util.stream.Stream;
2628

29+
import static java.util.List.of;
30+
import static java.util.stream.StreamSupport.stream;
31+
import static javax.tools.StandardLocation.CLASS_OUTPUT;
2732
import static org.hamcrest.MatcherAssert.assertThat;
2833
import static org.junit.jupiter.api.Assertions.assertEquals;
2934

3035
public class CompilerHelper {
31-
public static CompilerResult compile(Iterable<? extends JavaFileObject> sources, boolean logCompilerOutput) {
36+
/**
37+
* Compile the given source files.
38+
*
39+
* @param sourceFiles the source files to compile
40+
* @param logCompilerOutput if true, print the compiler output to stderr
41+
*/
42+
public static CompilerResult compile(Iterable<? extends FileObject> sourceFiles, boolean logCompilerOutput) {
43+
var javaSources = getJavaSources(sourceFiles);
3244
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
3345
if (compiler == null) {
3446
throw new IllegalStateException("No system Java compiler found. Run tests with a JDK, not a JRE.");
3547
}
3648
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
37-
JavaFileManager fileManager = new CustomJavaFileManager(compiler.getStandardFileManager(diagnostics, null, null));
49+
JavaFileManager fileManager = new LoggingInMemoryJavaFileManager(compiler.getStandardFileManager(diagnostics, null, null));
50+
51+
copyResourcesToOutput(getResources(sourceFiles), fileManager);
3852

3953
JavaCompiler.CompilationTask task = compiler.getTask(
4054
null,
4155
fileManager,
4256
diagnostics,
43-
List.of("-processor", "com.predic8.membrane.annot.SpringConfigurationXSDGeneratingAnnotationProcessor"),
57+
of("-processor", "com.predic8.membrane.annot.SpringConfigurationXSDGeneratingAnnotationProcessor"),
4458
null,
45-
sources
59+
javaSources
4660
);
4761

4862
boolean success = task.call();
4963

5064
if (logCompilerOutput)
5165
diagnostics.getDiagnostics().forEach(System.err::println);
5266

53-
return new CompilerResult(success, diagnostics);
67+
return new CompilerResult(success, diagnostics, fileManager.getClassLoader(CLASS_OUTPUT));
68+
}
69+
70+
/**
71+
* Parse the given XML Spring config.
72+
*/
73+
public static void parse(CompilerResult cr, String xmlSpringConfig) {
74+
ClassLoader originalClassloader = Thread.currentThread().getContextClassLoader();
75+
try {
76+
InMemoryClassLoader loaderA = (InMemoryClassLoader) cr.classLoader();
77+
loaderA.defineOverlay(new OverlayInMemoryFile("/demo.xml", xmlSpringConfig));
78+
CompositeClassLoader cl = new CompositeClassLoader(loaderA, CompilerHelper.class.getClassLoader());
79+
Thread.currentThread().setContextClassLoader(cl);
80+
Class<?> c = cl.loadClass("org.springframework.context.support.ClassPathXmlApplicationContext");
81+
c.getConstructor(String.class).newInstance("/demo.xml");
82+
} catch (Exception e) {
83+
throw new RuntimeException(e);
84+
} finally {
85+
Thread.currentThread().setContextClassLoader(originalClassloader);
86+
}
87+
}
88+
89+
private static List<JavaFileObject> getJavaSources(Iterable<? extends FileObject> sources) {
90+
return stream(sources.spliterator(), false)
91+
.filter(i -> i instanceof JavaFileObject)
92+
.map(i -> (JavaFileObject) i)
93+
.toList();
94+
}
95+
96+
private static List<OverlayInMemoryFile> getResources(Iterable<? extends FileObject> sources) {
97+
return stream(sources.spliterator(), false)
98+
.filter(i -> i instanceof OverlayInMemoryFile)
99+
.map(i -> (OverlayInMemoryFile) i)
100+
.toList();
101+
}
102+
103+
private static void copyResourcesToOutput(List<? extends OverlayInMemoryFile> sources, JavaFileManager fileManager) {
104+
sources.forEach(i -> {
105+
PrintWriter pw = null;
106+
try {
107+
pw = new PrintWriter(fileManager.getFileForOutput(CLASS_OUTPUT, "", i.getName(), null)
108+
.openWriter());
109+
} catch (IOException e) {
110+
throw new RuntimeException(e);
111+
}
112+
pw.write(i.getCharContent(true).toString());
113+
pw.close();
114+
});
54115
}
55116

56-
public static List<JavaFileObject> splitSources(String sources) {
117+
public static List<FileObject> splitSources(String sources) {
57118
return Stream.of(sources.split("---"))
58119
.filter(s -> !s.isBlank())
59-
.map(CompilerHelper::toInMemoryJavaFile)
120+
.map(CompilerHelper::toFile)
60121
.toList();
61122
}
62123

124+
private static FileObject toFile( String content) {
125+
if (!content.trim().startsWith("resource"))
126+
return toInMemoryJavaFile(content);
127+
128+
String[] parts;
129+
while(true) {
130+
parts = content.split("\n", 2);
131+
if (parts.length != 2)
132+
throw new RuntimeException("Invalid resource file: " + content + ". The resource is expected to have the format 'resource <path>\n<content>'.");
133+
if (!parts[0].isEmpty())
134+
break;
135+
content = parts[1];
136+
};
137+
138+
String name = parts[0].substring(9).trim();
139+
return new OverlayInMemoryFile(name, parts[1]);
140+
}
141+
63142
private static JavaFileObject toInMemoryJavaFile(String source) {
64143
String pkg = extractPackage(source);
65144
String cls = extractName(source);
66-
return new InMemoryJavaFile(pkg + "." + cls, source);
145+
return new OverlayInMemoryJavaFile(pkg + "." + cls, source);
67146
}
68147

69148
private static String extractName(String source) {

0 commit comments

Comments
 (0)