001 /* 002 * Copyright (C) 2006-2007 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package org.codehaus.gmaven.runtime.v1_7; 018 019 import groovy.lang.GroovyClassLoader; 020 import org.codehaus.gmaven.feature.Component; 021 import org.codehaus.gmaven.feature.support.FeatureSupport; 022 import org.codehaus.gmaven.runtime.ClassCompiler; 023 import org.codehaus.gmaven.runtime.support.CompilerSupport; 024 import org.codehaus.groovy.control.CompilationUnit; 025 import org.codehaus.groovy.control.CompilerConfiguration; 026 import org.codehaus.groovy.tools.GroovyClass; 027 028 import java.net.URL; 029 import java.security.CodeSource; 030 import java.util.Iterator; 031 import java.util.List; 032 033 /** 034 * Provides the class compilation feature. 035 * 036 * @version $Id: ClassCompilerFeature.java 91 2010-07-05 21:06:12Z user57 $ 037 * @author <a href="mailto:jason@planet57.com">Jason Dillon</a> 038 */ 039 public class ClassCompilerFeature 040 extends FeatureSupport 041 { 042 public ClassCompilerFeature() { 043 super(ClassCompiler.KEY); 044 } 045 046 @Override 047 protected Component doCreate() throws Exception { 048 return new ClassCompilerImpl(); 049 } 050 051 // 052 // ClassCompilerImpl 053 // 054 055 private class ClassCompilerImpl 056 extends CompilerSupport 057 implements ClassCompiler, ClassCompiler.Keys 058 { 059 private final CompilerConfiguration cc = new CompilerConfiguration(); 060 061 private URL[] classPath; 062 063 private ClassCompilerImpl() throws Exception { 064 super(ClassCompilerFeature.this); 065 } 066 067 private void configure() { 068 cc.setVerbose(config.get(VERBOSE, false)); 069 070 cc.setDebug(config.get(DEBUG, false)); 071 072 if (config.contains(TOLERANCE)) { 073 cc.setTolerance(config.get(TOLERANCE, 0)); 074 } 075 076 if (config.contains(TARGET_BYTECODE)) { 077 cc.setTargetBytecode(config.get(TARGET_BYTECODE, (String)null)); 078 } 079 080 if (config.contains(SCRIPT_BASE_CLASSNAME)) { 081 cc.setScriptBaseClass(config.get(SCRIPT_BASE_CLASSNAME, (String)null)); 082 } 083 084 if (config.contains(DEFAULT_SCRIPT_EXTENSION)) { 085 cc.setDefaultScriptExtension(config.get(DEFAULT_SCRIPT_EXTENSION, (String)null)); 086 } 087 088 if (config.contains(WARNING_LEVEL)) { 089 cc.setTolerance(config.get(WARNING_LEVEL, 0)); 090 } 091 092 if (config.contains(SOURCE_ENCODING)) { 093 cc.setSourceEncoding(config.get(SOURCE_ENCODING, (String)null)); 094 } 095 } 096 097 public int compile() throws Exception { 098 if (sources.isEmpty()) { 099 log.debug("No sources added to compile; skipping"); 100 101 return 0; 102 } 103 104 configure(); 105 cc.setTargetDirectory(getTargetDirectory().getCanonicalPath()); 106 107 // 108 // NOTE: Do not use the CL from this class or it will mess up resolution 109 // when using classes from groovy* which depend on other artifacts, 110 // also don't really want to pollute the classpath with our dependencies. 111 // 112 113 ClassLoader parent = ClassLoader.getSystemClassLoader(); 114 115 GroovyClassLoader gcl = new GroovyClassLoader(parent, cc); 116 117 log.debug("Classpath:"); 118 119 // Append each URL to the GCL 120 URL[] classpath = getClassPath(); 121 122 for (int i=0; i<classpath.length; i++) { 123 gcl.addURL(classpath[i]); 124 125 log.debug(" {}", classpath[i]); 126 } 127 128 // 129 // TODO: See if we should set the CodeSource to something? 130 // 131 132 CodeSource security = null; 133 GroovyClassLoader transformLoader = new GroovyClassLoader(getClass().getClassLoader()); 134 for (int i=0; i<classpath.length; i++) { 135 transformLoader.addURL(classpath[i]); 136 } 137 138 CompilationUnit cu = new CompilationUnit(cc, security, gcl, transformLoader); 139 log.debug("Compiling {} sources", String.valueOf(sources.size())); 140 141 for (Iterator iter = sources.iterator(); iter.hasNext();) { 142 URL url = (URL) iter.next(); 143 log.debug(" {}", url); 144 145 cu.addSource(url); 146 } 147 148 cu.compile(); 149 150 List classes = cu.getClasses(); 151 152 if (log.isDebugEnabled()) { 153 log.debug("Compiled {} classes:", String.valueOf(classes.size())); 154 155 for (Iterator iter = classes.iterator(); iter.hasNext();) { 156 log.debug(" {}", ((GroovyClass)iter.next()).getName()); 157 } 158 } 159 160 return classes.size(); 161 } 162 } 163 }