001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.jci.compilers;
019    
020    import java.util.HashMap;
021    import java.util.Map;
022    
023    import junit.framework.TestCase;
024    
025    import org.apache.commons.jci.problems.CompilationProblem;
026    import org.apache.commons.jci.readers.ResourceReader;
027    import org.apache.commons.jci.stores.MemoryResourceStore;
028    
029    /**
030     * Providing convenience methods for JavaCompiler TestCases
031     *
032     * @author tcurdt
033     */
034    public abstract class AbstractCompilerTestCase extends TestCase {
035    
036        public abstract JavaCompiler createJavaCompiler();
037    
038        public abstract String getCompilerName();
039    
040        public void testFactoryCreation() {
041            final JavaCompiler factoryCompiler = new JavaCompilerFactory().createCompiler(getCompilerName());
042            assertNotNull(factoryCompiler);
043    
044            final JavaCompiler compiler = createJavaCompiler();
045            assertEquals(factoryCompiler.getClass().getName(), compiler.getClass().getName());
046        }
047    
048        public void testSimpleCompile() throws Exception {
049            final JavaCompiler compiler = createJavaCompiler();
050    
051            final ResourceReader reader = new ResourceReader() {
052                final private Map<String, byte[]> sources = new HashMap<String, byte[]>() {
053                    private static final long serialVersionUID = 1L;
054                    {
055                        put("jci/Simple.java", (
056                            "package jci;\n" +
057                            "public class Simple {\n" +
058                            "  public String toString() {\n" +
059                            "    return \"Simple\";\n" +
060                            "  }\n" +
061                            "}").getBytes());
062                    }};
063    
064                public byte[] getBytes( final String pResourceName ) {
065                    return sources.get(pResourceName);
066                }
067    
068                public boolean isAvailable( final String pResourceName ) {
069                    return sources.containsKey(pResourceName);
070                }
071    
072            };
073    
074            final MemoryResourceStore store = new MemoryResourceStore();
075            final CompilationResult result = compiler.compile(
076                    new String[] {
077                            "jci/Simple.java"
078                    }, reader, store);
079    
080            assertEquals(toString(result.getErrors()), 0, result.getErrors().length);
081            assertEquals(toString(result.getWarnings()), 0, result.getWarnings().length);
082    
083            final byte[] clazzBytes = store.read("jci/Simple.class");
084            assertNotNull("jci/Simple.class is not null",clazzBytes);
085            assertTrue("jci/Simple.class is not empty", clazzBytes.length > 0);
086        }
087    
088        public void testExtendedCompile() throws Exception {
089            final JavaCompiler compiler = createJavaCompiler();
090    
091            final ResourceReader reader = new ResourceReader() {
092                final private Map<String, byte[]> sources = new HashMap<String, byte[]>() {
093                    private static final long serialVersionUID = 1L;
094                    {
095                        put("jci/Simple.java", (
096                                "package jci;\n" +
097                                "public class Simple {\n" +
098                                "  public String toString() {\n" +
099                                "    return \"Simple\";\n" +
100                                "  }\n" +
101                        "}").getBytes());
102                        put("jci/Extended.java", (
103                                "package jci;\n" +
104                                "public class Extended extends Simple {\n" +
105                                "  public String toString() {\n" +
106                                "    return \"Extended\" + super.toString();\n" +
107                                "  }\n" +
108                        "}").getBytes());
109                    }};
110    
111                public byte[] getBytes( final String pResourceName ) {
112                    return sources.get(pResourceName);
113                }
114    
115                public boolean isAvailable( final String pResourceName ) {
116                    return sources.containsKey(pResourceName);
117                }
118    
119            };
120    
121            final MemoryResourceStore store = new MemoryResourceStore();
122            final CompilationResult result = compiler.compile(
123                    new String[] {
124                            "jci/Extended.java",
125                            "jci/Simple.java"
126                    }, reader, store);
127    
128            assertEquals(toString(result.getErrors()), 0, result.getErrors().length);
129            assertEquals(toString(result.getWarnings()), 0, result.getWarnings().length);
130    
131            final byte[] clazzBytesSimple = store.read("jci/Simple.class");
132            assertNotNull("jci/Simple.class is not null", clazzBytesSimple);
133            assertTrue("jci/Simple.class is not empty", clazzBytesSimple.length > 0);
134    
135            final byte[] clazzBytesExtended = store.read("jci/Extended.class");
136            assertNotNull("jci/Extended.class is not null", clazzBytesExtended);
137            assertTrue("jci/Extended.class is not empty",clazzBytesExtended.length > 0);
138        }
139    
140        public void testInternalClassCompile() throws Exception {
141            final JavaCompiler compiler = createJavaCompiler();
142    
143            final ResourceReader reader = new ResourceReader() {
144                final private Map<String, byte[]> sources = new HashMap<String, byte[]>() {
145                    private static final long serialVersionUID = 1L;
146                    {
147                        put("jci/Simple.java", (
148                                "package jci;\n" +
149                                "public class Simple {\n" +
150                                "  private class Sub {\n" +
151                                "  }\n" +
152                                "  public String toString() {\n" +
153                                "    new Sub();\n" +
154                                "    return \"Simple\";\n" +
155                                "  }\n" +
156                        "}").getBytes());
157                    }};
158    
159                public byte[] getBytes( final String pResourceName ) {
160                    return sources.get(pResourceName);
161                }
162    
163                public boolean isAvailable( final String pResourceName ) {
164                    return sources.containsKey(pResourceName);
165                }
166    
167            };
168    
169            final MemoryResourceStore store = new MemoryResourceStore();
170            final CompilationResult result = compiler.compile(
171                    new String[] {
172                            "jci/Simple.java"
173                    }, reader, store);
174    
175            assertEquals(toString(result.getErrors()), 0, result.getErrors().length);
176            assertEquals(toString(result.getWarnings()), 0, result.getWarnings().length);
177    
178            final byte[] clazzBytes = store.read("jci/Simple.class");
179            assertNotNull("jci/Simple.class is not null", clazzBytes);
180            assertTrue("jci/Simple.class is not empty", clazzBytes.length > 0);
181    
182            final byte[] subClazzBytes = store.read("jci/Simple$Sub.class");
183            assertNotNull("jci/Simple$Sub.class is not null", subClazzBytes);
184            assertTrue("jci/Simple$Sub.class is not empty", subClazzBytes.length > 0);
185    
186        }
187    
188        public void testUppercasePackageNameCompile() throws Exception {
189            final JavaCompiler compiler = createJavaCompiler();
190    
191            final ResourceReader reader = new ResourceReader() {
192                final private Map<String, byte[]> sources = new HashMap<String, byte[]>() {
193                    private static final long serialVersionUID = 1L;
194                    {
195                        put("Jci/Simple.java", (
196                                "package Jci;\n" +
197                                "public class Simple {\n" +
198                                "  public String toString() {\n" +
199                                "    return \"Simple\";\n" +
200                                "  }\n" +
201                        "}").getBytes());
202                    }};
203    
204                public byte[] getBytes( final String pResourceName ) {
205                    return sources.get(pResourceName);
206                }
207    
208                public boolean isAvailable( final String pResourceName ) {
209                    return sources.containsKey(pResourceName);
210                }
211    
212            };
213    
214            final MemoryResourceStore store = new MemoryResourceStore();
215            final CompilationResult result = compiler.compile(
216                    new String[] {
217                            "Jci/Simple.java"
218                    }, reader, store);
219    
220            assertEquals(toString(result.getErrors()), 0, result.getErrors().length);
221            assertEquals(toString(result.getWarnings()), 0, result.getWarnings().length);
222    
223            final byte[] clazzBytes = store.read("Jci/Simple.class");
224            assertNotNull("Jci/Simple.class is not null", clazzBytes);
225            assertTrue("Jci/Simple.class is not empty", clazzBytes.length > 0);
226        }
227    
228        /*
229         * https://issues.apache.org/jira/browse/JCI-53
230         */
231        public void testCrossReferenceCompilation() throws Exception {
232          final String javaVersion = System.getProperty("java.version");
233    
234          final JavaCompiler compiler = createJavaCompiler();
235    
236            final ResourceReader reader = new ResourceReader() {
237                final private Map<String, byte[]> sources = new HashMap<String, byte[]>() {
238                    private static final long serialVersionUID = 1L;
239                    {
240                        put("jci/Func1.java", (
241                                "package jci;\n" +
242                                "import static jci.Func2.func2;" +
243                                "public class Func1 {\n" +
244                                "  public static boolean func1() throws Exception {\n" +
245                                "    return true;\n" +
246                                "  }\n" +
247                        "}").getBytes());
248                        put("jci/Func2.java", (
249                                "package jci;\n" +
250                                "import static jci.Func1.func1;" +
251                                "public class Func2 {\n" +
252                                "  public static boolean func2() throws Exception {\n" +
253                                "    return true;\n" +
254                                "  }\n" +
255                        "}").getBytes());
256                    }};
257    
258                public byte[] getBytes( final String pResourceName ) {
259                    return sources.get(pResourceName);
260                }
261    
262                public boolean isAvailable( final String pResourceName ) {
263                    return sources.containsKey(pResourceName);
264                }
265    
266            };
267    
268            final JavaCompilerSettings settings = compiler.createDefaultSettings();
269            settings.setTargetVersion("1.5");
270            settings.setSourceVersion("1.5");
271    
272            final MemoryResourceStore store = new MemoryResourceStore();
273            final CompilationResult result = compiler.compile(
274                    new String[] {
275                            "jci/Func1.java",
276                            "jci/Func2.java"
277                    }, reader, store, this.getClass().getClassLoader(), settings);
278    
279            assertEquals(toString(result.getErrors()), 0, result.getErrors().length);
280            assertEquals(toString(result.getWarnings()), 0, result.getWarnings().length);
281    
282            final byte[] clazzBytesFunc1 = store.read("jci/Func1.class");
283            assertNotNull("jci/Func1.class is not null", clazzBytesFunc1);
284            assertTrue("jci/Func1.class is not empty", clazzBytesFunc1.length > 0);
285    
286            final byte[] clazzBytesFunc2 = store.read("jci/Func2.class");
287            assertNotNull("jci/Func2.class is not null", clazzBytesFunc2);
288            assertTrue("jci/Func2.class is not empty", clazzBytesFunc2.length > 0);
289        }
290    
291        /*
292         * https://issues.apache.org/jira/browse/JCI-59
293         */
294        public void testAdditionalTopLevelClassCompile() throws Exception {
295            final JavaCompiler compiler = createJavaCompiler(); 
296        
297            final ResourceReader reader = new ResourceReader() {
298               final private Map<String, byte[]> sources = new HashMap<String, byte[]>() {
299                   private static final long serialVersionUID = 1L;
300                   {
301                       put("jci/Simple.java", (
302                           "package jci;\n" +
303                           "public class Simple {\n" +
304                           "  public String toString() {\n" +
305                           "    return \"Simple\";\n" +
306                           "  }\n" +
307                           "}\n" +
308                           "class AdditionalTopLevel {\n" +
309                           "  public String toString() {\n" +
310                           "    return \"AdditionalTopLevel\";\n" +
311                           "  }\n" +
312                           "}").getBytes());
313                   }};
314        
315               public byte[] getBytes( final String pResourceName ) {
316                   return sources.get(pResourceName);
317               }
318        
319               public boolean isAvailable( final String pResourceName ) {
320                   return sources.containsKey(pResourceName);
321               }
322            };
323        
324            final MemoryResourceStore store = new MemoryResourceStore();
325            final CompilationResult result = compiler.compile(
326                   new String[] {
327                           "jci/Simple.java"
328                   }, reader, store);
329        
330            assertEquals("Unexpected errors(s): " + toString(result.getErrors()), 0, result.getErrors().length);
331        
332            final byte[] clazzBytes = store.read("jci/Simple.class");
333            assertNotNull("Expected to find jci/Simple.class", clazzBytes);
334            assertTrue(clazzBytes.length > 0);
335    
336            final byte[] additionalTopLevelBytes = store.read("jci/AdditionalTopLevel.class");
337            assertNotNull("Expected to find jci/AdditionalTopLevel.class", additionalTopLevelBytes);
338            assertTrue(additionalTopLevelBytes.length > 0);
339    
340            assertEquals("Unexpected warning(s): " + toString(result.getWarnings()), 0, result.getWarnings().length);
341        }
342    
343        public final String toString( final CompilationProblem[] pProblems ) {
344            final StringBuilder sb = new StringBuilder();
345    
346            for (CompilationProblem problem : pProblems) {
347                sb.append(problem.getMessage()).append(", ");
348            }
349    
350            return sb.toString();
351        }
352    
353    }