You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by gp...@apache.org on 2010/07/11 00:46:49 UTC

svn commit: r962936 [2/3] - in /myfaces/extensions/cdi/trunk: core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/config/ core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/scope/conversation/ core/api/src/main/java/org/apa...

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/api/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/api/request/RequestTypeResolver.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/api/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/api/request/RequestTypeResolver.java?rev=962936&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/api/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/api/request/RequestTypeResolver.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/api/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/api/request/RequestTypeResolver.java Sat Jul 10 22:46:47 2010
@@ -0,0 +1,29 @@
+/*
+ * 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.myfaces.extensions.cdi.javaee.jsf.api.request;
+
+/**
+ * @author Gerhard Petracek
+ */
+public interface RequestTypeResolver
+{
+    boolean isPartialRequest();
+
+    boolean isPostRequest();
+}

Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/config/faces-config.xml
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/config/faces-config.xml?rev=962936&r1=962935&r2=962936&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/config/faces-config.xml (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/config/faces-config.xml Sat Jul 10 22:46:47 2010
@@ -18,12 +18,17 @@
 -->
 
 <faces-config version="1.2"
-    xmlns="http://java.sun.com/xml/ns/javaee"
-    xmlns:xi="http://www.w3.org/2001/XInclude"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
+              xmlns="http://java.sun.com/xml/ns/javaee"
+              xmlns:xi="http://www.w3.org/2001/XInclude"
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
+
+    <application>
+        <navigation-handler>org.apache.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation.AccessScopeAwareNavigationHandler</navigation-handler>
+    </application>
 
     <factory>
         <faces-context-factory>org.apache.myfaces.extensions.cdi.javaee.jsf.impl.request.CodiFacesContextFactory</faces-context-factory>
+        <render-kit-factory>org.apache.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation.CodiRenderKitFactory</render-kit-factory>
     </factory>
 </faces-config>
\ No newline at end of file

Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/config/javax.enterprise.inject.spi.Extension
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/config/javax.enterprise.inject.spi.Extension?rev=962936&r1=962935&r2=962936&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/config/javax.enterprise.inject.spi.Extension (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/config/javax.enterprise.inject.spi.Extension Sat Jul 10 22:46:47 2010
@@ -17,6 +17,6 @@
 # under the License.
 #####################################################################################
 
-#org.apache.myfaces.extensions.cdi.javaee.jsf.impl.listener.phase.PhaseListenerExtension
+org.apache.myfaces.extensions.cdi.javaee.jsf.impl.listener.phase.PhaseListenerExtension
 
-#org.apache.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation.grouped.GroupedConversationContextExtension
\ No newline at end of file
+org.apache.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation.grouped.GroupedConversationContextExtension
\ No newline at end of file

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/config/DefaultWindowContextConfig.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/config/DefaultWindowContextConfig.java?rev=962936&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/config/DefaultWindowContextConfig.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/config/DefaultWindowContextConfig.java Sat Jul 10 22:46:47 2010
@@ -0,0 +1,177 @@
+/*
+ * 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.myfaces.extensions.cdi.javaee.jsf.impl.config;
+
+import org.apache.myfaces.extensions.cdi.core.api.config.Config;
+import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowContextConfig;
+import static org.apache.myfaces.extensions.cdi.javaee.jsf.api.ConfigParameter.*;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.inject.Produces;
+import javax.faces.context.FacesContext;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+/**
+ * @author Gerhard Petracek
+ */
+@Singleton
+public class DefaultWindowContextConfig extends WindowContextConfig
+{
+    private static final long serialVersionUID = -1065123725125153533L;
+
+    private Boolean configInitialized;
+
+    @Produces
+    @Named
+    @Dependent
+    @Config(WindowContextConfig.class)
+    public boolean getRequestParameterSupported()
+    {
+        return isGetRequestParameterSupported();
+    }
+
+    @Produces
+    @Named
+    @Dependent
+    @Config(WindowContextConfig.class)
+    public Integer windowContextTimeoutInMinutes()
+    {
+        return getWindowContextTimeoutInMinutes();
+    }
+
+    @Produces
+    @Named
+    @Dependent
+    @Config(WindowContextConfig.class)
+    public Integer conversationTimeoutInMinutes()
+    {
+        return getConversationTimeoutInMinutes();
+    }
+
+    public boolean isGetRequestParameterSupported()
+    {
+        lazyInit();
+        return getAttribute(GET_REQUEST_PARAMETER_ENABLED, Boolean.class);
+    }
+
+    public int getWindowContextTimeoutInMinutes()
+    {
+        lazyInit();
+        return getAttribute(WINDOW_CONTEXT_TIMEOUT, Integer.class);
+    }
+
+    public int getConversationTimeoutInMinutes()
+    {
+        lazyInit();
+        return getAttribute(GROUPED_CONVERSATION_TIMEOUT, Integer.class);
+    }
+
+    private void lazyInit()
+    {
+        if (configInitialized == null)
+        {
+            init(FacesContext.getCurrentInstance());
+        }
+    }
+
+    private synchronized void init(FacesContext facesContext)
+    {
+        if (configInitialized != null || facesContext == null)
+        {
+            return;
+        }
+
+        configInitialized = true;
+
+        initGetRequestParameterEnabled(facesContext);
+        initWindowContextConversationTimeout(facesContext);
+        initGroupedConversationTimeout(facesContext);
+    }
+
+    private void initGetRequestParameterEnabled(FacesContext facesContext)
+    {
+        boolean requestParameterEnabled = GET_REQUEST_PARAMETER_ENABLED_DEFAULT;
+
+        String requestParameterEnabledString =
+                facesContext.getExternalContext().getInitParameter(GET_REQUEST_PARAMETER_ENABLED);
+
+        if (requestParameterEnabledString == null)
+        {
+            setAttribute(GET_REQUEST_PARAMETER_ENABLED, requestParameterEnabled);
+            return;
+        }
+
+        requestParameterEnabledString = requestParameterEnabledString.trim();
+
+        if ("".equals(requestParameterEnabledString))
+        {
+            setAttribute(GET_REQUEST_PARAMETER_ENABLED, requestParameterEnabled);
+            return;
+        }
+
+        setAttribute(GET_REQUEST_PARAMETER_ENABLED, Boolean.parseBoolean(requestParameterEnabledString));
+    }
+
+    private void initWindowContextConversationTimeout(FacesContext facesContext)
+    {
+        int timeoutInMinutes = WINDOW_CONTEXT_TIMEOUT_DEFAULT;
+
+        String timeoutString = facesContext.getExternalContext().getInitParameter(WINDOW_CONTEXT_TIMEOUT);
+
+        if (timeoutString == null)
+        {
+            setAttribute(WINDOW_CONTEXT_TIMEOUT, timeoutInMinutes);
+            return;
+        }
+
+        timeoutString = timeoutString.trim();
+
+        if ("".equals(timeoutString))
+        {
+            setAttribute(WINDOW_CONTEXT_TIMEOUT, timeoutInMinutes);
+            return;
+        }
+
+        setAttribute(WINDOW_CONTEXT_TIMEOUT, Integer.parseInt(timeoutString));
+    }
+
+    private void initGroupedConversationTimeout(FacesContext facesContext)
+    {
+        int timeoutInMinutes = GROUPED_CONVERSATION_TIMEOUT_DEFAULT;
+
+        String timeoutString = facesContext.getExternalContext().getInitParameter(GROUPED_CONVERSATION_TIMEOUT);
+
+        if (timeoutString == null)
+        {
+            setAttribute(GROUPED_CONVERSATION_TIMEOUT, timeoutInMinutes);
+            return;
+        }
+
+        timeoutString = timeoutString.trim();
+
+        if ("".equals(timeoutString))
+        {
+            setAttribute(GROUPED_CONVERSATION_TIMEOUT, timeoutInMinutes);
+            return;
+        }
+
+        setAttribute(GROUPED_CONVERSATION_TIMEOUT, Integer.parseInt(timeoutString));
+    }
+}
\ No newline at end of file

Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/request/CodiFacesContextWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/request/CodiFacesContextWrapper.java?rev=962936&r1=962935&r2=962936&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/request/CodiFacesContextWrapper.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/request/CodiFacesContextWrapper.java Sat Jul 10 22:46:47 2010
@@ -19,26 +19,29 @@
 package org.apache.myfaces.extensions.cdi.javaee.jsf.impl.request;
 
 import org.apache.myfaces.extensions.cdi.core.api.manager.BeanManagerProvider;
+import org.apache.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation.RedirectedConversationAwareExternalContext;
 
-import javax.faces.context.FacesContext;
+import javax.el.ELContext;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.faces.application.Application;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIViewRoot;
 import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseStream;
 import javax.faces.context.ResponseWriter;
-import javax.faces.application.Application;
-import javax.faces.application.FacesMessage;
 import javax.faces.render.RenderKit;
-import javax.faces.component.UIViewRoot;
-import javax.el.ELContext;
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.context.spi.CreationalContext;
 import java.util.Iterator;
 import java.util.Set;
 
 /**
+ * TODO move to a shared package
+ *
  * @author Gerhard Petracek
  */
-class CodiFacesContextWrapper extends FacesContext
+public class CodiFacesContextWrapper extends FacesContext
 {
     private FacesContext wrappedFacesContext;
 
@@ -46,7 +49,7 @@ class CodiFacesContextWrapper extends Fa
 
     private BeforeAfterFacesRequestBroadcaster beforeAfterFacesRequestBroadcaster;
 
-    CodiFacesContextWrapper(FacesContext wrappedFacesContext)
+    public CodiFacesContextWrapper(FacesContext wrappedFacesContext)
     {
         this.wrappedFacesContext = wrappedFacesContext;
         //(currently) causes issue in combination with geronimo 3.0-m1
@@ -89,7 +92,7 @@ class CodiFacesContextWrapper extends Fa
 
     public ExternalContext getExternalContext()
     {
-        return wrappedFacesContext.getExternalContext();
+        return new RedirectedConversationAwareExternalContext(wrappedFacesContext.getExternalContext());
     }
 
     public FacesMessage.Severity getMaximumSeverity()
@@ -178,7 +181,7 @@ class CodiFacesContextWrapper extends Fa
     {
         Set<? extends Bean> broadcasterBeans = this.beanManager.getBeans(BeforeAfterFacesRequestBroadcaster.class);
 
-        if(broadcasterBeans.size() != 1)
+        if (broadcasterBeans.size() != 1)
         {
             //TODO add an exception to the exception context
             return;
@@ -186,7 +189,7 @@ class CodiFacesContextWrapper extends Fa
 
         CreationalContext<BeforeAfterFacesRequestBroadcaster> creationalContext;
 
-        for(Bean<BeforeAfterFacesRequestBroadcaster> requestHandlerBean : broadcasterBeans)
+        for (Bean<BeforeAfterFacesRequestBroadcaster> requestHandlerBean : broadcasterBeans)
         {
             creationalContext = beanManager.createCreationalContext(requestHandlerBean);
 

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/request/DefaultRequestTypeResolver.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/request/DefaultRequestTypeResolver.java?rev=962936&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/request/DefaultRequestTypeResolver.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/request/DefaultRequestTypeResolver.java Sat Jul 10 22:46:47 2010
@@ -0,0 +1,70 @@
+/*
+ * 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.myfaces.extensions.cdi.javaee.jsf.impl.request;
+
+import org.apache.myfaces.extensions.cdi.javaee.jsf.api.request.AbstractRequestTypeResolver;
+import org.apache.myfaces.extensions.cdi.javaee.jsf.api.request.RequestTypeResolver;
+
+import javax.enterprise.context.RequestScoped;
+import javax.faces.FactoryFinder;
+import javax.faces.context.FacesContext;
+import javax.faces.render.RenderKit;
+import javax.faces.render.RenderKitFactory;
+
+/**
+ * @author Gerhard Petracek
+ */
+@RequestScoped
+public class DefaultRequestTypeResolver extends AbstractRequestTypeResolver
+{
+    protected RequestTypeResolver createDefaultRequestTypeResolver()
+    {
+        return new RequestTypeResolver()
+        {
+            private boolean postRequest;
+
+            {
+                //TODO
+                FacesContext facesContext = FacesContext.getCurrentInstance();
+
+                RenderKit renderKit = facesContext.getRenderKit();
+                if (renderKit == null)
+                {
+                    String renderKitId = facesContext.getApplication().getViewHandler()
+                            .calculateRenderKitId(facesContext);
+
+                    RenderKitFactory factory = (RenderKitFactory)
+                            FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
+                    renderKit = factory.getRenderKit(facesContext, renderKitId);
+                }
+                this.postRequest = renderKit.getResponseStateManager().isPostback(facesContext);
+            }
+
+            public boolean isPartialRequest()
+            {
+                return false;
+            }
+
+            public boolean isPostRequest()
+            {
+                return this.postRequest;
+            }
+        };
+    }
+}

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/AccessScopeAwareNavigationHandler.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/AccessScopeAwareNavigationHandler.java?rev=962936&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/AccessScopeAwareNavigationHandler.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/AccessScopeAwareNavigationHandler.java Sat Jul 10 22:46:47 2010
@@ -0,0 +1,67 @@
+/*
+ * 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.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation;
+
+import org.apache.myfaces.extensions.cdi.javaee.jsf.impl.request.CodiFacesContextWrapper;
+
+import javax.faces.application.NavigationHandler;
+import javax.faces.context.FacesContext;
+import java.util.Map;
+
+/**
+ * @author Gerhard Petracek
+ */
+public class AccessScopeAwareNavigationHandler extends NavigationHandler
+{
+    public static final String OLD_VIEW_ID_KEY = "oldViewId";
+    public static final String NEW_VIEW_ID_KEY = "newViewId";
+
+    private NavigationHandler navigationHandler;
+
+    public AccessScopeAwareNavigationHandler(NavigationHandler navigationHandler)
+    {
+        this.navigationHandler = navigationHandler;
+    }
+
+    public void handleNavigation(FacesContext facesContext, String s, String s1)
+    {
+        facesContext = getWrappedFacesContext(facesContext);
+        String oldViewId = facesContext.getViewRoot().getViewId();
+
+        Map requestMap = facesContext.getExternalContext().getRequestMap();
+        requestMap.put(OLD_VIEW_ID_KEY, oldViewId); //don't change the order
+
+        this.navigationHandler.handleNavigation(facesContext, s, s1);
+
+        String newViewId = facesContext.getViewRoot().getViewId();
+
+
+        requestMap.put(NEW_VIEW_ID_KEY, newViewId);
+    }
+
+    //TODO check myfaces core - issue? facesContext is not wrapped here
+    private FacesContext getWrappedFacesContext(FacesContext facesContext)
+    {
+        if(facesContext instanceof CodiFacesContextWrapper)
+        {
+            return facesContext;
+        }
+        return new CodiFacesContextWrapper(facesContext);
+    }
+}

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/BeanStorage.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/BeanStorage.java?rev=962936&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/BeanStorage.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/BeanStorage.java Sat Jul 10 22:46:47 2010
@@ -0,0 +1,101 @@
+/*
+ * 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.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation;
+
+import org.apache.myfaces.extensions.cdi.core.api.manager.BeanManagerProvider;
+import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.UnscopeBeanEvent;
+import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.BeanEntry;
+
+import javax.enterprise.inject.spi.BeanManager;
+import java.io.Serializable;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author Gerhard Petracek
+ */
+class BeanStorage implements Serializable
+{
+    private static final long serialVersionUID = 7020160538290030954L;
+
+    private transient BeanManager beanManager;
+
+    private final Map<Class, BeanEntry<Serializable>> beanMap = new ConcurrentHashMap<Class, BeanEntry<Serializable>>();
+
+    public BeanEntry getBean(Class beanClass)
+    {
+        synchronized (this)
+        {
+            BeanEntry<Serializable> beanEntry = this.beanMap.get(beanClass);
+
+            if (beanEntry == null)
+            {
+                return null;
+            }
+
+            //don't use something like Bean#touch here to ensure that the correct ViewId is used as well
+            return addBean(beanClass, this.beanMap, beanEntry);
+        }
+    }
+
+    public BeanEntry addBean(Class beanClass, BeanEntry<Serializable> beanHolder)
+    {
+        synchronized (this)
+        {
+            return addBean(beanClass, this.beanMap, beanHolder);
+        }
+    }
+
+    private BeanEntry addBean(
+            Class beanClass, Map<Class, BeanEntry<Serializable>> beanMap, BeanEntry<Serializable> beanEntry)
+    {
+        //BeanEntryHolder newBean = new BeanEntryHolder(beanHolder);
+        beanMap.remove(beanClass);
+        beanMap.put(beanClass, beanEntry);
+        //this.beanAccessedEventEvent.fire(new BeanAccessedEvent(bean.getBeanInstance()));
+        return beanEntry;
+    }
+
+    //TODO don't reset window scoped beans
+    public void resetStorage()
+    {
+        Serializable oldBeanInstance;
+        for (BeanEntry<Serializable> beanHolder : this.beanMap.values())
+        {
+            oldBeanInstance = beanHolder.resetBeanInstance();
+            fireUnscopeBeanEvent(oldBeanInstance);
+        }
+    }
+
+    //TODO PreDestroy
+    private void fireUnscopeBeanEvent(Serializable instance)
+    {
+        getOrCreateBeanManager().fireEvent(new UnscopeBeanEvent(instance));
+    }
+
+    private BeanManager getOrCreateBeanManager()
+    {
+        if (this.beanManager == null)
+        {
+            this.beanManager = BeanManagerProvider.getInstance().getBeanManager();
+        }
+
+        return this.beanManager;
+    }
+}

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/CodiRenderKitFactory.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/CodiRenderKitFactory.java?rev=962936&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/CodiRenderKitFactory.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/CodiRenderKitFactory.java Sat Jul 10 22:46:47 2010
@@ -0,0 +1,58 @@
+/*
+ * 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.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation;
+
+import javax.faces.context.FacesContext;
+import javax.faces.render.RenderKit;
+import javax.faces.render.RenderKitFactory;
+import java.util.Iterator;
+
+/**
+ * @author Gerhard Petracek
+ */
+public class CodiRenderKitFactory extends RenderKitFactory
+{
+    private RenderKitFactory wrapped;
+
+    public CodiRenderKitFactory(RenderKitFactory wrapped)
+    {
+        this.wrapped = wrapped;
+    }
+
+    public void addRenderKit(String s, RenderKit renderKit)
+    {
+        wrapped.addRenderKit(s, renderKit);
+    }
+
+    public RenderKit getRenderKit(FacesContext facesContext, String s)
+    {
+        RenderKit renderKit = wrapped.getRenderKit(facesContext, s);
+
+        if (renderKit == null)
+        {
+            return null;
+        }
+        return new InterceptedRenderKit(renderKit);
+    }
+
+    public Iterator<String> getRenderKitIds()
+    {
+        return wrapped.getRenderKitIds();
+    }
+}

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/CodiResponseStateManager.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/CodiResponseStateManager.java?rev=962936&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/CodiResponseStateManager.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/CodiResponseStateManager.java Sat Jul 10 22:46:47 2010
@@ -0,0 +1,69 @@
+/*
+ * 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.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation;
+
+import javax.faces.application.StateManager;
+import javax.faces.context.FacesContext;
+import javax.faces.render.ResponseStateManager;
+import java.io.IOException;
+
+/**
+ * @author Gerhard Petracek
+ */
+class CodiResponseStateManager extends ResponseStateManager
+{
+    private ResponseStateManager wrapped;
+
+    CodiResponseStateManager(ResponseStateManager wrapped)
+    {
+        this.wrapped = wrapped;
+    }
+
+    public void writeState(FacesContext facesContext, Object o)
+            throws IOException
+    {
+        wrapped.writeState(facesContext, o);
+    }
+
+    public void writeState(FacesContext facesContext, StateManager.SerializedView serializedView)
+            throws IOException
+    {
+        wrapped.writeState(facesContext, serializedView);
+    }
+
+    public Object getState(FacesContext facesContext, String s)
+    {
+        return wrapped.getState(facesContext, s);
+    }
+
+    public Object getTreeStructureToRestore(FacesContext facesContext, String s)
+    {
+        return wrapped.getTreeStructureToRestore(facesContext, s);
+    }
+
+    public Object getComponentStateToRestore(FacesContext facesContext)
+    {
+        return wrapped.getComponentStateToRestore(facesContext);
+    }
+
+    public boolean isPostback(FacesContext facesContext)
+    {
+        return wrapped.isPostback(facesContext);
+    }
+}

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultConversation.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultConversation.java?rev=962936&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultConversation.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultConversation.java Sat Jul 10 22:46:47 2010
@@ -0,0 +1,174 @@
+/*
+ * 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.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation;
+
+import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.Conversation;
+import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.grouped.ViewAccess;
+import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.grouped.Window;
+import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.BeanEntry;
+import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.EditableConversation;
+
+import javax.faces.context.FacesContext;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * @author Gerhard Petracek
+ */
+public class DefaultConversation implements Conversation, EditableConversation
+{
+    private static final long serialVersionUID = -2958548175169003298L;
+
+    //for easier debugging
+    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
+    private final Class groupKey;
+
+    private final boolean windowScoped;
+
+    private String lastViewId; //for access scope
+
+    private final BeanStorage beanStorage;
+
+    private final long conversationTimeoutInMs;
+
+    private boolean active;
+
+    private Date lastAccess;
+
+    public DefaultConversation(Class groupKey, int conversationTimeoutInMinutes)
+    {
+        this.groupKey = groupKey;
+        this.windowScoped = Window.class.isAssignableFrom(groupKey);
+
+        if (groupKey.isAnnotationPresent(ViewAccess.class))
+        {
+            this.lastViewId = getCurrentViewId();
+        }
+
+        this.beanStorage = new BeanStorage();
+        this.conversationTimeoutInMs = conversationTimeoutInMinutes * 60000;
+    }
+
+    public boolean isActive()
+    {
+        return !isConversationTimedout() && this.active;
+    }
+
+    public void deactivate()
+    {
+        if (!this.windowScoped)
+        {
+            this.active = false;
+        }
+    }
+
+    public void end()
+    {
+        this.active = false;
+        this.beanStorage.resetStorage();
+    }
+
+    public void restart()
+    {
+        touchConversation();
+        this.beanStorage.resetStorage();
+    }
+
+    @SuppressWarnings({"unchecked"})
+    public <T> T getBean(Class<T> key)
+    {
+        if (!isActive())
+        {
+            return null;
+        }
+
+        touchConversation();
+
+        BeanEntry scopedBean = this.beanStorage.getBean(key);
+
+        if (scopedBean == null)
+        {
+            return null;
+        }
+
+        return (T) scopedBean.getBeanInstance();
+    }
+
+    public <T> void addBean(Class<?> beanClass, BeanEntry<T> beanEntry)
+    {
+        if (beanEntry.getBean().getBeanClass().isAnnotationPresent(ViewAccess.class))
+        {
+            this.lastViewId = getCurrentViewId();
+        }
+
+        //TODO check if conversation is active
+        touchConversation();
+
+        //TODO
+        //noinspection unchecked
+        this.beanStorage.addBean(beanClass, (BeanEntry<Serializable>) beanEntry);
+    }
+
+    /*
+    private BeanEntryHolder createBean(BeanEntry<Serializable> beanEntry)
+    {
+        return new BeanEntryHolder(beanEntry, FacesContext.getCurrentInstance().getViewRoot().getViewId());
+    }
+    */
+
+    private boolean isConversationTimedout()
+    {
+        if (this.windowScoped)
+        {
+            return false;
+        }
+
+        if (this.lastViewId != null)
+        {
+            Map requestMap = FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
+            String fromViewId = (String) requestMap.get(AccessScopeAwareNavigationHandler.OLD_VIEW_ID_KEY);
+
+            if (fromViewId != null && fromViewId.endsWith(this.lastViewId))
+            {
+                this.lastViewId = (String) requestMap.get(AccessScopeAwareNavigationHandler.NEW_VIEW_ID_KEY);
+            }
+            return !this.lastViewId.equals(getCurrentViewId());
+        }
+
+        return this.lastAccess == null ||
+                (this.lastAccess.getTime() + this.conversationTimeoutInMs) < System.currentTimeMillis();
+    }
+
+    private void touchConversation()
+    {
+        this.active = true;
+        this.lastAccess = new Date();
+
+        if (this.lastViewId != null)
+        {
+            this.lastViewId = getCurrentViewId();
+        }
+    }
+
+    private String getCurrentViewId()
+    {
+        return FacesContext.getCurrentInstance().getViewRoot().getViewId();
+    }
+}

Copied: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultWindowContextManager.java (from r962434, myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultConversationManager.java)
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultWindowContextManager.java?p2=myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultWindowContextManager.java&p1=myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultConversationManager.java&r1=962434&r2=962936&rev=962936&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultConversationManager.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/DefaultWindowContextManager.java Sat Jul 10 22:46:47 2010
@@ -18,53 +18,249 @@
  */
 package org.apache.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation;
 
-import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.grouped.spi.ConversationManager;
-import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.ConversationContext;
+import org.apache.myfaces.extensions.cdi.core.api.resolver.ConfigResolver;
+import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.Conversation;
+import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowContext;
+import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowContextConfig;
+import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.WindowContextManager;
+import org.apache.myfaces.extensions.cdi.javaee.jsf.api.listener.phase.AfterPhase;
+import org.apache.myfaces.extensions.cdi.javaee.jsf.api.listener.phase.PhaseId;
+import org.apache.myfaces.extensions.cdi.javaee.jsf.api.request.RequestTypeResolver;
+import org.apache.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation.grouped.JsfWindowContext;
+import org.apache.myfaces.extensions.cdi.javaee.jsf.impl.util.ConversationUtils;
+import static org.apache.myfaces.extensions.cdi.javaee.jsf.impl.util.ConversationUtils.resolveWindowContextId;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.context.SessionScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Produces;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseEvent;
+import javax.inject.Inject;
+import javax.inject.Named;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
 
 /**
+ * TODO don't cleanup in case of partial requests (via RequestTypeResolver)
+ *
  * @author Gerhard Petracek
  */
-public class DefaultConversationManager implements ConversationManager
+@Named("windowContextManager")
+@SessionScoped
+public class DefaultWindowContextManager implements WindowContextManager
 {
-    public ConversationContext getCurrentConversationContext()
+    private static final long serialVersionUID = 2872151847183166424L;
+
+    private Map<Long, WindowContext> windowContextMap = new ConcurrentHashMap<Long, WindowContext>();
+
+    //TODO refactor to UUID?
+    private AtomicLong lastWindowContextId = new AtomicLong(0);
+
+    @Inject
+    @SuppressWarnings({"UnusedDeclaration"})
+    private ConfigResolver configResolver;
+
+    private WindowContextConfig conversationContextConfig;
+
+    @PostConstruct
+    protected void init()
+    {
+        conversationContextConfig = this.configResolver.resolve(WindowContextConfig.class);
+    }
+
+    //don't change/optimize this observer!!!
+    protected void cleanup(@Observes @AfterPhase(PhaseId.RESTORE_VIEW) PhaseEvent phaseEvent,
+                           RequestTypeResolver requestTypeResolver)
+    {
+        //restore view-id in case of a get request - we need it esp. for redirects
+        if (!requestTypeResolver.isPostRequest())
+        {
+            phaseEvent.getFacesContext().getExternalContext().getRequestMap()
+                    .put(AccessScopeAwareNavigationHandler.NEW_VIEW_ID_KEY,
+                            phaseEvent.getFacesContext().getViewRoot().getViewId());
+
+            String oldViewId = phaseEvent.getFacesContext().getExternalContext().getRequestParameterMap()
+                    .get(AccessScopeAwareNavigationHandler.OLD_VIEW_ID_KEY);
+
+            if (oldViewId != null)
+            {
+                phaseEvent.getFacesContext().getExternalContext().getRequestMap()
+                        .put(AccessScopeAwareNavigationHandler.OLD_VIEW_ID_KEY, oldViewId);
+            }
+        }
+
+        //for performance reasons + cleanup at the beginning of the request (check timeout,...)
+        //+ we aren't allowed to cleanup in case of redirects
+        //we would transfer the restored view-id into the conversation
+        if (requestTypeResolver.isPartialRequest() || !requestTypeResolver.isPostRequest())
+        {
+            return;
+        }
+
+        for (WindowContext conversationContext : this.windowContextMap.values())
+        {
+            for (Conversation conversation : conversationContext.getConversations().values())
+            {
+                if (!conversation.isActive())
+                {
+                    conversation.end();
+                }
+            }
+
+            conversationContext.cleanup();
+        }
+    }
+
+    @Produces
+    @Named(WindowContext.CURRENT_WINDOW_CONTEXT_BEAN_NAME)
+    @RequestScoped
+    protected WindowContext currentWindowContext()
+    {
+        return getCurrentWindowContext();
+    }
+
+    //TODO improve performance
+    public WindowContext getCurrentWindowContext()
+    {
+        Long windowContextId = resolveWindowContextId(this.conversationContextConfig.isGetRequestParameterSupported());
+
+        if (windowContextId == null)
+        {
+            windowContextId = this.lastWindowContextId.incrementAndGet();
+        }
+
+        return getWindowContext(windowContextId);
+    }
+
+    public WindowContext getWindowContext(long windowContextId)
+    {
+        synchronized (this)
+        {
+            WindowContext result = this.windowContextMap.get(windowContextId);
+
+            if (result == null)
+            {
+                result = new JsfWindowContext(windowContextId, this.conversationContextConfig);
+
+                this.windowContextMap.put(windowContextId, result);
+            }
+            return result;
+        }
+    }
+
+    public void activateWindowContext(long id)
+    {
+        activateWindowContext(getWindowContext(id));
+    }
+
+    public void activateWindowContext(WindowContext conversationContext)
+    {
+        FacesContext facesContext = FacesContext.getCurrentInstance();
+        WindowContextIdHolderComponent conversationContextIdHolder =
+                ConversationUtils.getWindowContextIdHolderComponent(facesContext);
+
+        if (conversationContextIdHolder != null)
+        {
+            conversationContextIdHolder.changeWindowContextId(conversationContext.getId());
+        }
+
+        setWindowContextIdOfRequest(facesContext, conversationContext.getId());
+    }
+
+    //TODO
+    public void resetCurrentWindowContext()
     {
-        //TODO impl. it
-        throw new IllegalStateException("not implemented");
+        resetWindowContext(getCurrentWindowContext());
     }
 
-    public ConversationContext getConversationContext(Long id)
+    //TODO
+    public void resetWindowContext(long id)
     {
-        //TODO impl. it
-        throw new IllegalStateException("not implemented");
+        resetWindowContext(getWindowContext(id));
     }
 
-    public void activateConversationContext(ConversationContext conversationContext)
+    public void resetWindowContext(WindowContext windowContext)
     {
-        //TODO impl. it
-        throw new IllegalStateException("not implemented");
+        for (Conversation conversation : windowContext.getConversations().values())
+        {
+            conversation.restart();
+        }
     }
 
-    public void resetCurrentConversationContext()
+    public void resetConversations()
     {
-        //TODO impl. it
-        throw new IllegalStateException("not implemented");
+        resetConversations(getCurrentWindowContext());
     }
 
-    public void resetConversationContext(ConversationContext conversationContext)
+    public void resetConversations(long windowContextId)
     {
-        //TODO impl. it
-        throw new IllegalStateException("not implemented");
+        resetConversations(getWindowContext(windowContextId));
     }
 
-    public void removeCurrentConversationContext()
+    public void resetConversations(WindowContext windowContext)
     {
-        //TODO impl. it
-        throw new IllegalStateException("not implemented");
+        for (Conversation conversation : windowContext.getConversations().values())
+        {
+            conversation.deactivate();
+            if (!conversation.isActive()) //it isn't possible to deactivate window scoped conversations
+            {
+                conversation.restart();
+            }
+        }
     }
 
-    public void removeConversationContext(ConversationContext conversationContext)
+    public void removeCurrentWindowContext()
     {
-        //TODO impl. it
-        throw new IllegalStateException("not implemented");
+        removeWindowContext(getCurrentWindowContext());
+    }
+
+    public void removeWindowContext(long id)
+    {
+        removeWindowContext(getWindowContext(id));
+    }
+
+    public void removeWindowContext(WindowContext conversationContext)
+    {
+        this.windowContextMap.remove(conversationContext.getId());
+
+        FacesContext facesContext = FacesContext.getCurrentInstance();
+        removeConversationContextIdHolderComponent(facesContext);
+        setWindowContextIdOfRequest(facesContext, null);
+
+        conversationContext.endConversations();
+    }
+
+
+    private void setWindowContextIdOfRequest(FacesContext facesContext, Long newId)
+    {
+        Map requestMap = facesContext.getExternalContext().getRequestMap();
+
+        if (newId != null)
+        {
+            //noinspection unchecked
+            requestMap.put(WindowContextManager.WINDOW_CONTEXT_ID_PARAMETER_KEY, newId);
+        }
+        requestMap.remove(WindowContextManager.WINDOW_CONTEXT_ID_PARAMETER_KEY);
+    }
+
+    private void removeConversationContextIdHolderComponent(FacesContext facesContext)
+    {
+        Iterator<UIComponent> uiComponents = facesContext.getViewRoot().getChildren().iterator();
+
+        UIComponent uiComponent;
+        while (uiComponents.hasNext())
+        {
+            uiComponent = uiComponents.next();
+            if (uiComponent instanceof WindowContextIdHolderComponent)
+            {
+                uiComponents.remove();
+                return;
+            }
+        }
     }
 }

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/InterceptedRenderKit.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/InterceptedRenderKit.java?rev=962936&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/InterceptedRenderKit.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/InterceptedRenderKit.java Sat Jul 10 22:46:47 2010
@@ -0,0 +1,72 @@
+/*
+ * 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.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation;
+
+import javax.faces.context.ResponseStream;
+import javax.faces.context.ResponseWriter;
+import javax.faces.render.RenderKit;
+import javax.faces.render.Renderer;
+import javax.faces.render.ResponseStateManager;
+import java.io.OutputStream;
+import java.io.Writer;
+
+/**
+ * @author Gerhard Petracek
+ */
+class InterceptedRenderKit extends RenderKit
+{
+    private RenderKit renderKit;
+
+    public InterceptedRenderKit(RenderKit renderKit)
+    {
+        this.renderKit = renderKit;
+    }
+
+    public void addRenderer(String s, String s1, Renderer renderer)
+    {
+        renderKit.addRenderer(s, s1, renderer);
+    }
+
+    public Renderer getRenderer(String s, String s1)
+    {
+        return renderKit.getRenderer(s, s1);
+    }
+
+    public ResponseStateManager getResponseStateManager()
+    {
+        return renderKit.getResponseStateManager();
+    }
+
+    public ResponseWriter createResponseWriter(Writer writer, String s, String s1)
+    {
+        ResponseWriter responseWriter = renderKit.createResponseWriter(writer, s, s1);
+
+        if (responseWriter == null)
+        {
+            return null;
+        }
+
+        return new InterceptedResponseWriter(responseWriter);
+    }
+
+    public ResponseStream createResponseStream(OutputStream outputStream)
+    {
+        return renderKit.createResponseStream(outputStream);
+    }
+}

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/InterceptedResponseWriter.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/InterceptedResponseWriter.java?rev=962936&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/InterceptedResponseWriter.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/InterceptedResponseWriter.java Sat Jul 10 22:46:47 2010
@@ -0,0 +1,216 @@
+/*
+ * 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.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation;
+
+import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.WindowContextManager;
+import org.apache.myfaces.extensions.cdi.core.impl.utils.CodiUtils;
+import org.apache.myfaces.extensions.cdi.javaee.jsf.impl.util.ConversationUtils;
+
+import javax.enterprise.inject.spi.Bean;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.List;
+
+/**
+ * Adds
+ * {@link WindowContextIdHolderComponent}
+ * to the tree before the call of {@link #startDocument}
+ *
+ * @author Gerhard Petracek
+ */
+class InterceptedResponseWriter extends ResponseWriter
+{
+    private ResponseWriter wrapped;
+
+    InterceptedResponseWriter(ResponseWriter wrapped)
+    {
+        this.wrapped = wrapped;
+    }
+
+    private boolean isWindowContextIdHolderComponentAvailable()
+    {
+        List<UIComponent> uiComponents = FacesContext.getCurrentInstance().getViewRoot().getChildren();
+        for (UIComponent uiComponent : uiComponents)
+        {
+            if (uiComponent instanceof WindowContextIdHolderComponent)
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private void addWindowContextIdHolderComponent()
+    {
+        FacesContext.getCurrentInstance().getViewRoot().getChildren()
+                .add(createComponentWithCurrentConversationContextId());
+    }
+
+    private WindowContextIdHolderComponent createComponentWithCurrentConversationContextId()
+    {
+        Bean<WindowContextManager> conversationManagerBean = ConversationUtils.resolveConversationManagerBean();
+
+        WindowContextManager conversationManager = CodiUtils.getOrCreateScopedInstanceOfBean(conversationManagerBean);
+
+        return new WindowContextIdHolderComponent(conversationManager.getCurrentWindowContext().getId());
+    }
+
+    public String getContentType()
+    {
+        return wrapped.getContentType();
+    }
+
+    public String getCharacterEncoding()
+    {
+        return wrapped.getCharacterEncoding();
+    }
+
+    public void flush()
+            throws IOException
+    {
+        wrapped.flush();
+    }
+
+    public void startDocument()
+            throws IOException
+    {
+        if (!isWindowContextIdHolderComponentAvailable())
+        {
+            addWindowContextIdHolderComponent();
+        }
+        wrapped.startDocument();
+    }
+
+    public void endDocument()
+            throws IOException
+    {
+        wrapped.endDocument();
+    }
+
+    public void startElement(String s, UIComponent uiComponent)
+            throws IOException
+    {
+        wrapped.startElement(s, uiComponent);
+    }
+
+    public void endElement(String s)
+            throws IOException
+    {
+        wrapped.endElement(s);
+    }
+
+    public void writeAttribute(String s, Object o, String s1)
+            throws IOException
+    {
+        wrapped.writeAttribute(s, o, s1);
+    }
+
+    public void writeURIAttribute(String s, Object o, String s1)
+            throws IOException
+    {
+        wrapped.writeURIAttribute(s, o, s1);
+    }
+
+    public void writeComment(Object o)
+            throws IOException
+    {
+        wrapped.writeComment(o);
+    }
+
+    public void writeText(Object o, String s)
+            throws IOException
+    {
+        wrapped.writeText(o, s);
+    }
+
+    public void writeText(char[] chars, int i, int i1)
+            throws IOException
+    {
+        wrapped.writeText(chars, i, i1);
+    }
+
+    public ResponseWriter cloneWithWriter(Writer writer)
+    {
+        return wrapped.cloneWithWriter(writer);
+    }
+
+    public void writeText(Object o, UIComponent uiComponent, String s)
+            throws IOException
+    {
+        wrapped.writeText(o, uiComponent, s);
+    }
+
+    public void close()
+            throws IOException
+    {
+        wrapped.close();
+    }
+
+    public Writer append(char c)
+            throws IOException
+    {
+        return wrapped.append(c);
+    }
+
+    public Writer append(CharSequence csq, int start, int end)
+            throws IOException
+    {
+        return wrapped.append(csq, start, end);
+    }
+
+    public Writer append(CharSequence csq)
+            throws IOException
+    {
+        return wrapped.append(csq);
+    }
+
+    public void write(String str, int off, int len)
+            throws IOException
+    {
+        wrapped.write(str, off, len);
+    }
+
+    public void write(String str)
+            throws IOException
+    {
+        wrapped.write(str);
+    }
+
+    public void write(char[] cbuf, int off, int len)
+            throws IOException
+    {
+        wrapped.write(cbuf, off, len);
+    }
+
+    public void write(char[] cbuf)
+            throws IOException
+    {
+        wrapped.write(cbuf);
+    }
+
+    public void write(int c)
+            throws IOException
+    {
+        wrapped.write(c);
+    }
+}

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/RedirectedConversationAwareExternalContext.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/RedirectedConversationAwareExternalContext.java?rev=962936&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/RedirectedConversationAwareExternalContext.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/RedirectedConversationAwareExternalContext.java Sat Jul 10 22:46:47 2010
@@ -0,0 +1,277 @@
+/*
+ * 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.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation;
+
+import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.WindowContextManager;
+import org.apache.myfaces.extensions.cdi.javaee.jsf.impl.util.ConversationUtils;
+
+import javax.faces.context.ExternalContext;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.Principal;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Gerhard Petracek
+ */
+public class RedirectedConversationAwareExternalContext extends ExternalContext
+{
+    private ExternalContext wrapped;
+
+    public RedirectedConversationAwareExternalContext(ExternalContext wrapped)
+    {
+        this.wrapped = wrapped;
+    }
+
+    public void dispatch(String s)
+            throws IOException
+    {
+        wrapped.dispatch(s);
+    }
+
+    public String encodeActionURL(String s)
+    {
+        return wrapped.encodeActionURL(s);
+    }
+
+    private Long resolveWindowContextId()
+    {
+        return ConversationUtils.resolveWindowContextId(false
+                /*TODO log warning if request parameter is disabled - we have to use false here*/);
+    }
+
+    public String encodeNamespace(String s)
+    {
+        return wrapped.encodeNamespace(s);
+    }
+
+    public String encodeResourceURL(String s)
+    {
+        return wrapped.encodeResourceURL(s);
+    }
+
+    public Map<String, Object> getApplicationMap()
+    {
+        return wrapped.getApplicationMap();
+    }
+
+    public String getAuthType()
+    {
+        return wrapped.getAuthType();
+    }
+
+    public Object getContext()
+    {
+        return wrapped.getContext();
+    }
+
+    public String getInitParameter(String s)
+    {
+        return wrapped.getInitParameter(s);
+    }
+
+    public Map getInitParameterMap()
+    {
+        return wrapped.getInitParameterMap();
+    }
+
+    public String getRemoteUser()
+    {
+        return wrapped.getRemoteUser();
+    }
+
+    public Object getRequest()
+    {
+        return wrapped.getRequest();
+    }
+
+    public String getRequestCharacterEncoding()
+    {
+        return wrapped.getRequestCharacterEncoding();
+    }
+
+    public String getRequestContentType()
+    {
+        return wrapped.getRequestContentType();
+    }
+
+    public String getRequestContextPath()
+    {
+        return wrapped.getRequestContextPath();
+    }
+
+    public Map<String, Object> getRequestCookieMap()
+    {
+        return wrapped.getRequestCookieMap();
+    }
+
+    public Map<String, String> getRequestHeaderMap()
+    {
+        return wrapped.getRequestHeaderMap();
+    }
+
+    public Map<String, String[]> getRequestHeaderValuesMap()
+    {
+        return wrapped.getRequestHeaderValuesMap();
+    }
+
+    public Locale getRequestLocale()
+    {
+        return wrapped.getRequestLocale();
+    }
+
+    public Iterator<Locale> getRequestLocales()
+    {
+        return wrapped.getRequestLocales();
+    }
+
+    public Map<String, Object> getRequestMap()
+    {
+        return wrapped.getRequestMap();
+    }
+
+    public Map<String, String> getRequestParameterMap()
+    {
+        return wrapped.getRequestParameterMap();
+    }
+
+    public Iterator<String> getRequestParameterNames()
+    {
+        return wrapped.getRequestParameterNames();
+    }
+
+    public Map<String, String[]> getRequestParameterValuesMap()
+    {
+        return wrapped.getRequestParameterValuesMap();
+    }
+
+    public String getRequestPathInfo()
+    {
+        return wrapped.getRequestPathInfo();
+    }
+
+    public String getRequestServletPath()
+    {
+        return wrapped.getRequestServletPath();
+    }
+
+    public URL getResource(String s)
+            throws MalformedURLException
+    {
+        return wrapped.getResource(s);
+    }
+
+    public InputStream getResourceAsStream(String s)
+    {
+        return wrapped.getResourceAsStream(s);
+    }
+
+    public Set<String> getResourcePaths(String s)
+    {
+        return wrapped.getResourcePaths(s);
+    }
+
+    public Object getResponse()
+    {
+        return wrapped.getResponse();
+    }
+
+    public String getResponseContentType()
+    {
+        return wrapped.getResponseContentType();
+    }
+
+    public Object getSession(boolean b)
+    {
+        return wrapped.getSession(b);
+    }
+
+    public Map<String, Object> getSessionMap()
+    {
+        return wrapped.getSessionMap();
+    }
+
+    public Principal getUserPrincipal()
+    {
+        return wrapped.getUserPrincipal();
+    }
+
+    public void setRequest(Object o)
+    {
+        wrapped.setRequest(o);
+    }
+
+    public void setRequestCharacterEncoding(String s)
+            throws UnsupportedEncodingException
+    {
+        wrapped.setRequestCharacterEncoding(s);
+    }
+
+    public void setResponse(Object o)
+    {
+        wrapped.setResponse(o);
+    }
+
+    public void setResponseCharacterEncoding(String s)
+    {
+        wrapped.setResponseCharacterEncoding(s);
+    }
+
+    public String getResponseCharacterEncoding()
+    {
+        return wrapped.getResponseCharacterEncoding();
+    }
+
+    public boolean isUserInRole(String s)
+    {
+        return wrapped.isUserInRole(s);
+    }
+
+    public void log(String s)
+    {
+        wrapped.log(s);
+    }
+
+    public void log(String s, Throwable throwable)
+    {
+        wrapped.log(s, throwable);
+    }
+
+    public void redirect(String url)
+            throws IOException
+    {
+        Long windowContextId = resolveWindowContextId();
+
+        if (windowContextId != null)
+        {
+            url = url + "?" + WindowContextManager.WINDOW_CONTEXT_ID_PARAMETER_KEY + "=" + windowContextId
+                    + "&" + AccessScopeAwareNavigationHandler.OLD_VIEW_ID_KEY + "=" +
+                    getRequestMap().get(AccessScopeAwareNavigationHandler.OLD_VIEW_ID_KEY);
+            url = this.wrapped.encodeActionURL(url);
+        }
+
+        this.wrapped.redirect(url);
+    }
+}

Added: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/WindowContextIdHolderComponent.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/WindowContextIdHolderComponent.java?rev=962936&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/WindowContextIdHolderComponent.java (added)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/WindowContextIdHolderComponent.java Sat Jul 10 22:46:47 2010
@@ -0,0 +1,76 @@
+/*
+ * 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.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation;
+
+import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.WindowContextManager;
+
+import javax.faces.component.UIOutput;
+import javax.faces.context.FacesContext;
+
+/**
+ * @author Gerhard Petracek
+ */
+public class WindowContextIdHolderComponent extends UIOutput
+{
+    private long windowContextId;
+
+    public WindowContextIdHolderComponent()
+    {
+    }
+
+    public WindowContextIdHolderComponent(long windowContextId)
+    {
+        this.windowContextId = windowContextId;
+    }
+
+
+    public Object saveState(FacesContext facesContext)
+    {
+        Object[] values = new Object[2];
+        values[0] = super.saveState(facesContext);
+        values[1] = this.windowContextId;
+        return values;
+    }
+
+    public void restoreState(FacesContext facesContext, Object state)
+    {
+        if (state == null)
+        {
+            return;
+        }
+
+        Object[] values = (Object[]) state;
+        super.restoreState(facesContext, values[0]);
+
+        this.windowContextId = (Long) values[1];
+
+        facesContext.getExternalContext().getRequestMap()
+                .put(WindowContextManager.WINDOW_CONTEXT_ID_PARAMETER_KEY, this.windowContextId);
+    }
+
+    public long getWindowContextId()
+    {
+        return windowContextId;
+    }
+
+    void changeWindowContextId(long conversationContextId)
+    {
+        this.windowContextId = conversationContextId;
+    }
+}

Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/grouped/GroupedConversationContextAdapter.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/grouped/GroupedConversationContextAdapter.java?rev=962936&r1=962935&r2=962936&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/grouped/GroupedConversationContextAdapter.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/grouped/GroupedConversationContextAdapter.java Sat Jul 10 22:46:47 2010
@@ -18,22 +18,25 @@
  */
 package org.apache.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation.grouped;
 
-import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.grouped.spi.ConversationManager;
-import org.apache.myfaces.extensions.cdi.core.api.tools.annotate.DefaultAnnotation;
-import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.grouped.AbstractGroupedConversationContextAdapter;
-import org.apache.myfaces.extensions.cdi.javaee.jsf.api.qualifier.Jsf;
+import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.Conversation;
+import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.grouped.ConversationGroup;
+import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.grouped.Window;
+import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.AbstractConversationContextAdapter;
+import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.BeanEntry;
+import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.EditableConversation;
+import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.WindowContextManager;
+import org.apache.myfaces.extensions.cdi.javaee.jsf.impl.util.ConversationUtils;
 
 import javax.enterprise.inject.spi.Bean;
 import javax.enterprise.inject.spi.BeanManager;
 import javax.faces.context.FacesContext;
-import java.util.Set;
 
 /**
  * jsf specific parts for managing grouped conversations
  *
  * @author Gerhard Petracek
  */
-public class GroupedConversationContextAdapter extends AbstractGroupedConversationContextAdapter
+public class GroupedConversationContextAdapter extends AbstractConversationContextAdapter
 {
     public GroupedConversationContextAdapter(BeanManager beanManager)
     {
@@ -42,8 +45,8 @@ public class GroupedConversationContextA
 
     /**
      * @return true as soon as JSF is active
-     * the {@link org.apache.myfaces.extensions.cdi.core.api.scope.conversation.ConversationContext}
-     * will be created automatically
+     *         the {@link org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowContext}
+     *         will be created automatically
      */
     public boolean isActive()
     {
@@ -51,24 +54,61 @@ public class GroupedConversationContextA
     }
 
     /**
-     * @return the descriptor of a custom {@link ConversationManager} with the qualifier {@link Jsf} or
-     * the descriptor of the default implementation provided by this module
+     * @return the descriptor of a custom
+     * {@link org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.WindowContextManager}
+     * with the qualifier {@link org.apache.myfaces.extensions.cdi.javaee.jsf.api.qualifier.Jsf} or
+     *         the descriptor of the default implementation provided by this module
      */
-    protected Bean<ConversationManager> resolveConversationManagerBean()
+    protected Bean<WindowContextManager> resolveConversationManagerBean()
     {
-        Set<?> conversationManagerBeans = this.beanManager.getBeans(
-                ConversationManager.class, DefaultAnnotation.of(Jsf.class));
+        return ConversationUtils.resolveConversationManagerBean();
+    }
+
+    /**
+     * @param conversationManager the current
+     * {@link org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.WindowContextManager}
+     * @param beanDescriptor      descriptor of the requested bean
+     * @return the instance of the requested bean if it exists in the current
+     *         {@link org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowContext}
+     *         null otherwise
+     */
+    protected <T> T resolveBeanInstance(WindowContextManager conversationManager, Bean<T> beanDescriptor)
+    {
+        Class<?> beanClass = beanDescriptor.getBeanClass();
+        Conversation foundConversation = getConversation(conversationManager, beanClass);
+
+        //noinspection unchecked
+        return (T) foundConversation.getBean(beanClass);
+    }
+
+    protected <T> void scopeBeanEntry(WindowContextManager conversationManager, BeanEntry<T> beanEntry)
+    {
+        Class<?> beanClass = beanEntry.getBean().getBeanClass();
+        Conversation foundConversation = getConversation(conversationManager, beanClass);
 
-        if(conversationManagerBeans.isEmpty())
+        ((EditableConversation) foundConversation).addBean(beanClass, beanEntry);
+    }
+
+    private Conversation getConversation(WindowContextManager conversationManager, Class<?> beanClass)
+    {
+        Class conversationGroup = getConversationGroup(beanClass);
+
+        return conversationManager.getCurrentWindowContext().getConversation(conversationGroup);
+    }
+
+    private Class getConversationGroup(Class<?> beanClass)
+    {
+        ConversationGroup conversationGroupAnnotation = beanClass.getAnnotation(ConversationGroup.class);
+
+        if (conversationGroupAnnotation != null)
         {
-            conversationManagerBeans = getDefaultConversationManager();
+            return conversationGroupAnnotation.value();
         }
 
-        if(conversationManagerBeans.size() != 1)
+        if (beanClass.isAnnotationPresent(Window.class))
         {
-            throw new IllegalStateException(conversationManagerBeans.size() + " conversation-managers were found");
+            return Window.class;
         }
-        //noinspection unchecked
-        return (Bean<ConversationManager>)conversationManagerBeans.iterator().next();
+        return beanClass;
     }
 }
\ No newline at end of file

Copied: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/grouped/JsfWindowContext.java (from r962434, myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/grouped/JsfConversationContext.java)
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/grouped/JsfWindowContext.java?p2=myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/grouped/JsfWindowContext.java&p1=myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/grouped/JsfConversationContext.java&r1=962434&r2=962936&rev=962936&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/grouped/JsfConversationContext.java (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/java/org/apache/myfaces/extensions/cdi/javaee/jsf/impl/scope/conversation/grouped/JsfWindowContext.java Sat Jul 10 22:46:47 2010
@@ -18,28 +18,34 @@
  */
 package org.apache.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation.grouped;
 
-import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.ConversationContext;
 import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.Conversation;
-import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.ConversationContextConfig;
+import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowContext;
+import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowContextConfig;
+import org.apache.myfaces.extensions.cdi.javaee.jsf.impl.scope.conversation.DefaultConversation;
 
-import javax.enterprise.context.SessionScoped;
+import java.util.Collections;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * TODO
+ *
  * @author Gerhard Petracek
  */
-@SessionScoped
-public class JsfConversationContext implements ConversationContext
+public class JsfWindowContext implements WindowContext
 {
     private static final long serialVersionUID = 5272798129165017829L;
 
-    private Long id;
-    private ConversationContextConfig config;
+    private final Long id;
 
-    public JsfConversationContext(Long id, ConversationContextConfig config)
+    private final WindowContextConfig config;
+
+    private final Map<Class, Conversation> groupedConversations = new ConcurrentHashMap<Class, Conversation>();
+
+    public JsfWindowContext(Long conversationContextId, WindowContextConfig config)
     {
-        this.id = id;
+        this.id = conversationContextId;
         this.config = config;
     }
 
@@ -48,32 +54,79 @@ public class JsfConversationContext impl
         return this.id;
     }
 
-    public void invalidate()
+    public synchronized void endConversations()
     {
-        //TODO impl. it
-        throw new IllegalStateException("not implemented");
+        for (Map.Entry<Class, Conversation> conversationEntry : this.groupedConversations.entrySet())
+        {
+            endAndRemoveConversation(conversationEntry.getKey(), conversationEntry.getValue());
+        }
     }
 
-    public Conversation getConversation(Class conversationGroup)
+    public Conversation getConversation(Class conversationGroupKey)
     {
-        throw new IllegalStateException("not implemented");
+        Conversation conversation = this.groupedConversations.get(conversationGroupKey);
+
+        if (conversation != null && !conversation.isActive())
+        {
+            endAndRemoveConversation(conversationGroupKey, conversation);
+            conversation = null;
+        }
+
+        if (conversation == null)
+        {
+            conversation = createConversation(conversationGroupKey);
+            this.groupedConversations.put(conversationGroupKey, conversation);
+        }
+        return conversation;
+    }
+
+    public Conversation endConversation(Class conversationGroupKey)
+    {
+        Conversation conversation = this.groupedConversations.get(conversationGroupKey);
+        return endAndRemoveConversation(conversationGroupKey, conversation);
+    }
+
+    public Conversation endAndRemoveConversation(Class conversationGroupKey, Conversation conversation)
+    {
+        if (conversation.isActive())
+        {
+            conversation.end();
+        }
+
+        return this.groupedConversations.remove(conversationGroupKey);
     }
 
     public Conversation createConversation(Class conversationGroup)
     {
-        throw new IllegalStateException("not implemented");
+        return new DefaultConversation(conversationGroup, this.config.getConversationTimeoutInMinutes());
     }
 
     public Map<Class /*conversation group*/, Conversation> getConversations()
     {
-        throw new IllegalStateException("not implemented");
+        return Collections.unmodifiableMap(this.groupedConversations);
     }
 
-    public ConversationContextConfig getConfig()
+    public WindowContextConfig getConfig()
     {
         return this.config;
     }
 
+    public void cleanup()
+    {
+        Iterator<Conversation> conversations = this.groupedConversations.values().iterator();
+
+        Conversation conversation;
+        while (conversations.hasNext())
+        {
+            conversation = conversations.next();
+
+            if (!conversation.isActive())
+            {
+                conversations.remove();
+            }
+        }
+    }
+
     public boolean setAttribute(String name, Object value)
     {
         throw new IllegalStateException("not implemented");