View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.jci.compilers;
19  
20  import groovy.lang.GroovyClassLoader;
21  
22  import java.util.ArrayList;
23  import java.util.Collection;
24  import java.util.Iterator;
25  import java.util.List;
26  
27  import org.apache.commons.jci.problems.CompilationProblem;
28  import org.apache.commons.jci.readers.ResourceReader;
29  import org.apache.commons.jci.stores.ResourceStore;
30  import org.apache.commons.jci.utils.ConversionUtils;
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  import org.codehaus.groovy.control.CompilationFailedException;
34  import org.codehaus.groovy.control.CompilationUnit;
35  import org.codehaus.groovy.control.CompilerConfiguration;
36  import org.codehaus.groovy.control.ErrorCollector;
37  import org.codehaus.groovy.control.MultipleCompilationErrorsException;
38  import org.codehaus.groovy.control.Phases;
39  import org.codehaus.groovy.control.SourceUnit;
40  import org.codehaus.groovy.control.messages.Message;
41  import org.codehaus.groovy.control.messages.WarningMessage;
42  import org.codehaus.groovy.tools.GroovyClass;
43  
44  /**
45   * Groovy implementation of the JavaCompiler interface
46   * 
47   * @author tcurdt
48   */
49  public final class GroovyJavaCompiler extends AbstractJavaCompiler {
50  
51      private final Log log = LogFactory.getLog(GroovyJavaCompiler.class);
52      private final GroovyJavaCompilerSettings defaultSettings;
53      
54      public GroovyJavaCompiler() {
55          defaultSettings = new GroovyJavaCompilerSettings(new CompilerConfiguration());
56      }
57          
58      public CompilationResult compile(
59              final String[] pResourceNames,
60              final ResourceReader pReader,
61              final ResourceStore pStore,
62              final ClassLoader pClassLoader,
63              final JavaCompilerSettings pSettings
64              ) {
65  
66          final CompilerConfiguration configuration = ((GroovyJavaCompilerSettings) pSettings).getCompilerConfiguration();
67          final ErrorCollector collector = new ErrorCollector(configuration);
68          final GroovyClassLoader groovyClassLoader = new GroovyClassLoader(pClassLoader);
69          final CompilationUnit unit = new CompilationUnit(configuration, null, groovyClassLoader);
70          final SourceUnit[] source = new SourceUnit[pResourceNames.length];
71          for (int i = 0; i < source.length; i++) {
72              final String resourceName = pResourceNames[i];
73              source[i] = new SourceUnit(
74                      ConversionUtils.convertResourceToClassName(resourceName),
75                      new String(pReader.getBytes(resourceName)), // FIXME delay the read
76                      configuration,
77                      groovyClassLoader,
78                      collector
79                      );
80              unit.addSource(source[i]);
81          }
82          
83          final Collection problems = new ArrayList();
84  
85          try {
86              log.debug("compiling");
87              unit.compile(Phases.CLASS_GENERATION);
88              
89              final List classes = unit.getClasses();
90              for (final Iterator it = classes.iterator(); it.hasNext();) {
91                  final GroovyClass clazz = (GroovyClass) it.next();
92                  final byte[] bytes = clazz.getBytes();
93                  pStore.write(ConversionUtils.convertClassToResourcePath(clazz.getName()), bytes);
94              }
95          } catch (final MultipleCompilationErrorsException e) {
96              final ErrorCollector col = e.getErrorCollector();
97              final Collection warnings = col.getWarnings();
98              if (warnings != null) {
99                  for (final Iterator it = warnings.iterator(); it.hasNext();) {
100                     final WarningMessage warning = (WarningMessage) it.next();
101                     final CompilationProblem problem = new GroovyCompilationProblem(warning); 
102                     if (problemHandler != null) {
103                         problemHandler.handle(problem);
104                     }
105                     problems.add(problem);
106                 }
107             }
108 
109             final Collection errors = col.getErrors();
110             if (errors != null) {
111                 for (final Iterator it = errors.iterator(); it.hasNext();) {
112                     final Message message = (Message) it.next();
113                     final CompilationProblem problem = new GroovyCompilationProblem(message); 
114                     if (problemHandler != null) {
115                         problemHandler.handle(problem);
116                     }
117                     problems.add(problem);
118                 }
119             }
120         } catch (CompilationFailedException e) {
121             throw new RuntimeException("no expected");
122         }
123 
124         final CompilationProblem[] result = new CompilationProblem[problems.size()];
125         problems.toArray(result);
126         return new CompilationResult(result);
127     }
128 
129     public JavaCompilerSettings createDefaultSettings() {
130         return defaultSettings;
131     }
132 }