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 groovy.lang.GroovyClassLoader; 021 022 import java.util.ArrayList; 023 import java.util.Collection; 024 import java.util.List; 025 026 import org.apache.commons.jci.problems.CompilationProblem; 027 import org.apache.commons.jci.readers.ResourceReader; 028 import org.apache.commons.jci.stores.ResourceStore; 029 import org.apache.commons.jci.utils.ConversionUtils; 030 import org.apache.commons.logging.Log; 031 import org.apache.commons.logging.LogFactory; 032 import org.codehaus.groovy.control.CompilationFailedException; 033 import org.codehaus.groovy.control.CompilationUnit; 034 import org.codehaus.groovy.control.CompilerConfiguration; 035 import org.codehaus.groovy.control.ErrorCollector; 036 import org.codehaus.groovy.control.MultipleCompilationErrorsException; 037 import org.codehaus.groovy.control.Phases; 038 import org.codehaus.groovy.control.SourceUnit; 039 import org.codehaus.groovy.control.messages.Message; 040 import org.codehaus.groovy.control.messages.WarningMessage; 041 import org.codehaus.groovy.tools.GroovyClass; 042 043 /** 044 * Groovy implementation of the JavaCompiler interface 045 * 046 * @author tcurdt 047 */ 048 public final class GroovyJavaCompiler extends AbstractJavaCompiler { 049 050 private final Log log = LogFactory.getLog(GroovyJavaCompiler.class); 051 private final GroovyJavaCompilerSettings defaultSettings; 052 053 public GroovyJavaCompiler() { 054 defaultSettings = new GroovyJavaCompilerSettings(new CompilerConfiguration()); 055 } 056 057 public CompilationResult compile( 058 final String[] pResourceNames, 059 final ResourceReader pReader, 060 final ResourceStore pStore, 061 final ClassLoader pClassLoader, 062 final JavaCompilerSettings pSettings 063 ) { 064 065 final CompilerConfiguration configuration = ((GroovyJavaCompilerSettings) pSettings).getCompilerConfiguration(); 066 final ErrorCollector collector = new ErrorCollector(configuration); 067 final GroovyClassLoader groovyClassLoader = new GroovyClassLoader(pClassLoader); 068 final CompilationUnit unit = new CompilationUnit(configuration, null, groovyClassLoader); 069 final SourceUnit[] source = new SourceUnit[pResourceNames.length]; 070 for (int i = 0; i < source.length; i++) { 071 final String resourceName = pResourceNames[i]; 072 source[i] = new SourceUnit( 073 ConversionUtils.convertResourceToClassName(resourceName), 074 new String(pReader.getBytes(resourceName)), // FIXME delay the read 075 configuration, 076 groovyClassLoader, 077 collector 078 ); 079 unit.addSource(source[i]); 080 } 081 082 final Collection<CompilationProblem> problems = new ArrayList<CompilationProblem>(); 083 084 try { 085 log.debug("compiling"); 086 unit.compile(Phases.CLASS_GENERATION); 087 088 @SuppressWarnings("unchecked") // Groovy library is not yet generic 089 final List<GroovyClass> classes = unit.getClasses(); 090 for (GroovyClass clazz : classes) { 091 final byte[] bytes = clazz.getBytes(); 092 pStore.write(ConversionUtils.convertClassToResourcePath(clazz.getName()), bytes); 093 } 094 } catch (final MultipleCompilationErrorsException e) { 095 final ErrorCollector col = e.getErrorCollector(); 096 @SuppressWarnings("unchecked") // Groovy library is not yet generic 097 final Collection<WarningMessage> warnings = col.getWarnings(); 098 if (warnings != null) { 099 for (WarningMessage warning : warnings) { 100 final CompilationProblem problem = new GroovyCompilationProblem(warning); 101 if (problemHandler != null) { 102 problemHandler.handle(problem); 103 } 104 problems.add(problem); 105 } 106 } 107 108 @SuppressWarnings("unchecked") // Groovy library is not yet generic 109 final Collection<Message> errors = col.getErrors(); 110 if (errors != null) { 111 for (Message message : errors) { 112 final CompilationProblem problem = new GroovyCompilationProblem(message); 113 if (problemHandler != null) { 114 problemHandler.handle(problem); 115 } 116 problems.add(problem); 117 } 118 } 119 } catch (CompilationFailedException e) { 120 throw new RuntimeException("no expected"); 121 } 122 123 final CompilationProblem[] result = new CompilationProblem[problems.size()]; 124 problems.toArray(result); 125 return new CompilationResult(result); 126 } 127 128 public JavaCompilerSettings createDefaultSettings() { 129 return defaultSettings; 130 } 131 }