great. will check out now; ...and demonstrate that next week, on my JSF 2 talk :-)
On Tue, Jan 12, 2010 at 7:20 PM, <[email protected]> wrote: > Author: struberg > Date: Tue Jan 12 18:20:42 2010 > New Revision: 898454 > > URL: http://svn.apache.org/viewvc?rev=898454&view=rev > Log: > OWB-229 support for the new JSF-2 javax.faces.bean.ViewScoped annotation > > TODO: this should get moved to an own jsf-2 module because this currently > breaks JSF-1 compatibility! > > Added: > > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/scopes/ > > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/scopes/Jsf2ScopesExtension.java > (with props) > > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/scopes/ViewScopedContext.java > (with props) > > openwebbeans/trunk/webbeans-jsf/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension > Modified: > > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/WebBeansPhaseListener.java > > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/plugin/OpenWebBeansJsfPlugin.java > > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/util/JSFUtil.java > > Modified: > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/WebBeansPhaseListener.java > URL: > http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/WebBeansPhaseListener.java?rev=898454&r1=898453&r2=898454&view=diff > ============================================================================== > --- > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/WebBeansPhaseListener.java > (original) > +++ > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/WebBeansPhaseListener.java > Tue Jan 12 18:20:42 2010 > @@ -34,6 +34,8 @@ > */ > public class WebBeansPhaseListener implements PhaseListener > { > + private static final long serialVersionUID = 1L; > + > /**Logger instance*/ > private static final WebBeansLogger logger = > WebBeansLogger.getLogger(WebBeansPhaseListener.class); > > > Modified: > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/plugin/OpenWebBeansJsfPlugin.java > URL: > http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/plugin/OpenWebBeansJsfPlugin.java?rev=898454&r1=898453&r2=898454&view=diff > ============================================================================== > --- > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/plugin/OpenWebBeansJsfPlugin.java > (original) > +++ > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/plugin/OpenWebBeansJsfPlugin.java > Tue Jan 12 18:20:42 2010 > @@ -28,7 +28,7 @@ > /** {...@inheritdoc} */ > public void startUp() throws WebBeansConfigurationException > { > - // nothing to do > + // nothing to do > } > > /** {...@inheritdoc} */ > > Added: > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/scopes/Jsf2ScopesExtension.java > URL: > http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/scopes/Jsf2ScopesExtension.java?rev=898454&view=auto > ============================================================================== > --- > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/scopes/Jsf2ScopesExtension.java > (added) > +++ > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/scopes/Jsf2ScopesExtension.java > Tue Jan 12 18:20:42 2010 > @@ -0,0 +1,43 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you 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.apache.webbeans.jsf.scopes; > + > +import javax.enterprise.event.Observes; > +import javax.enterprise.inject.spi.AfterBeanDiscovery; > +import javax.enterprise.inject.spi.BeforeBeanDiscovery; > +import javax.enterprise.inject.spi.Extension; > +import javax.faces.bean.ViewScoped; > + > +/** > + * This small extension adds support for various JSF 2 scopes > + * TODO: this should be moved to an own module because this will > + * currently hinder webbeans-jsf to run in a JSF-1 application! > + */ > +public class Jsf2ScopesExtension implements Extension { > + > + public void addViewScoped(@Observes BeforeBeanDiscovery > beforeBeanDiscovery) > + { > + beforeBeanDiscovery.addScope(ViewScoped.class, true, true); > + } > + > + public void registerViewContext(@Observes AfterBeanDiscovery > afterBeanDiscovery) > + { > + afterBeanDiscovery.addContext(new ViewScopedContext()); > + } > +} > \ No newline at end of file > > Propchange: > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/scopes/Jsf2ScopesExtension.java > ------------------------------------------------------------------------------ > svn:eol-style = native > > Propchange: > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/scopes/Jsf2ScopesExtension.java > ------------------------------------------------------------------------------ > svn:keywords = Author Date Id Revision > > Added: > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/scopes/ViewScopedContext.java > URL: > http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/scopes/ViewScopedContext.java?rev=898454&view=auto > ============================================================================== > --- > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/scopes/ViewScopedContext.java > (added) > +++ > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/scopes/ViewScopedContext.java > Tue Jan 12 18:20:42 2010 > @@ -0,0 +1,213 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you 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.apache.webbeans.jsf.scopes; > + > +import java.lang.annotation.Annotation; > +import java.util.Map; > +import java.util.Map.Entry; > +import java.util.concurrent.ConcurrentHashMap; > + > +import javax.enterprise.context.ContextNotActiveException; > +import javax.enterprise.context.spi.Context; > +import javax.enterprise.context.spi.Contextual; > +import javax.enterprise.context.spi.CreationalContext; > + > +import javax.faces.bean.ViewScoped; > +import javax.faces.component.UIViewRoot; > +import javax.faces.context.FacesContext; > +import javax.faces.event.PreDestroyViewMapEvent; > +import javax.faces.event.SystemEvent; > +import javax.faces.event.SystemEventListener; > + > +import org.apache.webbeans.util.JSFUtil; > + > +/** > + * This class provides the contexts lifecycle for the > + * new JSF-2 @ViewScoped Context > + * > + */ > +public class ViewScopedContext implements Context, SystemEventListener > +{ > + > + private final static String COMPONENT_MAP_NAME > ="openwebbeans.componentInstanceMap"; > + private final static String CREATIONAL_MAP_NAME > ="openwebbeans.creationalInstanceMap"; > + > + private boolean isJsfSubscribed = false; > + > + �...@override > + public <T> T get(Contextual<T> component) > + { > + checkActive(); > + > + if(!isJsfSubscribed) > + { > + > FacesContext.getCurrentInstance().getApplication().subscribeToEvent(PreDestroyViewMapEvent.class, > this); > + > + isJsfSubscribed = true; > + } > + > + Map<String, Object> viewMap = JSFUtil.getViewRoot().getViewMap(); > + > + �...@suppresswarnings("unchecked") > + ConcurrentHashMap<Contextual<?>, Object> componentInstanceMap = > (ConcurrentHashMap<Contextual<?>, Object>) viewMap.get(COMPONENT_MAP_NAME); > + > + if(componentInstanceMap == null) { > + return null; > + } > + > + �...@suppresswarnings("unchecked") > + T instance = (T) componentInstanceMap.get(component); > + > + return instance; > + } > + > + �...@override > + public <T> T get(Contextual<T> component, CreationalContext<T> > creationalContext) > + { > + checkActive(); > + > + Map<String, Object> viewMap = JSFUtil.getViewRoot().getViewMap(true); > + > + �...@suppresswarnings("unchecked") > + ConcurrentHashMap<Contextual<?>, Object> componentInstanceMap = > (ConcurrentHashMap<Contextual<?>, Object>) viewMap.get(COMPONENT_MAP_NAME); > + > + if(componentInstanceMap == null) > + { > + // TODO we now need to start being carefull with reentrancy... > + componentInstanceMap = new ConcurrentHashMap<Contextual<?>, > Object>(); > + viewMap.put(COMPONENT_MAP_NAME, componentInstanceMap); > + } > + > + �...@suppresswarnings("unchecked") > + ConcurrentHashMap<Contextual<?>, CreationalContext<?>> > creationalContextMap = (ConcurrentHashMap<Contextual<?>, > CreationalContext<?>>) viewMap.get(CREATIONAL_MAP_NAME); > + if(creationalContextMap == null) > + { > + // TODO we now need to start being carefull with reentrancy... > + creationalContextMap = new ConcurrentHashMap<Contextual<?>, > CreationalContext<?>>(); > + viewMap.put(CREATIONAL_MAP_NAME, creationalContextMap); > + } > + > + �...@suppresswarnings("unchecked") > + T instance = (T) componentInstanceMap.get(component); > + if (instance != null) > + { > + return instance; > + } > + else > + { > + if(creationalContext == null) > + { > + return null; > + } > + else > + { > + synchronized (componentInstanceMap) > + { > + // just to make sure... > + �...@suppresswarnings("unchecked") > + T i = (T)componentInstanceMap.get(component); > + if (i != null) > + { > + return i; > + } > + > + instance = component.create(creationalContext); > + > + if (instance != null) > + { > + componentInstanceMap.put(component, instance); > + creationalContextMap.put(component, > creationalContext); > + } > + } > + } > + } > + > + return instance; > + } > + > + �...@override > + public Class<? extends Annotation> getScope() > + { > + return ViewScoped.class; > + } > + > + /** > + * The view context is active if a valid ViewRoot could be detected. > + */ > + �...@override > + public boolean isActive() > + { > + return JSFUtil.getViewRoot() != null; > + } > + > + private void checkActive() > + { > + if (!isActive()) > + { > + throw new ContextNotActiveException("WebBeans context with scope > annotation @ViewScoped is not active with respect to the current thread"); > + } > + } > + > + �...@override > + public boolean isListenerForSource(Object source) { > + if (source instanceof UIViewRoot) > + { > + return true; > + } > + > + return false; > + } > + > + /** > + * We get PreDestroyViewMapEvent events from the JSF servlet and destroy > our contextual > + * instances. This should (theoretically!) also get fired if the webapp > closes, so there > + * should be no need to manually track all view scopes and destroy them > at a shutdown. > + * > + * @see > javax.faces.event.SystemEventListener#processEvent(javax.faces.event.SystemEvent) > + */ > + �...@override > + �...@suppresswarnings("unchecked") > + public void processEvent(SystemEvent event) { > + if (event instanceof PreDestroyViewMapEvent) > + { > + // better use the viewmap we get from the event to prevent > concurrent modification problems > + Map<String, Object> viewMap = ((UIViewRoot) > event.getSource()).getViewMap(); > + > + ConcurrentHashMap<Contextual<?>, Object> componentInstanceMap > + = (ConcurrentHashMap<Contextual<?>, Object>) > viewMap.get(COMPONENT_MAP_NAME); > + > + ConcurrentHashMap<Contextual<?>, CreationalContext<?>> > creationalContextMap > + = (ConcurrentHashMap<Contextual<?>, > CreationalContext<?>>) viewMap.get(CREATIONAL_MAP_NAME); > + > + if(componentInstanceMap != null) { > + for ( Entry<Contextual<?>, Object> componentEntry : > componentInstanceMap.entrySet()) > + { > + // there is no nice way to explain the Java Compiler > that we are handling the same type T, > + // therefore we need completely drop the type > information :( > + Contextual contextual = componentEntry.getKey(); > + Object instance = componentEntry.getValue(); > + CreationalContext creational = > creationalContextMap.get(contextual); > + > + contextual.destroy(instance, creational); > + } > + } > + } > + } > + > +} > > Propchange: > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/scopes/ViewScopedContext.java > ------------------------------------------------------------------------------ > svn:eol-style = native > > Propchange: > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/scopes/ViewScopedContext.java > ------------------------------------------------------------------------------ > svn:keywords = Author Date Id Revision > > Modified: > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/util/JSFUtil.java > URL: > http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/util/JSFUtil.java?rev=898454&r1=898453&r2=898454&view=diff > ============================================================================== > --- > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/util/JSFUtil.java > (original) > +++ > openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/util/JSFUtil.java > Tue Jan 12 18:20:42 2010 > @@ -63,6 +63,9 @@ > return > getCurrentFacesContext().getRenderKit().getResponseStateManager().isPostback(getCurrentFacesContext()); > } > > + /** > + * @return the viewId of the viewRoot, e.g. '/user/menu.xhtml' > + */ > public static String getViewId() > { > UIViewRoot viewRoot = getCurrentFacesContext().getViewRoot(); > > Added: > openwebbeans/trunk/webbeans-jsf/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension > URL: > http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-jsf/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension?rev=898454&view=auto > ============================================================================== > --- > openwebbeans/trunk/webbeans-jsf/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension > (added) > +++ > openwebbeans/trunk/webbeans-jsf/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension > Tue Jan 12 18:20:42 2010 > @@ -0,0 +1,18 @@ > +#Licensed to the Apache Software Foundation (ASF) under one > +#or more contributor license agreements. See the NOTICE file > +#distributed with this work for additional information > +#regarding copyright ownership. The ASF licenses this file > +#to you 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. > + > +org.apache.webbeans.jsf.scopes.Jsf2ScopesExtension > \ No newline at end of file > > > -- Matthias Wessendorf blog: http://matthiaswessendorf.wordpress.com/ sessions: http://www.slideshare.net/mwessendorf twitter: http://twitter.com/mwessendorf
