Author: alexsmirnov
Date: 2010-06-16 20:23:45 -0400 (Wed, 16 Jun 2010)
New Revision: 17632
Added:
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/Module.java
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/Scope.java
Removed:
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/BindingModule.java
Modified:
root/core/branches/jsr-330/jsr330-impl/pom.xml
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/Binder.java
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/BinderImpl.java
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/InjectorImpl.java
root/core/branches/jsr-330/jsr330-impl/src/test/java/org/richfaces/jsr330/InjectorTest.java
Log:
implement scopes
Modified: root/core/branches/jsr-330/jsr330-impl/pom.xml
===================================================================
--- root/core/branches/jsr-330/jsr330-impl/pom.xml 2010-06-16 12:38:15 UTC (rev 17631)
+++ root/core/branches/jsr-330/jsr330-impl/pom.xml 2010-06-17 00:23:45 UTC (rev 17632)
@@ -48,5 +48,12 @@
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
</dependency>
+ <!-- Provided dependencies -->
+ <!-- JSF2 api version set by bom/richface-parent -->
+ <dependency>
+ <groupId>${jsf2.api.groupid}</groupId>
+ <artifactId>${jsf2.api.artifactid}</artifactId>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
</project>
Modified:
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/Binder.java
===================================================================
---
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/Binder.java 2010-06-16
12:38:15 UTC (rev 17631)
+++
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/Binder.java 2010-06-17
00:23:45 UTC (rev 17632)
@@ -48,5 +48,8 @@
public Binder<T> toService(Class<? extends T> defaultImplementation);
public Binder<T> asSingleton();
-
+ public Binder<T> asSessionScope();
+ public Binder<T> asRequestScope();
+ public Binder<T> asApplicationScope();
+
}
Modified:
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/BinderImpl.java
===================================================================
---
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/BinderImpl.java 2010-06-16
12:38:15 UTC (rev 17631)
+++
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/BinderImpl.java 2010-06-17
00:23:45 UTC (rev 17632)
@@ -24,7 +24,10 @@
package org.richfaces.jsr330;
import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import javax.faces.context.FacesContext;
import javax.inject.Provider;
/**
@@ -32,42 +35,117 @@
* </p>
*
* @author asmirnov(a)exadel.com
- *
+ *
* @param <T>
*/
public final class BinderImpl<T> implements Binder<T> {
- private final Class<T> target;
+ private final Scope<T> defaultScope = new Scope<T>() {
+ public T get() {
+ return getProvider().get();
+ }
+ };
+
+ private final Scope<T> singltonScope = new Scope<T>() {
+
+ private boolean instantiated = false;
+
+ private volatile T value;
+
+ public T get() {
+ if (!instantiated) {
+ value = getProvider().get();
+ instantiated = true;
+ }
+ return value;
+ }
+ };
+
+ private abstract class FacesScope implements Scope<T> {
+
+ private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
+
+ public T get() {
+ T value;
+ rwLock.readLock().lock();
+ try {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ if (null != facesContext) {
+ Map<String, Object> map = getMap(facesContext);
+ value = (T) map.get(target.toString());
+ if(null == value){
+ rwLock.readLock().unlock();
+ rwLock.writeLock().lock();
+ try {
+ value = getProvider().get();
+ map.put(target.toString(), value);
+ } finally {
+ rwLock.readLock().lock();
+ rwLock.writeLock().unlock();
+ }
+ }
+ } else {
+ value = getProvider().get();
+ }
+ } finally {
+ rwLock.readLock().unlock();
+ }
+ return value;
+ }
+
+ protected abstract Map<String, Object> getMap(FacesContext facesContext);
+ }
- private volatile T value;
+ private final Scope<T> sessionScope = new FacesScope() {
+
+ @Override
+ protected Map<String, Object> getMap(FacesContext facesContext) {
+ Map<String, Object> map =
facesContext.getExternalContext().getSessionMap();
+ return map;
+ }
+ };
+ private final Scope<T> requestScope = new FacesScope() {
+ @Override
+ protected Map<String, Object> getMap(FacesContext facesContext) {
+ return facesContext.getExternalContext().getRequestMap();
+ }
+ };
+
+ private final Scope<T> applicationScope = new FacesScope() {
+ @Override
+ protected Map<String, Object> getMap(FacesContext facesContext) {
+ return facesContext.getExternalContext().getApplicationMap();
+ }
+ };
+
+ private final Target target;
+
private Provider<T> provider;
private Provider<Provider<T>> providerOfProvider;
- private boolean singleton;
+ private Scope<T> scope;
private volatile BinderImpl<Provider<T>> providerBinder;
-
+
private boolean initialized = false;
- private boolean providerSingleton;
-
/**
- * <p class="changed_added_4_0"></p>
- * @param target the target to set
+ * <p class="changed_added_4_0">
+ * </p>
+ *
+ * @param target
+ * the target to set
*/
- public BinderImpl(Class<T> target) {
+ public BinderImpl(Target target) {
this.target = target;
+ this.scope = defaultScope;
}
public T get() {
checkInitialized();
- if (null != value) {
- return value;
- } else {
- return getProvider().get();
- }
+ return scope.get();
}
public BinderImpl<Provider<T>> asProviderBinder() {
@@ -77,7 +155,9 @@
return providerBinder;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.richfaces.jsr330.Binder#to(java.lang.Class)
*/
public Binder<T> to(Class<? extends T> implementation) {
@@ -85,22 +165,25 @@
return this;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.richfaces.jsr330.Binder#toInstance(java.lang.Object)
*/
- public Binder<T> toInstance(T value) {
+ public Binder<T> toInstance(final T value) {
checkNotInitialized();
- this.value = value;
this.provider = new Provider<T>() {
public T get() {
- return BinderImpl.this.value;
+ return value;
}
};
return this;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.richfaces.jsr330.Binder#toProvider(java.lang.Class)
*/
@SuppressWarnings("unchecked")
@@ -110,7 +193,9 @@
return this;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.richfaces.jsr330.Binder#toProviderInstance(javax.inject.Provider)
*/
public Binder<T> toProviderInstance(Provider<T> provider) {
@@ -118,112 +203,127 @@
return this;
}
- /* (non-Javadoc)
+ public Binder<T> toService() {
+ Collection<Class<? extends T>> service = loadService();
+ if (service.size() > 0) {
+ this.to(service.iterator().next());
+ } else {
+ throw new DependencyException("No implementation found for service
" + target);
+ }
+ return this;
+ }
+
+ public Binder<T> toService(Class<? extends T> defaultImplementation) {
+ Collection<Class<? extends T>> service = loadService();
+ if (service.size() > 0) {
+ this.to(service.iterator().next());
+ } else {
+ this.to(defaultImplementation);
+ }
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
* @see org.richfaces.jsr330.Binder#asSingleton()
*/
public Binder<T> asSingleton() {
- this.singleton = true;
+ this.scope = singltonScope;
return this;
}
- private void checkInitialized() {
- if(!initialized){
- throw new DependencyException("Dependency injection implementation has
not been initialized");
- }
+ public Binder<T> asApplicationScope() {
+ this.scope = applicationScope;
+ return this;
}
- private void checkNotInitialized() {
- if(initialized){
- throw new DependencyException("Dependency injection implementation has
already been initialized");
- }
+ public Binder<T> asRequestScope() {
+ this.scope = requestScope;
+ return this;
}
- Provider<T> getProvider() {
- return null == this.provider ? this.providerOfProvider.get() : this.provider;
+ public Binder<T> asSessionScope() {
+ this.scope = sessionScope;
+ return this;
}
void init(Binders injector) throws DependencyException {
checkNotInitialized();
- if (null == value && null == provider && null ==
providerOfProvider) {
+ if (null == provider && null == providerOfProvider) {
throw new DependencyException("binding not has not been set");
}
if (null != provider && provider instanceof Initializable) {
- this.singleton |=((Initializable) provider).init(injector);
+ if( ((Initializable) provider).init(injector)){
+ this.scope = singltonScope;
+ }
}
if (null != providerOfProvider && providerOfProvider instanceof
Initializable) {
- this.providerSingleton |=((Initializable)
providerOfProvider).init(injector);
+ ((Initializable) providerOfProvider).init(injector);
}
this.initialized = true;
}
void createInstances(Binders injector) throws DependencyException {
checkInitialized();
- if(providerSingleton && null == provider){
+ if (null == provider && null != providerOfProvider) {
this.provider = providerOfProvider.get();
}
- if(singleton && null == value ){
- this.value= getProvider().get();
+ if (this.scope == singltonScope ) {
+ scope.get();
}
createProviderBinding();
}
+ public void destroy(InjectorImpl injectorImpl) {
+ if (null != provider && provider instanceof Initializable) {
+ ((Initializable) provider).destroy();
+ }
+ if (null != providerOfProvider && providerOfProvider instanceof
Initializable) {
+ ((Initializable) providerOfProvider).destroy();
+ }
+ provider = null;
+ providerOfProvider = null;
+ providerBinder = null;
+ this.initialized = false;
+ }
+
+ Provider<T> getProvider() {
+ return null == this.provider ? this.providerOfProvider.get() : this.provider;
+ }
+
+ private void checkInitialized() {
+ if (!initialized) {
+ throw new DependencyException("Dependency injection implementation has
not been initialized");
+ }
+ }
+
+ private void checkNotInitialized() {
+ if (initialized) {
+ throw new DependencyException("Dependency injection implementation has
already been initialized");
+ }
+ }
+
@SuppressWarnings("unchecked")
private void createProviderBinding() {
- BinderImpl<Provider<T>> providerBinder = new
BinderImpl(Provider.class);
+ BinderImpl<Provider<T>> providerBinder = new
BinderImpl(target.toProvider());
if (null != provider) {
providerBinder.toInstance(provider);
- } else if(null != providerOfProvider){
+ } else if (null != providerOfProvider) {
providerBinder.toProviderInstance(providerOfProvider);
}
- providerBinder.initialized=true;
+ providerBinder.initialized = true;
this.providerBinder = providerBinder;
}
- public Binder<T> toService() {
- Collection<Class<? extends T>> service = loadService();
- if(service.size()>0){
- this.to(service.iterator().next());
- } else {
- throw new DependencyException("No implementation found for service
"+target.getName());
- }
- return this;
- }
-
private Collection<Class<? extends T>> loadService() {
- if(null == target){
+ if (null == target) {
throw new DependencyException("Binder does not configured
correctly");
}
try {
- return ServiceLoader.loadServiceClasses(target);
+ return ServiceLoader.<T> loadServiceClasses((Class<T>)
target.getRawType());
} catch (ServiceException e) {
- throw new DependencyException("Error loading service ",e);
+ throw new DependencyException("Error loading service ", e);
}
}
-
- public Binder<T> toService(Class<? extends T> defaultImplementation) {
- Collection<Class<? extends T>> service = loadService();
- if(service.size()>0){
- this.to(service.iterator().next());
- } else {
- this.to(defaultImplementation);
- }
- return this;
- }
-
- public void destroy(InjectorImpl injectorImpl) {
- if (null != value && value instanceof Initializable) {
- ((Initializable) value).destroy();
- }
- if (null != provider && provider instanceof Initializable) {
- ((Initializable) provider).destroy();
- }
- if (null != providerOfProvider && providerOfProvider instanceof
Initializable) {
- ((Initializable) providerOfProvider).destroy();
- }
- value = null;
- provider = null;
- providerOfProvider = null;
- providerBinder = null;
- this.initialized = false;
- }
}
Deleted:
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/BindingModule.java
===================================================================
---
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/BindingModule.java 2010-06-16
12:38:15 UTC (rev 17631)
+++
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/BindingModule.java 2010-06-17
00:23:45 UTC (rev 17632)
@@ -1,12 +0,0 @@
-package org.richfaces.jsr330;
-
-/**
- * <p class="changed_added_4_0">User-provided configuration
module.</p>
- * @author asmirnov(a)exadel.com
- *
- */
-public interface BindingModule {
-
- public void configure(InjectorConfig injector);
-
-}
Modified:
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/InjectorImpl.java
===================================================================
---
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/InjectorImpl.java 2010-06-16
12:38:15 UTC (rev 17631)
+++
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/InjectorImpl.java 2010-06-17
00:23:45 UTC (rev 17632)
@@ -32,9 +32,9 @@
return create(type, null);
}
- public void init(BindingModule... modules) {
+ public void init(Module... modules) {
register(DependencyInjector.class).toInstance(this);
- for (BindingModule bindingModule : modules) {
+ for (Module bindingModule : modules) {
bindingModule.configure(this);
}
initProviders();
@@ -74,7 +74,7 @@
return bindings.get(type);
} else if (type.isConcrete()) {
// Concrete classes can be created without configuration.
- BinderImpl binding = new BinderImpl(type.getRawType());
+ BinderImpl binding = new BinderImpl(type);
binding.to(type.getRawType());
binding.init(this);
binding.createInstances(this);
@@ -108,7 +108,7 @@
*/
@SuppressWarnings("unchecked")
public <T> Binder<T> register(Target type) {
- BinderImpl<T> binding = new BinderImpl(type.getRawType());
+ BinderImpl<T> binding = new BinderImpl(type);
registerBinding(type, binding);
return binding;
}
Copied:
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/Module.java
(from rev 17631,
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/BindingModule.java)
===================================================================
--- root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/Module.java
(rev 0)
+++
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/Module.java 2010-06-17
00:23:45 UTC (rev 17632)
@@ -0,0 +1,12 @@
+package org.richfaces.jsr330;
+
+/**
+ * <p class="changed_added_4_0">User-provided configuration
module.</p>
+ * @author asmirnov(a)exadel.com
+ *
+ */
+public interface Module {
+
+ public void configure(InjectorConfig injector);
+
+}
Added:
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/Scope.java
===================================================================
--- root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/Scope.java
(rev 0)
+++
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/Scope.java 2010-06-17
00:23:45 UTC (rev 17632)
@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ *
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package org.richfaces.jsr330;
+
+import javax.inject.Provider;
+
+/**
+ * <p class="changed_added_4_0"></p>
+ * @author asmirnov(a)exadel.com
+ *
+ */
+interface Scope<T> extends Provider<T> {
+
+}
Property changes on:
root/core/branches/jsr-330/jsr330-impl/src/main/java/org/richfaces/jsr330/Scope.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified:
root/core/branches/jsr-330/jsr330-impl/src/test/java/org/richfaces/jsr330/InjectorTest.java
===================================================================
---
root/core/branches/jsr-330/jsr330-impl/src/test/java/org/richfaces/jsr330/InjectorTest.java 2010-06-16
12:38:15 UTC (rev 17631)
+++
root/core/branches/jsr-330/jsr330-impl/src/test/java/org/richfaces/jsr330/InjectorTest.java 2010-06-17
00:23:45 UTC (rev 17632)
@@ -10,7 +10,7 @@
@Test
public void injectByConstructor() throws Exception {
InjectorImpl injector = new InjectorImpl();
- injector.init(new BindingModule(){
+ injector.init(new Module(){
public void configure(InjectorConfig injector) {
injector.register(Interface.class).to(ConstructorInjection.class);
@@ -27,7 +27,7 @@
@Test
public void injectByField() throws Exception {
InjectorImpl injector = new InjectorImpl();
- injector.init(new BindingModule(){
+ injector.init(new Module(){
public void configure(InjectorConfig injector) {
injector.register(Interface.class).to(FieldInjection.class);
@@ -44,7 +44,7 @@
@Test
public void injectByMethod() throws Exception {
InjectorImpl injector = new InjectorImpl();
- injector.init(new BindingModule(){
+ injector.init(new Module(){
public void configure(InjectorConfig injector) {
injector.register(Interface.class).to(MethodInjection.class);
@@ -61,7 +61,7 @@
@Test
public void injectByProvider() throws Exception {
InjectorImpl injector = new InjectorImpl();
- injector.init(new BindingModule(){
+ injector.init(new Module(){
public void configure(InjectorConfig injector) {
injector.register(Interface.class).to(ProviderInjection.class);
@@ -78,7 +78,7 @@
@Test
public void injectProvider() throws Exception {
InjectorImpl injector = new InjectorImpl();
- injector.init(new BindingModule(){
+ injector.init(new Module(){
public void configure(InjectorConfig injector) {
injector.register(Interface.class).to(ProviderInjection.class);
@@ -98,7 +98,7 @@
@Test
public void inject() throws Exception {
InjectorImpl injector = new InjectorImpl();
- injector.init(new BindingModule(){
+ injector.init(new Module(){
public void configure(InjectorConfig injector) {
injector.register("foo", String.class).toProviderInstance(new
FooProvider());