Changeset 3966
- Timestamp:
- 28/09/08 20:49:05 (3 years ago)
- Files:
-
- trunk/build.properties (modified) (1 diff)
- trunk/build.xml (modified) (2 diffs)
- trunk/ivy.xml (modified) (3 diffs)
- trunk/src/main/java/org/sarugo/xtc/Resolver.java (modified) (1 diff)
- trunk/src/main/java/org/sarugo/xtc/TemplateFactory.java (modified) (4 diffs)
- trunk/src/main/java/org/sarugo/xtc/compiler/Compiler.java (modified) (1 diff)
- trunk/src/main/java/org/sarugo/xtc/compiler/ReflectionUtil.java (modified) (2 diffs)
- trunk/src/main/java/org/sarugo/xtc/compiler/SAXCompiler.java (modified) (2 diffs)
- trunk/src/main/java/org/sarugo/xtc/compiler/TagLibraryConfig.java (modified) (4 diffs)
- trunk/src/main/java/org/sarugo/xtc/impl/DefaultTemplateFactory.java (modified) (2 diffs)
- trunk/src/main/java/org/sarugo/xtc/osgi (added)
- trunk/src/main/java/org/sarugo/xtc/osgi/Activator.java (added)
- trunk/src/main/java/org/sarugo/xtc/osgi/OsgiResolver.java (added)
- trunk/src/main/java/org/sarugo/xtc/restlet/fop/FOPRepresentation.java (modified) (2 diffs)
- trunk/src/main/java/org/sarugo/xtc/servlet/ServletResolver.java (modified) (2 diffs)
- trunk/src/main/java/org/sarugo/xtc/util/Classpath.java (modified) (3 diffs)
- trunk/src/main/resources/META-INF/MANIFEST.MF (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/build.properties
r3739 r3966 1 1 project.name=xtc 2 project.rev=0. 4.42 project.rev=0.5 3 3 project.status=release trunk/build.xml
r3739 r3966 28 28 <exclude name="org/sarugo/xtc/restlet/**/*.class" /> 29 29 </fileset> 30 <fileset dir="${build.dir}/main/resources" /> 30 <fileset dir="${build.dir}/main/resources"> 31 <exclude name="META-INF/MANIFEST.MF" /> 32 </fileset> 31 33 </jar> 32 34 <jar destfile="${dist.dir}/${project.name}-restlet-${build.rev}.jar"> … … 40 42 </fileset> 41 43 </jar> 44 <ivy:retrieve pattern="${build.dir}/main/osgi/[artifact]-[revision].[ext]" conf="osgi" useOrigin="true" /> 45 <jar destfile="${dist.dir}/${project.name}-osgi-${build.rev}.jar" filesetmanifest="merge"> 46 <fileset dir="${build.dir}/main/java" /> 47 <fileset dir="${build.dir}/main/resources" /> 48 <fileset dir="${build.dir}/main/osgi" /> 49 </jar> 42 50 <!-- Use ivy to copy the runtime dependencies to distribution directory --> 43 51 <ivy:retrieve pattern="${dist.dir}/[artifact]-[revision].[ext]" conf="default" useOrigin="true" /> trunk/ivy.xml
r3739 r3966 7 7 <conf name="restlet" description="XTC-Restlet integration" extends="default"/> 8 8 <conf name="fop" description="Apache FOP integration" extends="restlet"/> 9 <conf name="osgi" description="OSGi Bundle version"/> 9 10 <conf name="compile" visibility="private" extends="default,restlet,fop"/> 10 11 <conf name="test" visibility="private" extends="compile"/> … … 14 15 <artifact name="${project.name}-restlet" conf="restlet" /> 15 16 <artifact name="${project.name}-fop" conf="fop" /> 17 <artifact name="${project.name}-osgi" conf="osgi" /> 16 18 </publications> 17 19 <dependencies> 18 <dependency org="de.odysseus.juel" name="juel" rev="2.1.0" conf="default "/>19 <dependency org="org.restlet" name="org.restlet" rev="1.1- M2" conf="restlet,compile->default"/>20 <dependency org="com.noelios.restlet" name="com.noelios.restlet.ext. simple" rev="1.1-M2" conf="compile->default"/>20 <dependency org="de.odysseus.juel" name="juel" rev="2.1.0" conf="default,osgi->default"/> 21 <dependency org="org.restlet" name="org.restlet" rev="1.1-RC1" conf="restlet,compile->default"/> 22 <dependency org="com.noelios.restlet" name="com.noelios.restlet.ext.jetty" rev="1.1-RC1" conf="compile->default"/> 21 23 <dependency org="javax.servlet" name="servlet-api" rev="2.5" conf="compile->default" /> 22 <dependency org="com.noelios.restlet" name="com.noelios.restlet.ext.net" rev="1.1- M2" conf="test->default"/>24 <dependency org="com.noelios.restlet" name="com.noelios.restlet.ext.net" rev="1.1-RC1" conf="test->default"/> 23 25 <dependency org="junit" name="junit" rev="3.8.1" conf="test->default"/> 24 26 <dependency org="xmlunit" name="xmlunit" rev="1.0" conf="test->default"/> … … 26 28 <!-- TODO exclude un-needed dependencies --> 27 29 </dependency> 30 <dependency org="org.eclipse" name="osgi" rev="3.4.0.v20080605-1900" conf="compile->default"/> 28 31 </dependencies> 29 32 </ivy-module> trunk/src/main/java/org/sarugo/xtc/Resolver.java
r3011 r3966 1 1 package org.sarugo.xtc; 2 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.net.JarURLConnection; 3 7 import java.net.URL; 8 import java.net.URLConnection; 9 import java.util.Arrays; 10 import java.util.Collection; 11 import java.util.Enumeration; 12 import java.util.HashSet; 13 import java.util.List; 14 import java.util.Set; 15 import java.util.jar.JarEntry; 16 import java.util.jar.JarFile; 4 17 5 18 /** 6 * The resolver is used by a {@link TemplateFactory} to load resources.19 * The resolver is used to load resources and classes. 7 20 * 8 * The default resolver for the default factory uses the class loader.21 * The default resolver for uses the available class loaders. 9 22 * 10 23 * @author Michael Terrington 11 24 */ 12 public interfaceResolver {25 public class Resolver { 13 26 14 public URL resolveUrl(String path); 27 private ClassLoader userClassLoader; 28 29 public URL getResource(String name) { 30 URL result = null; 31 for (ClassLoader cl : getClassLoaders()) { 32 if (cl == null) 33 continue; 34 result = cl.getResource(name); 35 if (result != null) 36 break; 37 } 38 return result; 39 } 40 41 public InputStream getResourceAsStream(String name) { 42 InputStream result = null; 43 for (ClassLoader cl : getClassLoaders()) { 44 if (cl == null) 45 continue; 46 result = cl.getResourceAsStream(name); 47 if (result != null) 48 break; 49 } 50 return result; 51 } 52 53 public Collection<URL> search(String prefix, String suffix) 54 throws IOException { 55 Set<URL> results = new HashSet<URL>(); 56 for (ClassLoader cl : getClassLoaders()) { 57 if (cl == null) 58 continue; 59 search(results, cl, prefix, suffix); 60 } 61 return results; 62 } 63 64 public Class<?> loadClass(String name) throws ClassNotFoundException { 65 Class<?> result = null; 66 try { 67 result = Class.forName(name); 68 } catch (ClassNotFoundException e) { 69 // ignore 70 } 71 for (ClassLoader cl : getClassLoaders()) { 72 if (cl == null) 73 continue; 74 try { 75 result = cl.loadClass(name); 76 break; 77 } catch (ClassNotFoundException e) { 78 // ignore 79 } 80 } 81 if (result == null) { 82 throw new ClassNotFoundException(name); 83 } 84 return result; 85 } 86 87 public void setUserClassLoader(ClassLoader cl) { 88 this.userClassLoader = cl; 89 } 90 91 protected List<ClassLoader> getClassLoaders() { 92 return Arrays.asList(userClassLoader, Thread.currentThread() 93 .getContextClassLoader(), getClass().getClassLoader(), 94 ClassLoader.getSystemClassLoader()); 95 } 96 97 protected URL localise(URL url) { 98 return url; 99 } 100 101 private void search(Collection<URL> results, ClassLoader cl, String prefix, 102 String suffix) throws IOException { 103 Enumeration<URL> e = cl.getResources(prefix); 104 URL url; 105 URLConnection conn; 106 JarFile jarFile; 107 while (e.hasMoreElements()) { 108 url = localise((URL) e.nextElement()); 109 conn = url.openConnection(); 110 conn.setUseCaches(false); 111 conn.setDefaultUseCaches(false); 112 if (conn instanceof JarURLConnection) { 113 jarFile = ((JarURLConnection) conn).getJarFile(); 114 } else { 115 jarFile = getAlternativeJarFile(url); 116 } 117 if (jarFile != null) { 118 searchJar(cl, results, jarFile, prefix, suffix); 119 } else { 120 searchDir(results, new File(url.getFile()), suffix); 121 } 122 } 123 } 124 125 private static void searchDir(Collection<URL> result, File file, 126 String suffix) throws IOException { 127 if (file.exists() && file.isDirectory()) { 128 File[] fc = file.listFiles(); 129 String path; 130 for (int i = 0; i < fc.length; i++) { 131 path = fc[i].getAbsolutePath(); 132 if (fc[i].isDirectory()) { 133 searchDir(result, fc[i], suffix); 134 } else if (path.endsWith(suffix)) { 135 // result.add(new URL("file:/" + path)); 136 result.add(fc[i].toURI().toURL()); 137 } 138 } 139 } 140 } 141 142 /** 143 * For URLs to JARs that do not use JarURLConnection - allowed by the 144 * servlet spec - attempt to produce a JarFile object all the same. Known 145 * servlet engines that function like this include Weblogic and OC4J. This 146 * is not a full solution, since an unpacked WAR or EAR will not have JAR 147 * "files" as such. 148 */ 149 private static JarFile getAlternativeJarFile(URL url) throws IOException { 150 String urlFile = url.getFile(); 151 // Trim off any suffix - which is prefixed by "!/" on Weblogic 152 int separatorIndex = urlFile.indexOf("!/"); 153 154 // OK, didn't find that. Try the less safe "!", used on OC4J 155 if (separatorIndex == -1) { 156 separatorIndex = urlFile.indexOf('!'); 157 } 158 159 if (separatorIndex != -1) { 160 String jarFileUrl = urlFile.substring(0, separatorIndex); 161 // And trim off any "file:" prefix. 162 if (jarFileUrl.startsWith("file:")) { 163 jarFileUrl = jarFileUrl.substring("file:".length()); 164 } 165 return new JarFile(jarFileUrl); 166 } 167 return null; 168 } 169 170 private static void searchJar(ClassLoader cl, Collection<URL> result, 171 JarFile file, String prefix, String suffix) throws IOException { 172 Enumeration<JarEntry> e = file.entries(); 173 JarEntry entry; 174 String name; 175 while (e.hasMoreElements()) { 176 try { 177 entry = e.nextElement(); 178 } catch (Throwable t) { 179 continue; 180 } 181 name = entry.getName(); 182 if (name.startsWith(prefix) && name.endsWith(suffix)) { 183 Enumeration<URL> e2 = cl.getResources(name); 184 while (e2.hasMoreElements()) { 185 result.add(e2.nextElement()); 186 } 187 } 188 } 189 } 15 190 16 191 } trunk/src/main/java/org/sarugo/xtc/TemplateFactory.java
r3011 r3966 31 31 public abstract class TemplateFactory { 32 32 33 private static volatile Resolver resolver = new Resolver(); 34 33 35 private static ThreadLocal<TemplateFactory> instance = new ThreadLocal<TemplateFactory>(); 34 36 … … 38 40 * Return a Template instance as specified by the file at the passed URI. 39 41 * The {@link DefaultTemplateFactory default implementation} of this class 40 * resolves URI's beginning with "/" using the classloader. 42 * resolves URI's beginning with "/" using the 43 * {@link #setResolver(Resolver) resolver}. 41 44 * 42 45 * @param uri … … 52 55 public abstract Template getTemplate(String uri) throws IOException, 53 56 TemplateException, ELException; 57 58 /** 59 * Specifies the period after which templates should be checked for changes. 60 * 61 * @param refreshPeriod 62 * length of time in milliseconds. 63 */ 64 public abstract void setRefreshPeriod(long refreshPeriod); 54 65 55 66 /** … … 85 96 * @param resolver 86 97 */ 87 public abstract void setResolver(Resolver resolver); 98 public static void setResolver(Resolver resolver) { 99 TemplateFactory.resolver = resolver; 100 } 101 102 public static Resolver getResolver() { 103 return resolver; 104 } 88 105 89 106 } trunk/src/main/java/org/sarugo/xtc/compiler/Compiler.java
r2915 r3966 145 145 if (type != null) { 146 146 try { 147 return Class.forName(type, true, 148 Thread.currentThread().getContextClassLoader()) 147 return TemplateFactory.getResolver().loadClass(type) 149 148 .newInstance(); 150 149 } catch (Throwable t) { trunk/src/main/java/org/sarugo/xtc/compiler/ReflectionUtil.java
r2684 r3966 17 17 import java.lang.reflect.Array; 18 18 import java.util.Arrays; 19 20 import org.sarugo.xtc.TemplateFactory; 19 21 20 22 /** … … 50 52 if (name.endsWith("[]")) { 51 53 String nc = name.substring(0, name.length() - 2); 52 c = Class.forName(nc, true, Thread.currentThread().getContextClassLoader());54 c = TemplateFactory.getResolver().loadClass(nc); 53 55 c = Array.newInstance(c, 0).getClass(); 54 56 } else { 55 c = Class.forName(name, true, Thread.currentThread().getContextClassLoader());57 c = TemplateFactory.getResolver().loadClass(name); 56 58 } 57 59 } trunk/src/main/java/org/sarugo/xtc/compiler/SAXCompiler.java
r2915 r3966 27 27 import javax.xml.parsers.SAXParserFactory; 28 28 29 import org.sarugo.xtc.TemplateFactory; 29 30 import org.sarugo.xtc.TemplateException; 30 31 import org.sarugo.xtc.TemplateHandler; … … 151 152 return new InputSource(systemId); 152 153 }*/ 153 URL url = Thread.currentThread().getContextClassLoader() 154 .getResource(dtd); 154 URL url = TemplateFactory.getResolver().getResource(dtd); 155 155 return new InputSource(url.toString()); 156 156 } trunk/src/main/java/org/sarugo/xtc/compiler/TagLibraryConfig.java
r2915 r3966 19 19 import java.lang.reflect.Method; 20 20 import java.net.URL; 21 import java.util.Collection; 21 22 import java.util.logging.Level; 22 23 import java.util.logging.Logger; … … 26 27 import javax.xml.parsers.SAXParserFactory; 27 28 29 import org.sarugo.xtc.TemplateFactory; 28 30 import org.sarugo.xtc.tag.AbstractTagLibrary; 29 31 import org.sarugo.xtc.tag.TagHandler; … … 239 241 if ("-//Sarugo Pty. Ltd.//DTD XTC Taglib 1.0//EN" 240 242 .equals(publicId)) { 241 URL url = T hread.currentThread().getContextClassLoader()243 URL url = TemplateFactory.getResolver() 242 244 .getResource("xtc-taglib_1_0.dtd"); 243 245 return new InputSource(url.toExternalForm()); … … 316 318 317 319 public void loadImplicit(Compiler compiler) throws IOException { 318 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 319 URL[] urls = Classpath.search(cl, "META-INF/", SUFFIX); 320 for (int i = 0; i < urls.length; i++) { 320 Collection<URL> urls = TemplateFactory.getResolver().search("META-INF/", SUFFIX); 321 for (URL url: urls) { 321 322 try { 322 compiler.addTagLibrary(create(url s[i]));323 log.info("Added Library from: " + url s[i]);323 compiler.addTagLibrary(create(url)); 324 log.info("Added Library from: " + url); 324 325 } catch (Exception e) { 325 log.log(Level.SEVERE, "Error Loading Library: " + url s[i], e);326 log.log(Level.SEVERE, "Error Loading Library: " + url, e); 326 327 } 327 328 } trunk/src/main/java/org/sarugo/xtc/impl/DefaultTemplateFactory.java
r3472 r3966 49 49 private Map relativeLocations; 50 50 51 private Resolver resolver;52 53 51 private long refreshPeriod; 54 52 55 53 public DefaultTemplateFactory() throws IOException { 56 this(Compiler.getInstance() , new ClassLoaderResolver());57 } 58 59 public DefaultTemplateFactory(Compiler compiler , Resolver resolver)54 this(Compiler.getInstance()); 55 } 56 57 public DefaultTemplateFactory(Compiler compiler) 60 58 throws IOException { 61 this(compiler, resolver, -1); 62 } 63 64 public DefaultTemplateFactory(Compiler compiler, Resolver resolver, 65 long refreshPeriod) { 59 this(compiler, -1); 60 } 61 62 public DefaultTemplateFactory(Compiler compiler, long refreshPeriod) { 66 63 ParameterCheck.notNull("compiler", compiler); 67 ParameterCheck.notNull("resolver", resolver);68 64 this.compiler = compiler; 69 65 this.templates = new HashMap(); 70 66 this.relativeLocations = new HashMap(); 71 setResolver(resolver);72 // this.location = url;73 log.fine("Using ResourceResolver: " + resolver);74 67 this.refreshPeriod = (refreshPeriod > 0) ? refreshPeriod * 1000 : -1; 75 68 log.fine("Using Refresh Period: " + this.refreshPeriod); 76 }77 78 public void setResolver(Resolver resolver) {79 this.resolver = resolver;80 69 } 81 70 … … 110 99 public URL resolveURL(URL source, String path) throws IOException { 111 100 if (path.startsWith("/")) { 112 URL url = this.resolver.resolveUrl(path);101 URL url = getResolver().getResource(path); 113 102 if (url == null) { 114 103 throw new FileNotFoundException(path trunk/src/main/java/org/sarugo/xtc/restlet/fop/FOPRepresentation.java
r3746 r3966 24 24 import org.restlet.data.MediaType; 25 25 import org.sarugo.xtc.Template; 26 import org.sarugo.xtc.TemplateFactory; 26 27 import org.sarugo.xtc.restlet.TemplateRepresentation; 27 28 … … 43 44 if (href.startsWith("clap:")) { 44 45 String resource; 45 ClassLoader loader; 46 if (href.startsWith("clap://class/")) { 47 resource = href.substring(13); 48 loader = getClass().getClassLoader(); 49 } else { 46 if (!href.startsWith("clap://class/")) { 50 47 throw new TransformerException("Bad URI " + href); 51 48 } 52 URL url = loader.getResource(resource); 53 InputStream is = loader.getResourceAsStream(resource); 49 resource = href.substring(13); 50 URL url = TemplateFactory.getResolver().getResource(resource); 51 InputStream is = TemplateFactory.getResolver().getResourceAsStream(resource); 54 52 if (url != null) { 55 53 return new StreamSource(is, url.toExternalForm()); trunk/src/main/java/org/sarugo/xtc/servlet/ServletResolver.java
r3011 r3966 8 8 import org.sarugo.xtc.Resolver; 9 9 10 public class ServletResolver implements Resolver {10 public class ServletResolver extends Resolver { 11 11 12 12 private ServletContext servletContext; … … 16 16 } 17 17 18 public URL resolveUrl(String path) { 18 @Override 19 public URL getResource(String name) { 19 20 try { 20 return servletContext.getResource( path);21 return servletContext.getResource(name); 21 22 } catch (MalformedURLException e) { 22 23 return null; trunk/src/main/java/org/sarugo/xtc/util/Classpath.java
r2783 r3966 45 45 String providerClassName = null; 46 46 47 // Try the default classloader 48 ClassLoader cl = TemplateFactory.class.getClassLoader(); 49 URL configURL = cl.getResource(providerResource); 50 51 if (configURL == null) { 52 // Try the current thread's classloader 53 cl = Thread.currentThread().getContextClassLoader(); 54 configURL = cl.getResource(providerResource); 55 } 56 57 if (configURL == null) { 58 // Try the system classloader 59 cl = ClassLoader.getSystemClassLoader(); 60 configURL = cl.getResource(providerResource); 61 } 47 URL configURL = TemplateFactory.getResolver().getResource(providerResource); 62 48 63 49 if (configURL != null) { … … 90 76 // Instantiate the provider 91 77 if (providerClassName != null) { 92 return Class.forName(providerClassName).newInstance();78 return TemplateFactory.getResolver().loadClass(providerClassName).newInstance(); 93 79 } else { 94 80 return null; … … 96 82 } 97 83 98 public static URL[] search(String prefix, String suffix) throws IOException {99 return search(Thread.currentThread().getContextClassLoader(), prefix,100 suffix);101 }102 103 public static URL[] search(ClassLoader cl, String prefix, String suffix)104 throws IOException {105 Enumeration<URL> e = cl.getResources(prefix);106 Set<URL> all = new HashSet<URL>();107 URL url;108 URLConnection conn;109 JarFile jarFile;110 while (e.hasMoreElements()) {111 url = (URL) e.nextElement();112 conn = url.openConnection();113 conn.setUseCaches(false);114 conn.setDefaultUseCaches(false);115 if (conn instanceof JarURLConnection) {116 jarFile = ((JarURLConnection) conn).getJarFile();117 } else {118 jarFile = getAlternativeJarFile(url);119 }120 if (jarFile != null) {121 searchJar(cl, all, jarFile, prefix, suffix);122 } else {123 searchDir(all, new File(url.getFile()), suffix);124 }125 }126 URL[] urlArray = (URL[]) all.toArray(new URL[all.size()]);127 return urlArray;128 }129 130 private static void searchDir(Set<URL> result, File file, String suffix)131 throws IOException {132 if (file.exists() && file.isDirectory()) {133 File[] fc = file.listFiles();134 String path;135 for (int i = 0; i < fc.length; i++) {136 path = fc[i].getAbsolutePath();137 if (fc[i].isDirectory()) {138 searchDir(result, fc[i], suffix);139 } else if (path.endsWith(suffix)) {140 // result.add(new URL("file:/" + path));141 result.add(fc[i].toURL());142 }143 }144 }145 }146 147 /**148 * For URLs to JARs that do not use JarURLConnection - allowed by the149 * servlet spec - attempt to produce a JarFile object all the same. Known150 * servlet engines that function like this include Weblogic and OC4J. This151 * is not a full solution, since an unpacked WAR or EAR will not have JAR152 * "files" as such.153 */154 private static JarFile getAlternativeJarFile(URL url) throws IOException {155 String urlFile = url.getFile();156 // Trim off any suffix - which is prefixed by "!/" on Weblogic157 int separatorIndex = urlFile.indexOf("!/");158 159 // OK, didn't find that. Try the less safe "!", used on OC4J160 if (separatorIndex == -1) {161 separatorIndex = urlFile.indexOf('!');162 }163 164 if (separatorIndex != -1) {165 String jarFileUrl = urlFile.substring(0, separatorIndex);166 // And trim off any "file:" prefix.167 if (jarFileUrl.startsWith("file:")) {168 jarFileUrl = jarFileUrl.substring("file:".length());169 }170 return new JarFile(jarFileUrl);171 }172 return null;173 }174 175 private static void searchJar(ClassLoader cl, Set<URL> result,176 JarFile file, String prefix, String suffix) throws IOException {177 Enumeration e = file.entries();178 JarEntry entry;179 String name;180 while (e.hasMoreElements()) {181 try {182 entry = (JarEntry) e.nextElement();183 } catch (Throwable t) {184 continue;185 }186 name = entry.getName();187 if (name.startsWith(prefix) && name.endsWith(suffix)) {188 Enumeration<URL> e2 = cl.getResources(name);189 while (e2.hasMoreElements()) {190 result.add(e2.nextElement());191 }192 }193 }194 }195 84 196 85 }
