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_5; 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 protected Component doCreate() throws Exception { 049 return new ClassFactoryImpl(); 050 } 051 052 // 053 // ClassFactoryImpl 054 // 055 056 private class ClassFactoryImpl 057 extends ComponentSupport 058 implements ClassFactory 059 { 060 private ClassFactoryImpl() { 061 super(ClassFactoryFeature.this); 062 } 063 064 public Class create(final ClassSource classSource, final ClassLoader classLoader, final ResourceLoader resourceLoader) throws Exception { 065 assert classSource != null; 066 assert classLoader != null; 067 // resourceLoader can be null 068 069 GroovyClassLoader groovyClassLoader = createGroovyClassLoader(classLoader, resourceLoader); 070 071 GroovyCodeSource codeSource = createGroovyCodeSource(classSource); 072 073 return groovyClassLoader.parseClass(codeSource); 074 } 075 076 public Class create(final ClassSource classSource, final ClassLoader classLoader) throws Exception { 077 return create(classSource, classLoader, null); 078 } 079 080 public Class create(final String className, final ClassLoader classLoader, ResourceLoader resourceLoader) throws Exception { 081 assert className != null; 082 assert classLoader != null; 083 // resourceLoader can be null 084 085 if (resourceLoader == null) { 086 resourceLoader = new ResourceLoaderImpl(classLoader); 087 } 088 089 URL source = resourceLoader.loadResource(className); 090 091 if (source == null) { 092 throw new ComponentException("Missing source for: " + className); 093 } 094 095 return create(new ClassSource(source), classLoader, resourceLoader); 096 } 097 098 public Class create(final String className, final ClassLoader classLoader) throws Exception { 099 return create(className, classLoader, null); 100 } 101 102 private GroovyClassLoader createGroovyClassLoader(final ClassLoader classLoader, final ResourceLoader resourceLoader) { 103 assert classLoader != null; 104 // resourceLoader can be null 105 106 GroovyClassLoader groovyClassLoader = new GroovyClassLoader(classLoader); 107 108 groovyClassLoader.setResourceLoader(createGroovyResourceLoader(classLoader, resourceLoader)); 109 110 return groovyClassLoader; 111 } 112 113 private GroovyResourceLoader createGroovyResourceLoader(final ClassLoader classLoader, ResourceLoader resourceLoader) { 114 assert classLoader != null; 115 // resourceLoader can be null 116 117 if (resourceLoader == null) { 118 resourceLoader = new ResourceLoaderImpl(classLoader); 119 } 120 121 return new GroovyResourceLoaderAdapter(resourceLoader); 122 } 123 124 private GroovyCodeSource createGroovyCodeSource(final ClassSource source) throws IOException { 125 assert source != null; 126 127 int count = 0; 128 129 if (source.url != null) { 130 count++; 131 } 132 133 if (source.file != null) { 134 count++; 135 } 136 137 if (source.body != null) { 138 count++; 139 } 140 141 if (count == 0) { 142 throw new ComponentException("Invalid class source; must define a URL, File or Body: " + source); 143 } 144 145 if (count != 1) { 146 throw new ComponentException("Invalid class source; only one of URL, File or Body is allowed: " + source); 147 } 148 149 if (source.url != null) { 150 return new GroovyCodeSource(source.url); 151 } 152 153 if (source.file != null) { 154 return new GroovyCodeSource(source.file); 155 } 156 157 if (source.body != null) { 158 return new GroovyCodeSource(source.body.input, source.body.name, source.body.codeBase); 159 } 160 161 throw new InternalError(); 162 } 163 } 164 165 // 166 // GroovyResourceLoaderAdapter 167 // 168 169 private class GroovyResourceLoaderAdapter 170 implements GroovyResourceLoader 171 { 172 private final ResourceLoader loader; 173 174 public GroovyResourceLoaderAdapter(final ResourceLoader loader) { 175 assert loader != null; 176 177 this.loader = loader; 178 } 179 180 public URL loadGroovySource(final String name) throws MalformedURLException { 181 return loader.loadResource(name); 182 } 183 } 184 }