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_6; 018 019 import groovy.lang.GroovyClassLoader; 020 import groovy.lang.GroovyCodeSource; 021 import groovy.lang.GroovyResourceLoader; 022 import org.codehaus.gmaven.feature.Component; 023 import org.codehaus.gmaven.feature.ComponentException; 024 import org.codehaus.gmaven.feature.support.ComponentSupport; 025 import org.codehaus.gmaven.feature.support.FeatureSupport; 026 import org.codehaus.gmaven.runtime.ClassFactory; 027 import org.codehaus.gmaven.runtime.support.util.ResourceLoaderImpl; 028 import org.codehaus.gmaven.runtime.util.ClassSource; 029 import org.codehaus.gmaven.runtime.util.ResourceLoader; 030 031 import java.io.IOException; 032 import java.net.MalformedURLException; 033 import java.net.URL; 034 035 /** 036 * Provides the class factory feature. 037 * 038 * @version $Id: ClassFactoryFeature.java 52 2009-11-22 10:32:14Z user57 $ 039 * @author <a href="mailto:jason@planet57.com">Jason Dillon</a> 040 */ 041 public class ClassFactoryFeature 042 extends FeatureSupport 043 { 044 public ClassFactoryFeature() { 045 super(ClassFactory.KEY); 046 } 047 048 @Override 049 protected Component doCreate() throws Exception { 050 return new ClassFactoryImpl(); 051 } 052 053 // 054 // ClassFactoryImpl 055 // 056 057 private class ClassFactoryImpl 058 extends ComponentSupport 059 implements ClassFactory 060 { 061 private ClassFactoryImpl() { 062 super(ClassFactoryFeature.this); 063 } 064 065 public Class create(final ClassSource classSource, final ClassLoader classLoader, final ResourceLoader resourceLoader) throws Exception { 066 assert classSource != null; 067 assert classLoader != null; 068 // resourceLoader can be null 069 070 GroovyClassLoader groovyClassLoader = createGroovyClassLoader(classLoader, resourceLoader); 071 072 GroovyCodeSource codeSource = createGroovyCodeSource(classSource); 073 074 return groovyClassLoader.parseClass(codeSource); 075 } 076 077 public Class create(final ClassSource classSource, final ClassLoader classLoader) throws Exception { 078 return create(classSource, classLoader, null); 079 } 080 081 public Class create(final String className, final ClassLoader classLoader, ResourceLoader resourceLoader) throws Exception { 082 assert className != null; 083 assert classLoader != null; 084 // resourceLoader can be null 085 086 if (resourceLoader == null) { 087 resourceLoader = new ResourceLoaderImpl(classLoader); 088 } 089 090 URL source = resourceLoader.loadResource(className); 091 092 if (source == null) { 093 throw new ComponentException("Missing source for: " + className); 094 } 095 096 return create(new ClassSource(source), classLoader, resourceLoader); 097 } 098 099 public Class create(final String className, final ClassLoader classLoader) throws Exception { 100 return create(className, classLoader, null); 101 } 102 103 private GroovyClassLoader createGroovyClassLoader(final ClassLoader classLoader, final ResourceLoader resourceLoader) { 104 assert classLoader != null; 105 // resourceLoader can be null 106 107 GroovyClassLoader groovyClassLoader = new GroovyClassLoader(classLoader); 108 109 groovyClassLoader.setResourceLoader(createGroovyResourceLoader(classLoader, resourceLoader)); 110 111 return groovyClassLoader; 112 } 113 114 private GroovyResourceLoader createGroovyResourceLoader(final ClassLoader classLoader, ResourceLoader resourceLoader) { 115 assert classLoader != null; 116 // resourceLoader can be null 117 118 if (resourceLoader == null) { 119 resourceLoader = new ResourceLoaderImpl(classLoader); 120 } 121 122 return new GroovyResourceLoaderAdapter(resourceLoader); 123 } 124 125 private GroovyCodeSource createGroovyCodeSource(final ClassSource source) throws IOException { 126 assert source != null; 127 128 int count = 0; 129 130 if (source.url != null) { 131 count++; 132 } 133 134 if (source.file != null) { 135 count++; 136 } 137 138 if (source.body != null) { 139 count++; 140 } 141 142 if (count == 0) { 143 throw new ComponentException("Invalid class source; must define a URL, File or Body: " + source); 144 } 145 146 if (count != 1) { 147 throw new ComponentException("Invalid class source; only one of URL, File or Body is allowed: " + source); 148 } 149 150 if (source.url != null) { 151 return new GroovyCodeSource(source.url); 152 } 153 154 if (source.file != null) { 155 return new GroovyCodeSource(source.file); 156 } 157 158 if (source.body != null) { 159 return new GroovyCodeSource(source.body.input, source.body.name, source.body.codeBase); 160 } 161 162 throw new InternalError(); 163 } 164 } 165 166 // 167 // GroovyResourceLoaderAdapter 168 // 169 170 private class GroovyResourceLoaderAdapter 171 implements GroovyResourceLoader 172 { 173 private final ResourceLoader loader; 174 175 public GroovyResourceLoaderAdapter(final ResourceLoader loader) { 176 assert loader != null; 177 178 this.loader = loader; 179 } 180 181 public URL loadGroovySource(final String name) throws MalformedURLException { 182 return loader.loadResource(name); 183 } 184 } 185 }