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.drools.commons.jci.compilers;
019:
020: import java.io.BufferedReader;
021: import java.io.IOException;
022: import java.io.Reader;
023: import java.io.StringReader;
024: import java.util.ArrayList;
025: import java.util.Collection;
026: import java.util.HashMap;
027: import java.util.Iterator;
028: import java.util.Map;
029:
030: import org.codehaus.janino.ClassLoaderIClassLoader;
031: import org.codehaus.janino.CompileException;
032: import org.codehaus.janino.DebuggingInformation;
033: import org.codehaus.janino.Descriptor;
034: import org.codehaus.janino.IClass;
035: import org.codehaus.janino.IClassLoader;
036: import org.codehaus.janino.Java;
037: import org.codehaus.janino.Location;
038: import org.codehaus.janino.Parser;
039: import org.codehaus.janino.Scanner;
040: import org.codehaus.janino.UnitCompiler;
041: import org.codehaus.janino.WarningHandler;
042: import org.codehaus.janino.Scanner.LocatedException;
043: import org.codehaus.janino.UnitCompiler.ErrorHandler;
044: import org.codehaus.janino.util.ClassFile;
045: import org.drools.commons.jci.problems.CompilationProblem;
046: import org.drools.commons.jci.readers.ResourceReader;
047: import org.drools.commons.jci.stores.ResourceStore;
048: import org.drools.util.ClassUtils;
049:
050: /**
051: * @author art@gramlich-net.com
052: */
053: public final class JaninoJavaCompiler extends AbstractJavaCompiler {
054:
055: private class CompilingIClassLoader extends IClassLoader {
056:
057: private final Map types = new HashMap();
058: private final ResourceReader resourceReader;
059: private final Map classes;
060: private final Collection problems = new ArrayList();
061:
062: private CompilingIClassLoader(
063: final ResourceReader pResourceReader,
064: final Map pClasses, final ClassLoader classLoader) {
065: super (new ClassLoaderIClassLoader(classLoader));
066: resourceReader = pResourceReader;
067: classes = pClasses;
068: super .postConstruct();
069: }
070:
071: protected Collection getProblems() {
072: return problems;
073: }
074:
075: protected IClass findIClass(final String pType) {
076: final String className = Descriptor.toClassName(pType);
077: if (types.containsKey(pType)) {
078: return (IClass) types.get(pType);
079: }
080:
081: // FIXME: should not be tied to the extension
082: final String resourceNameFromClass = className.replace('.',
083: '/')
084: + ".java";
085:
086: final byte[] content = resourceReader
087: .getBytes(resourceNameFromClass);
088: if (content == null) {
089: return null;
090: }
091: final Reader reader = new BufferedReader(new StringReader(
092: new String(content)));
093: Scanner scanner = null;
094: try {
095: scanner = new Scanner(resourceNameFromClass, reader);
096: final Java.CompilationUnit unit = new Parser(scanner)
097: .parseCompilationUnit();
098: final UnitCompiler uc = new UnitCompiler(unit, this );
099: uc.setCompileErrorHandler(new ErrorHandler() {
100: public void handleError(final String pMessage,
101: final Location pOptionalLocation)
102: throws CompileException {
103: final CompilationProblem problem = new JaninoCompilationProblem(
104: pOptionalLocation, pMessage, true);
105: if (problemHandler != null) {
106: problemHandler.handle(problem);
107: }
108: problems.add(problem);
109: }
110: });
111: uc.setWarningHandler(new WarningHandler() {
112: public void handleWarning(final String pHandle,
113: final String pMessage,
114: final Location pOptionalLocation) {
115: final CompilationProblem problem = new JaninoCompilationProblem(
116: pOptionalLocation, pMessage, false);
117: if (problemHandler != null) {
118: problemHandler.handle(problem);
119: }
120: problems.add(problem);
121: }
122: });
123:
124: final ClassFile[] classFiles = uc
125: .compileUnit(DebuggingInformation.ALL);
126: for (int i = 0; i < classFiles.length; i++) {
127: classes.put(classFiles[i].getThisClassName(),
128: classFiles[i].toByteArray());
129: }
130: final IClass ic = uc.findClass(className);
131: if (null != ic) {
132: types.put(pType, ic);
133: }
134: return ic;
135: } catch (final LocatedException e) {
136: problems.add(new JaninoCompilationProblem(e));
137: } catch (final IOException e) {
138: problems.add(new JaninoCompilationProblem(
139: resourceNameFromClass, "IOException:"
140: + e.getMessage(), true));
141: } catch (final Exception e) {
142: problems.add(new JaninoCompilationProblem(
143: resourceNameFromClass, "Exception:"
144: + e.getMessage(), true));
145: } finally {
146: if (scanner != null) {
147: try {
148: scanner.close();
149: } catch (IOException e) {
150: throw new RuntimeException(
151: "IOException occured while compiling "
152: + className, e);
153: }
154: }
155: }
156: return null;
157: }
158: }
159:
160: public CompilationResult compile(final String[] pSourceNames,
161: final ResourceReader pResourceReader,
162: final ResourceStore pStore, final ClassLoader pClassLoader,
163: final JavaCompilerSettings pSettings) {
164:
165: final Map classFilesByName = new HashMap();
166:
167: final CompilingIClassLoader icl = new CompilingIClassLoader(
168: pResourceReader, classFilesByName, pClassLoader);
169: for (int i = 0; i < pSourceNames.length; i++) {
170: try {
171: icl.loadIClass(Descriptor.fromClassName(ClassUtils
172: .convertResourceToClassName(pSourceNames[i])));
173: } catch (final ClassNotFoundException e) {
174: // @TODO: if an exception is thrown here, how do we handle it?
175: e.printStackTrace();
176: }
177: }
178:
179: // Store all fully compiled classes
180: for (Iterator i = classFilesByName.entrySet().iterator(); i
181: .hasNext();) {
182: final Map.Entry entry = (Map.Entry) i.next();
183: final String clazzName = (String) entry.getKey();
184: pStore.write(ClassUtils
185: .convertClassToResourcePath(clazzName),
186: (byte[]) entry.getValue());
187: }
188:
189: final Collection problems = icl.getProblems();
190: final CompilationProblem[] result = new CompilationProblem[problems
191: .size()];
192: problems.toArray(result);
193: return new CompilationResult(result);
194: }
195:
196: public JavaCompilerSettings createDefaultSettings() {
197: // FIXME
198: return null;
199: }
200:
201: }
|