Author: pete.muir(a)jboss.org
Date: 2010-03-10 14:58:08 -0500 (Wed, 10 Mar 2010)
New Revision: 6035
Added:
extensions/trunk/src/main/java/org/jboss/weld/extensions/Resource.java
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/ResourceProducer.java
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/ResourceProvider.java
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/spi/
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/spi/ResourceLoader.java
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/spi/ResourceLoaderImpl.java
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/resources/
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/resources/ResourceClient.java
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/resources/ResourceLoaderTest.java
extensions/trunk/src/test/resources/com/
extensions/trunk/src/test/resources/com/acme/
extensions/trunk/src/test/resources/com/acme/foo1
Log:
Add resource loading to extensions
Added: extensions/trunk/src/main/java/org/jboss/weld/extensions/Resource.java
===================================================================
--- extensions/trunk/src/main/java/org/jboss/weld/extensions/Resource.java
(rev 0)
+++ extensions/trunk/src/main/java/org/jboss/weld/extensions/Resource.java 2010-03-10
19:58:08 UTC (rev 6035)
@@ -0,0 +1,32 @@
+package org.jboss.weld.extensions;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.enterprise.util.Nonbinding;
+import javax.inject.Qualifier;
+
+/**
+ * An injection point qualifier that may be used to specify a resource to inject
+ *
+ * @author Pete Muir
+ *
+ */
+@Retention(RUNTIME)
+@Target( { METHOD, TYPE, FIELD, PARAMETER })
+@Documented
+@Qualifier
+public @interface Resource
+{
+
+ @Nonbinding
+ String value();
+
+}
Property changes on:
extensions/trunk/src/main/java/org/jboss/weld/extensions/Resource.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Added:
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/ResourceProducer.java
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/ResourceProducer.java
(rev 0)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/ResourceProducer.java 2010-03-10
19:58:08 UTC (rev 6035)
@@ -0,0 +1,65 @@
+package org.jboss.weld.extensions.resources;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.net.URL;
+import java.util.Set;
+
+import javax.enterprise.inject.Disposes;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.inject.Inject;
+
+import org.jboss.weld.extensions.Resource;
+import org.jboss.weld.extensions.resources.spi.ResourceLoader;
+
+public class ResourceProducer
+{
+
+ private final ResourceLoader loader;
+
+ @Inject
+ private ResourceProducer(ResourceLoader loader)
+ {
+ this.loader = loader;
+ }
+
+ @Produces @Resource("")
+ protected InputStream loadResourceStream(InjectionPoint injectionPoint) throws
IOException
+ {
+ return loader.getResourceAsStream(getName(injectionPoint));
+ }
+
+ protected void closeResourceStream(@Disposes @Resource("") InputStream
inputStream) throws IOException
+ {
+ try
+ {
+ inputStream.close();
+ }
+ catch (IOException e)
+ {
+ // Nothing we can do about this
+ }
+ }
+
+ @Produces @Resource("")
+ protected URL loadResource(InjectionPoint injectionPoint)
+ {
+ return loader.getResource(getName(injectionPoint));
+ }
+
+ private String getName(InjectionPoint ip)
+ {
+ Set<Annotation> qualifiers = ip.getQualifiers();
+ for (Annotation qualifier : qualifiers)
+ {
+ if (qualifier.annotationType().equals(Resource.class))
+ {
+ return ((Resource) qualifier).value();
+ }
+ }
+ throw new IllegalArgumentException("Injection point " + ip + " does
not have @Resource qualifier");
+ }
+
+}
Property changes on:
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/ResourceProducer.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Added:
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/ResourceProvider.java
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/ResourceProvider.java
(rev 0)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/ResourceProvider.java 2010-03-10
19:58:08 UTC (rev 6035)
@@ -0,0 +1,121 @@
+package org.jboss.weld.extensions.resources;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.PreDestroy;
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+
+import org.jboss.weld.extensions.Resource;
+import org.jboss.weld.extensions.util.AnnotationInstanceProvider;
+
+/**
+ * The ResourceLoader allows dynamic loading of managed resources.
+ *
+ * If a input stream is loaded, it will be automatically closed when the InputStream goes
+ * out of scope. If a URL is used to create an input stream, the application is
responsible
+ * for closing it. For this reason it is recommended that managed input streams are used
+ * where possible.
+ *
+ * @author pmuir
+ *
+ */
+public class ResourceProvider implements Serializable
+{
+
+ private static final long serialVersionUID = -4463427096501401965L;
+
+ private final transient AnnotationInstanceProvider annotationInstanceProvider = new
AnnotationInstanceProvider();;
+
+ private final Instance<URL> urlProvider;
+ private final Instance<InputStream> inputStreamProvider;
+
+ // Workaround WELD-466
+ private final Set<InputStream> streams;
+
+ @Inject
+ private ResourceProvider(@Any Instance<InputStream> inputStreamProvider, @Any
Instance<URL> urlProvider)
+ {
+ this.inputStreamProvider = inputStreamProvider;
+ this.urlProvider = urlProvider;
+ this.streams = new HashSet<InputStream>();
+ }
+
+ /**
+ * <p>Load a resource.</p>
+ *
+ * <p>The default search order is:</p>
+ *
+ * <ul>
+ * <li></li>
+ * </ul>
+ *
+ *
+ * @param name
+ * @return
+ */
+ public InputStream loadResourceStream(String name)
+ {
+ if (name == null || name.equals(""))
+ {
+ throw new IllegalArgumentException("You must specify the name of the
resource to load");
+ }
+ Map<String, Object> values = new HashMap<String, Object>();
+ values.put("value", name);
+ InputStream stream =
inputStreamProvider.select(annotationInstanceProvider.get(Resource.class, values)).get();
+ // Workaround WELD-466
+ streams.add(stream);
+ return stream;
+ }
+
+
+ /**
+ * <p>Load a resource.</p>
+ *
+ * <p>The default search order is:</p>
+ *
+ * <ul>
+ * <li></li>
+ * </ul>
+ *
+ *
+ * @param name
+ * @return
+ */
+ public URL loadResource(String name)
+ {
+ if (name == null || name.equals(""))
+ {
+ throw new IllegalArgumentException("You must specify the name of the
resource to load");
+ }
+ Map<String, Object> values = new HashMap<String, Object>();
+ values.put("value", name);
+ return urlProvider.select(annotationInstanceProvider.get(Resource.class,
values)).get();
+ }
+
+ @SuppressWarnings("unused")
+ @PreDestroy
+ private void cleanup()
+ {
+ for (InputStream stream : streams)
+ {
+ try
+ {
+ stream.close();
+ }
+ catch (IOException e)
+ {
+ // Nothing we can do about this
+ }
+ }
+ }
+
+}
Property changes on:
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/ResourceProvider.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Added:
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/spi/ResourceLoader.java
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/spi/ResourceLoader.java
(rev 0)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/spi/ResourceLoader.java 2010-03-10
19:58:08 UTC (rev 6035)
@@ -0,0 +1,13 @@
+package org.jboss.weld.extensions.resources.spi;
+
+import java.io.InputStream;
+import java.net.URL;
+
+public interface ResourceLoader
+{
+
+ public URL getResource(String resource);
+
+ public InputStream getResourceAsStream(String name);
+
+}
Property changes on:
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/spi/ResourceLoader.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Added:
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/spi/ResourceLoaderImpl.java
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/spi/ResourceLoaderImpl.java
(rev 0)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/spi/ResourceLoaderImpl.java 2010-03-10
19:58:08 UTC (rev 6035)
@@ -0,0 +1,76 @@
+package org.jboss.weld.extensions.resources.spi;
+
+import java.io.InputStream;
+import java.net.URL;
+
+import org.jboss.weld.extensions.resources.ResourceProducer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ResourceLoaderImpl implements ResourceLoader
+{
+
+ private static final Logger log =
LoggerFactory.getLogger("org.jboss.weld.extensions.resources");
+
+ private ResourceLoaderImpl() {}
+
+ public InputStream getResourceAsStream(String name)
+ {
+ // Always use the strippedName, classloader always assumes no starting /
+ String strippedName = getStrippedName(name);
+ // Try to load from the TCCL
+ if (Thread.currentThread().getContextClassLoader() != null)
+ {
+ InputStream stream =
Thread.currentThread().getContextClassLoader().getResourceAsStream(strippedName);
+ if (stream != null)
+ {
+ log.trace("Loaded resource from context classloader: " +
strippedName);
+ return stream;
+ }
+ }
+ // Try to load from the extension's classloader
+ else
+ {
+ InputStream stream = ResourceProducer.class.getResourceAsStream(strippedName);
+ if (stream != null)
+ {
+ log.trace("Loaded resource from Seam classloader: " +
strippedName);
+ return stream;
+ }
+ }
+ return null;
+ }
+
+ public URL getResource(String name)
+ {
+ // Always use the strippedName, classloader always assumes no starting /
+ String strippedName = getStrippedName(name);
+ // Try to load from the TCCL
+ if (Thread.currentThread().getContextClassLoader() != null)
+ {
+ URL url =
Thread.currentThread().getContextClassLoader().getResource(strippedName);
+ if (url != null)
+ {
+ log.trace("Loaded resource from context classloader: " +
strippedName);
+ return url;
+ }
+ }
+ // Try to load from the extension's classloader
+ else
+ {
+ URL url = ResourceProducer.class.getResource(strippedName);
+ if (url != null)
+ {
+ log.trace("Loaded resource from Seam classloader: " +
strippedName);
+ return url;
+ }
+ }
+ return null;
+ }
+
+ private static String getStrippedName(String name)
+ {
+ return name.startsWith("/") ? name.substring(1) : name;
+ }
+
+}
Property changes on:
extensions/trunk/src/main/java/org/jboss/weld/extensions/resources/spi/ResourceLoaderImpl.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Added:
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/resources/ResourceClient.java
===================================================================
---
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/resources/ResourceClient.java
(rev 0)
+++
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/resources/ResourceClient.java 2010-03-10
19:58:08 UTC (rev 6035)
@@ -0,0 +1,19 @@
+package org.jboss.weld.test.extensions.resources;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+
+import org.jboss.weld.extensions.resources.ResourceProvider;
+
+@RequestScoped
+public class ResourceClient
+{
+
+ @Inject ResourceProvider resourceProvider;
+
+ public ResourceProvider getResourceProvider()
+ {
+ return resourceProvider;
+ }
+
+}
Property changes on:
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/resources/ResourceClient.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Added:
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/resources/ResourceLoaderTest.java
===================================================================
---
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/resources/ResourceLoaderTest.java
(rev 0)
+++
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/resources/ResourceLoaderTest.java 2010-03-10
19:58:08 UTC (rev 6035)
@@ -0,0 +1,99 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jboss.weld.test.extensions.resources;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+
+import org.jboss.testharness.impl.packaging.Artifact;
+import org.jboss.testharness.impl.packaging.Classes;
+import org.jboss.weld.test.AbstractWeldTest;
+import org.testng.annotations.Test;
+
+@Artifact
+@Classes(packages = {"org.jboss.weld.extensions.resources.spi",
"org.jboss.weld.extensions.resources"})
+public class ResourceLoaderTest extends AbstractWeldTest
+{
+
+ @Test
+ public void testLoadsStream() throws Throwable
+ {
+ InputStream stream =
getReference(ResourceClient.class).getResourceProvider().loadResourceStream("com/acme/foo1");
+ assert stream.available() > 0;
+ InputStreamReader reader = new InputStreamReader(stream);
+ char[] chars = new char[4];
+ reader.read(chars, 0, 4);
+ assert new String(chars).equals("foo1");
+ }
+
+ @Test
+ public void testLoadsURLs() throws Throwable
+ {
+ URL url =
getReference(ResourceClient.class).getResourceProvider().loadResource("com/acme/foo1");
+ InputStream stream = url.openStream();
+ assert stream.available() > 0;
+ InputStreamReader reader = new InputStreamReader(stream);
+ char[] chars = new char[4];
+ reader.read(chars, 0, 4);
+ assert new String(chars).equals("foo1");
+ assert url.getFile().endsWith("/com/acme/foo1");
+ }
+
+ @Test
+ public void testInitialSlashIgnored() throws Throwable
+ {
+ URL url =
getReference(ResourceClient.class).getResourceProvider().loadResource("/com/acme/foo1");
+ InputStream stream = url.openStream();
+ assert stream.available() > 0;
+ InputStreamReader reader = new InputStreamReader(stream);
+ char[] chars = new char[4];
+ reader.read(chars, 0, 4);
+ assert new String(chars).equals("foo1");
+ assert url.getFile().endsWith("com/acme/foo1");
+ }
+
+ @Test
+ public void testStreamsAreCleanedUp() throws Throwable
+ {
+ Bean<ResourceClient> bean = getBean(ResourceClient.class);
+ CreationalContext<ResourceClient> creationalContext =
getCurrentManager().createCreationalContext(bean);
+ ResourceClient client = bean.create(creationalContext);
+ InputStream stream =
client.getResourceProvider().loadResourceStream("/com/acme/foo1");
+ assert stream.available() > 0;
+ InputStreamReader reader = new InputStreamReader(stream);
+ char[] chars = new char[4];
+ reader.read(chars, 0, 4);
+ assert new String(chars).equals("foo1");
+ bean.destroy(client, creationalContext);
+ try
+ {
+ stream.available();
+ assert false;
+ }
+ catch (IOException e)
+ {
+ // Expected
+ }
+ }
+
+}
Property changes on:
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/resources/ResourceLoaderTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Added: extensions/trunk/src/test/resources/com/acme/foo1
===================================================================
--- extensions/trunk/src/test/resources/com/acme/foo1 (rev 0)
+++ extensions/trunk/src/test/resources/com/acme/foo1 2010-03-10 19:58:08 UTC (rev 6035)
@@ -0,0 +1 @@
+foo1
\ No newline at end of file