[seam-commits] Seam SVN: r12528 - in modules/wicket: tags and 30 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Tue Apr 20 12:15:15 EDT 2010


Author: pete.muir at jboss.org
Date: 2010-04-20 12:15:07 -0400 (Tue, 20 Apr 2010)
New Revision: 12528

Added:
   modules/wicket/branches/
   modules/wicket/tags/
   modules/wicket/tags/1.0.1-CR2/
   modules/wicket/tags/1.0.1-CR2/pom.xml
   modules/wicket/tags/1.0.1-CR2/src/
   modules/wicket/tags/1.0.1-CR2/src/main/
   modules/wicket/tags/1.0.1-CR2/src/main/java/
   modules/wicket/tags/1.0.1-CR2/src/main/java/org/
   modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/
   modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/
   modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/
   modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/BeanManagerLookup.java
   modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldApplication.java
   modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldComponentInstantiationListener.java
   modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldMetaData.java
   modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldRequestCycle.java
   modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldWebRequestCycleProcessor.java
   modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/util/
   modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/util/NonContextual.java
   modules/wicket/tags/1.0.1-CR2/src/main/resources/
   modules/wicket/tags/1.0.1-CR2/src/main/resources/META-INF/
   modules/wicket/tags/1.0.1-Final/
   modules/wicket/tags/1.0.1-Final/pom.xml
   modules/wicket/tags/1.0.1-Final/src/
   modules/wicket/tags/1.0.1-Final/src/main/
   modules/wicket/tags/1.0.1-Final/src/main/java/
   modules/wicket/tags/1.0.1-Final/src/main/java/org/
   modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/
   modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/
   modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/
   modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/BeanManagerLookup.java
   modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldApplication.java
   modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldComponentInstantiationListener.java
   modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldMetaData.java
   modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldRequestCycle.java
   modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldWebRequestCycleProcessor.java
   modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/util/
   modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/util/NonContextual.java
   modules/wicket/tags/1.0.1-Final/src/main/resources/
   modules/wicket/tags/1.0.1-Final/src/main/resources/META-INF/
   modules/wicket/trunk/
   modules/wicket/trunk/pom.xml
   modules/wicket/trunk/src/
   modules/wicket/trunk/src/main/
   modules/wicket/trunk/src/main/java/
   modules/wicket/trunk/src/main/java/org/
   modules/wicket/trunk/src/main/java/org/jboss/
   modules/wicket/trunk/src/main/java/org/jboss/weld/
   modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/
   modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/BeanManagerLookup.java
   modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldApplication.java
   modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldComponentInstantiationListener.java
   modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldMetaData.java
   modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldRequestCycle.java
   modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldWebRequestCycleProcessor.java
   modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/util/
   modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/util/NonContextual.java
   modules/wicket/trunk/src/main/resources/
   modules/wicket/trunk/src/main/resources/META-INF/
Log:
initial import of wicket

Added: modules/wicket/tags/1.0.1-CR2/pom.xml
===================================================================
--- modules/wicket/tags/1.0.1-CR2/pom.xml	                        (rev 0)
+++ modules/wicket/tags/1.0.1-CR2/pom.xml	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,124 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+   <parent>
+      <groupId>org.jboss.weld</groupId>
+      <artifactId>weld-parent</artifactId>
+      <version>9</version>
+   </parent>
+   <modelVersion>4.0.0</modelVersion>
+   <groupId>org.jboss.weld</groupId>
+   <artifactId>weld-wicket</artifactId>
+   <version>1.0.1-CR2</version>
+   <name>Weld Wicket support</name>
+
+   <description>Weld support for Apache Wicket</description>
+
+   <developers>
+      <developer>
+         <name>Clint Popetz</name>
+         <roles>
+            <role>Module lead</role>
+         </roles>
+      </developer>
+   </developers>
+   
+   <url>http://www.seamframework.org/Weld</url>
+   <licenses>
+      <license>
+         <name>Apache License, Version 2.0</name>
+         <distribution>repo</distribution>
+         <url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
+      </license>
+   </licenses>
+
+   <issueManagement>
+      <system>JIRA</system>
+      <url>https://jira.jboss.org/jira/browse/WELDX/component/12312752</url>
+   </issueManagement>
+
+
+
+   <properties>
+      <weld.api.version>1.0-SP1</weld.api.version>
+      <weld.core.version>1.0.1-CR2</weld.core.version>
+      <testng.version>5.10</testng.version>
+      <wicket.version>1.4.1</wicket.version>
+   </properties>
+
+   <!-- Import the BOMs -->
+   <dependencyManagement>
+      <dependencies>
+         <dependency>
+            <groupId>org.jboss.weld</groupId>
+            <artifactId>weld-api-bom</artifactId>
+            <version>${weld.api.version}</version>
+            <type>pom</type>
+            <scope>import</scope>
+         </dependency>
+         <dependency>
+            <groupId>org.jboss.weld</groupId>
+            <artifactId>weld-core-bom</artifactId>
+            <version>${weld.core.version}</version>
+            <type>pom</type>
+            <scope>import</scope>
+         </dependency>
+         <dependency>
+            <groupId>org.apache.wicket</groupId>
+            <artifactId>wicket</artifactId>
+            <version>${wicket.version}</version>
+         </dependency>
+      </dependencies>
+   </dependencyManagement>
+
+   <dependencies>
+      <dependency>
+         <groupId>org.testng</groupId>
+         <artifactId>testng</artifactId>
+         <scope>test</scope>
+         <version>${testng.version}</version>
+         <classifier>jdk15</classifier>
+         <exclusions>
+            <exclusion>
+               <artifactId>junit</artifactId>
+               <groupId>junit</groupId>
+            </exclusion>
+         </exclusions>
+      </dependency>
+
+      <dependency>
+         <groupId>javax.enterprise</groupId>
+         <artifactId>cdi-api</artifactId>
+      </dependency>
+
+      <dependency>
+         <groupId>org.jboss.weld</groupId>
+         <artifactId>weld-core</artifactId>
+         <scope>provided</scope>
+      </dependency>
+
+      <!-- WELDX-36 -->
+      <dependency>
+         <groupId>javax.portlet</groupId>
+         <artifactId>portlet-api</artifactId>
+         <version>1.0</version>
+      </dependency>
+
+      <dependency>
+         <groupId>javax.servlet</groupId>
+         <artifactId>servlet-api</artifactId>
+         <scope>provided</scope>
+      </dependency>
+
+      <dependency>
+         <groupId>org.apache.wicket</groupId>
+         <artifactId>wicket</artifactId>
+      </dependency>
+
+   </dependencies>
+
+   <scm>
+      <connection>scm:svn:http://anonsvn.jboss.org/repos/weld/wicket/tags/1.0.1-CR2</connection>
+      <developerConnection>scm:svn:https://svn.jboss.org/repos/weld/wicket/tags/1.0.1-CR2</developerConnection>
+      <url>http://fisheye.jboss.org/browse/weld/wicket/tags/1.0.1-CR2</url>
+   </scm>
+
+</project>

Added: modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/BeanManagerLookup.java
===================================================================
--- modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/BeanManagerLookup.java	                        (rev 0)
+++ modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/BeanManagerLookup.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,85 @@
+package org.jboss.weld.wicket;
+
+import javax.enterprise.inject.spi.BeanManager;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.servlet.ServletContext;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.protocol.http.WebApplication;
+
+/**
+ * A utilty class to provide access to the JSR-299 BeanManager
+ * @author cpopetz
+ *
+ */
+public class BeanManagerLookup
+{
+
+   private static BeanManager cachedManager;
+   /**
+    * This is the spec-defined name for the bean manager as registered in JNDI
+    * See JSR-299 11.3
+    */
+   // TODO Change to java:comp/BeanManager when JBoss AS supports it
+   private static String beanManagerJndiName = "java:app/BeanManager";
+
+   public static void setBeanManagerJndiName(String beanManagerJndiName)
+   {
+      BeanManagerLookup.beanManagerJndiName = beanManagerJndiName;
+   }
+
+   public static String getBeanManagerJndiName()
+   {
+      return beanManagerJndiName;
+   }
+
+   /**
+    * This is the name under which the bean manager will be stored in the
+    * servlet context. This is not yet specified in JSR-299.
+    */
+   private static String beanManagerServletContextName = BeanManager.class.getName();
+
+   public static void setBeanManagerServletContextName(String beanManagerServletContextName)
+   {
+      BeanManagerLookup.beanManagerServletContextName = beanManagerServletContextName;
+   }
+
+   public static String getBeanManagerServletContextName()
+   {
+      return beanManagerServletContextName;
+   }
+   
+
+   /**
+    * We will attempt first to obtain the BeanManager instance from JNDI.
+    * Failing that, we will look in the servlet context.
+    */
+   public static BeanManager getBeanManager()
+   {
+      if (cachedManager == null)
+      {
+         // first look in jndi
+         try
+         {
+            Context initialContext = new InitialContext();
+            cachedManager = (BeanManager) initialContext.lookup(getBeanManagerJndiName());
+         }
+         catch (Exception e)
+         {
+            // we ignore this failure; it could mean we are operating in a
+            // non-jndi (SE or Servlet) env
+         }
+
+         if (cachedManager == null)
+         {
+            ServletContext servletContext = ((WebApplication) Application.get()).getServletContext();
+            if (servletContext != null)
+            {
+               cachedManager = (BeanManager) servletContext.getAttribute(getBeanManagerServletContextName());
+            }
+         }
+      }
+      return cachedManager;
+   }
+}


Property changes on: modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/BeanManagerLookup.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldApplication.java
===================================================================
--- modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldApplication.java	                        (rev 0)
+++ modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldApplication.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,77 @@
+package org.jboss.weld.wicket;
+
+import org.apache.wicket.Request;
+import org.apache.wicket.RequestCycle;
+import org.apache.wicket.Response;
+import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.protocol.http.WebRequest;
+import org.apache.wicket.protocol.http.WebResponse;
+import org.apache.wicket.request.IRequestCycleProcessor;
+import org.jboss.weld.wicket.util.NonContextual;
+
+/**
+ * A convenience subclass of wicket's WebApplication which adds the hooks
+ * necessary to use JSR-299 injections in wicket components, as well as manage
+ * JSR-299 conversation scopes with Wicket page metadata. If you have your own
+ * WebApplication subclass, and can't subclass this class, you just need to do
+ * the three things that this class does, i.e. register the
+ * WeldComponentInstantiationListener, and override the two methods below to
+ * return the RequestCycle and IRequestCycleProcessor subclasses specific to
+ * Weld, or your subclasses of those classes.
+ * 
+ * @author cpopetz
+ * @author pmuir
+ * 
+ * @see WebApplication
+ * @see WeldWebRequestCycleProcessor
+ * @see WeldRequestCycle
+ */
+public abstract class WeldApplication extends WebApplication
+{
+   
+   private NonContextual<WeldComponentInstantiationListener> weldComponentInstantiationListener;
+   private NonContextual<WeldWebRequestCycleProcessor> weldWebRequestCycleProcessor;
+
+   /**
+    */
+   public WeldApplication()
+   {
+   }
+
+   /**
+    * Add our component instantiation listener
+    * 
+    * @see WeldComponentInstantiationListener
+    */
+   @Override
+   protected void internalInit() 
+   {
+      super.internalInit();
+      this.weldComponentInstantiationListener = new NonContextual<WeldComponentInstantiationListener>(BeanManagerLookup.getBeanManager(), WeldComponentInstantiationListener.class);
+      this.weldWebRequestCycleProcessor = new NonContextual<WeldWebRequestCycleProcessor>(BeanManagerLookup.getBeanManager(), WeldWebRequestCycleProcessor.class);
+      addComponentInstantiationListener(weldComponentInstantiationListener.newInstance().produce().inject().get());
+   }
+
+
+   /**
+    * Override to return our Weld-specific request cycle processor
+    * 
+    * @see WeldWebRequestCycleProcessor
+    */
+   @Override
+   protected IRequestCycleProcessor newRequestCycleProcessor()
+   {
+      return weldWebRequestCycleProcessor.newInstance().produce().inject().get();
+   }
+
+   /**
+    * Override to return our Weld-specific request cycle
+    * 
+    * @see WeldRequestCycle
+    */
+   @Override
+   public RequestCycle newRequestCycle(final Request request, final Response response)
+   {
+      return new WeldRequestCycle(this, (WebRequest) request, (WebResponse) response);
+   }
+}


Property changes on: modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldApplication.java
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:eol-style
   + native

Added: modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldComponentInstantiationListener.java
===================================================================
--- modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldComponentInstantiationListener.java	                        (rev 0)
+++ modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldComponentInstantiationListener.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,33 @@
+package org.jboss.weld.wicket;
+
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.application.IComponentInstantiationListener;
+import org.jboss.weld.wicket.util.NonContextual;
+
+/**
+ * This listener uses the BeanManager to handle injections for all wicket components.
+ * 
+ * @author cpopetz
+ * 
+ */
+public class WeldComponentInstantiationListener implements IComponentInstantiationListener
+{
+   
+	@Inject
+   private BeanManager manager;
+	
+   public void onInstantiation(Component component)
+   {
+      /*
+       * The manager could be null in unit testing environments
+       */
+      if (manager != null)
+      {
+         // TODO Cache the NonContextual!
+         new NonContextual<Component>(manager, component.getClass()).existingInstance(component).inject();
+      }
+   }
+}
\ No newline at end of file


Property changes on: modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldComponentInstantiationListener.java
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:eol-style
   + native

Added: modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldMetaData.java
===================================================================
--- modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldMetaData.java	                        (rev 0)
+++ modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldMetaData.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,23 @@
+package org.jboss.weld.wicket;
+
+import org.apache.wicket.MetaDataKey;
+
+/**
+ * Public storage for the metadata key used by the Weld integration to store
+ * conversation ids in wicket page metadata.
+ * 
+ * @author cpopetz
+ * 
+ */
+public class WeldMetaData
+{
+
+   /**
+    * This is the key we will use to to store the conversation metadata in the
+    * wicket page.
+    */
+   public static final MetaDataKey<String> CID = new MetaDataKey<String>()
+   {
+      private static final long serialVersionUID = -8788010688731927318L; 
+   }; 
+}


Property changes on: modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldMetaData.java
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:eol-style
   + native

Added: modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldRequestCycle.java
===================================================================
--- modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldRequestCycle.java	                        (rev 0)
+++ modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldRequestCycle.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,166 @@
+package org.jboss.weld.wicket;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Set;
+
+import javax.enterprise.context.Conversation;
+import javax.enterprise.inject.AmbiguousResolutionException;
+import javax.enterprise.inject.UnsatisfiedResolutionException;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+
+import org.apache.wicket.IRequestTarget;
+import org.apache.wicket.Page;
+import org.apache.wicket.Response;
+import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.protocol.http.WebRequest;
+import org.apache.wicket.protocol.http.WebRequestCycle;
+import org.apache.wicket.request.target.component.BookmarkablePageRequestTarget;
+import org.apache.wicket.request.target.component.IPageRequestTarget;
+import org.jboss.weld.Container;
+import org.jboss.weld.context.ContextLifecycle;
+import org.jboss.weld.context.ConversationContext;
+import org.jboss.weld.conversation.ConversationImpl;
+import org.jboss.weld.conversation.ConversationManager;
+import org.jboss.weld.servlet.ConversationBeanStore;
+
+/**
+ * WeldRequestCycle is a subclass of the standard wicket WebRequestCycle which:
+ * <ul>
+ * <li>restores long-running conversations specified in wicket page metadata
+ * when a page target is first used.
+ * <li>propagates long running conversations to new page targets by specifying
+ * the above metadata
+ * <li>propagates long running conversations across redirects through the use of
+ * a request parameter if the redirect is handled with a BookmarkablePageRequest
+ * <li>Sets up the conversational context when the request target is set
+ * <li>Tears down the conversation context on detach() of the RequestCycle
+ * </ul>
+ * 
+ * @see WeldWebRequestCycleProcessor Which handles propogation of conversation
+ *      data for newly-started long running conversations, by storing their ids
+ *      in the page metadata
+ * @author cpopetz
+ * 
+ */
+public class WeldRequestCycle extends WebRequestCycle
+{
+
+   public WeldRequestCycle(WebApplication application, WebRequest request, Response response)
+   {
+      super(application, request, response);
+   }
+
+   /**
+    * Override to set up the conversation context and to choose the conversation
+    * if a conversation id is present in target metadata.
+    */
+   @Override
+   protected void onRequestTargetSet(IRequestTarget target)
+   {
+      super.onRequestTargetSet(target);
+
+      Page page = null;
+      if (target instanceof IPageRequestTarget)
+      {
+         page = ((IPageRequestTarget) target).getPage();
+      }
+
+      // Two possible specifications of cid: page metadata or request url; the
+      // latter is used to propagate the conversation to mounted (bookmarkable)
+      // paths after a redirect
+
+      String specifiedCid = null;
+      if (page != null)
+      {
+         specifiedCid = page.getMetaData(WeldMetaData.CID);
+      }
+      else
+      {
+         specifiedCid = request.getParameter("cid");
+      }
+
+      BeanManager manager = BeanManagerLookup.getBeanManager();
+
+      ConversationImpl conversation = (ConversationImpl) getInstanceByType(manager, Conversation.class);
+
+      // restore a conversation if it exists and we aren't already in it
+      if (specifiedCid != null && (conversation == null || !specifiedCid.equals(conversation.getUnderlyingId())))
+      {
+         getInstanceByType(manager, ConversationManager.class).beginOrRestoreConversation(specifiedCid);
+      }
+
+
+      ConversationContext conversationContext = Container.instance().services().get(ContextLifecycle.class).getConversationContext();
+      // Now set up the conversational context if it isn't already
+      if (!conversationContext.isActive())
+      {
+         // TODO account for invalidated session
+         conversationContext.setBeanStore(new ConversationBeanStore(((WebRequest) request).getHttpServletRequest().getSession(), false, conversation.getUnderlyingId()));
+         conversationContext.setActive(true);
+      }
+
+      // handle propagation of existing long running converstaions to new
+      // targets
+      if (!conversation.isTransient())
+      {
+         // Note that we can't propagate conversations with other redirect
+         // targets like RequestRedirectTarget through this mechanism, because
+         // it does not provide an interface to modify its target URL. If
+         // propagation with those targets is to be supported, it needs a custom
+         // Response subclass.
+         if (isRedirect() && target instanceof BookmarkablePageRequestTarget)
+         {
+            BookmarkablePageRequestTarget bookmark = (BookmarkablePageRequestTarget) target;
+            // if a cid has already been specified, don't override it
+            if (!bookmark.getPageParameters().containsKey("cid"))
+               bookmark.getPageParameters().add("cid", conversation.getUnderlyingId());
+         }
+
+         // If we have a target page, propagate the conversation to the page's
+         // metadata
+         if (page != null)
+         {
+            page.setMetaData(WeldMetaData.CID, conversation.getUnderlyingId());
+         }
+      }
+
+
+   }
+
+   @SuppressWarnings("unchecked")
+   private <T> T getInstanceByType(BeanManager manager, Class<T> beanType, Annotation... bindings)
+   {
+      Bean<T> bean = (Bean<T>) ensureUniqueBean(beanType, manager.getBeans(beanType, bindings));
+      return (T) manager.getReference(bean, beanType, manager.createCreationalContext(bean));
+   }
+
+   private static Bean<?> ensureUniqueBean(Type type, Set<Bean<?>> beans)
+   {
+      if (beans.size() == 0)
+      {
+         throw new UnsatisfiedResolutionException("Unable to resolve any Web Beans of " + type);
+      }
+      else if (beans.size() > 1)
+      {
+         throw new AmbiguousResolutionException("More than one bean available for type " + type);
+      }
+      return beans.iterator().next();
+   }
+
+   @Override
+   public void detach()
+   {
+      super.detach();
+      ConversationContext conversationContext = Container.instance().services().get(ContextLifecycle.class).getConversationContext();
+      // cleanup and deactivate the conversation context
+      if (conversationContext.isActive())
+      {
+         ConversationManager conversationManager = getInstanceByType(BeanManagerLookup.getBeanManager(), ConversationManager.class);
+         conversationManager.cleanupConversation();
+         conversationContext.setActive(false);
+      }
+   }
+
+}
\ No newline at end of file


Property changes on: modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldRequestCycle.java
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:eol-style
   + native

Added: modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldWebRequestCycleProcessor.java
===================================================================
--- modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldWebRequestCycleProcessor.java	                        (rev 0)
+++ modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldWebRequestCycleProcessor.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,41 @@
+package org.jboss.weld.wicket;
+
+import javax.enterprise.context.Conversation;
+import javax.inject.Inject;
+
+import org.apache.wicket.Page;
+import org.apache.wicket.RequestCycle;
+import org.apache.wicket.protocol.http.WebRequestCycleProcessor;
+
+/**
+ * WeldWebRequestCycleProcessor is a subclass of the standard wicket
+ * WebRequestCycleProcessor which saves the conversation id of any long-running
+ * cornversation in wicket page metadata.
+ * 
+ * @author cpopetz
+ * 
+ */
+public class WeldWebRequestCycleProcessor extends WebRequestCycleProcessor
+{
+   @Inject
+   Conversation conversation;
+   
+   /**
+    * If a long running conversation has been started, store its id into page
+    * metadata
+    */
+   @Override
+   public void respond(RequestCycle requestCycle)
+   {
+      super.respond(requestCycle);
+      if (!conversation.isTransient())
+      {
+         Page page = RequestCycle.get().getResponsePage();
+         if (page != null)
+         {
+            page.setMetaData(WeldMetaData.CID, conversation.getId());
+         }
+      }
+      
+   }
+}
\ No newline at end of file


Property changes on: modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/WeldWebRequestCycleProcessor.java
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:eol-style
   + native

Added: modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/util/NonContextual.java
===================================================================
--- modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/util/NonContextual.java	                        (rev 0)
+++ modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/util/NonContextual.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,184 @@
+package org.jboss.weld.wicket.util;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionTarget;
+
+/**
+ * Perform production, injection, lifecycle callbacks and cleanup on a non-contextual object
+ * 
+ * @author pmuir
+ *
+ * @param <T>
+ */
+public class NonContextual<T>
+{
+
+   // Store the injection target. The CDI spec doesn't require an implementation
+   // to cache it, so we do
+   private final InjectionTarget<? extends T> injectionTarget;
+
+   // Store a reference to the CDI BeanManager
+   private final BeanManager beanManager;
+
+   /**
+    * Create an injector for the given class
+    */
+   public NonContextual(BeanManager manager, Class<? extends T> clazz)
+   {
+      this.beanManager = manager;
+
+      // Generate an "Annotated Type"
+      AnnotatedType<? extends T> type = manager.createAnnotatedType(clazz);
+
+      // Generate the InjectionTarget
+      this.injectionTarget = manager.createInjectionTarget(type);
+   }
+
+   public Instance<T> newInstance()
+   {
+      return new Instance<T>(beanManager, (InjectionTarget<T>) injectionTarget);
+   }
+   
+   public Instance<T> existingInstance(T instance)
+   {
+      return new Instance<T>(beanManager, (InjectionTarget<T>) injectionTarget, instance);
+   }
+ 
+   /**
+    * Represents a non-contextual instance
+    * 
+    * @author pmuir
+    * 
+    * @param <T>
+    */
+   public static class Instance<T>
+   {
+
+      private final CreationalContext<T> ctx;
+      private final InjectionTarget<T> injectionTarget;
+      private T instance;
+      private boolean disposed = false;
+
+      private Instance(BeanManager beanManager, InjectionTarget<T> injectionTarget)
+      {
+         this.injectionTarget = injectionTarget;
+         this.ctx = beanManager.createCreationalContext(null);
+      }
+      
+      private Instance(BeanManager beanManager, InjectionTarget<T> injectionTarget, T instance)
+      {
+         this.injectionTarget = injectionTarget;
+         this.ctx = beanManager.createCreationalContext(null);
+         this.instance = instance;
+      }
+
+      /**
+       * Get the instance
+       * 
+       * @return
+       */
+      public T get()
+      {
+         return instance;
+      }
+
+      /**
+       * Create the instance
+       * 
+       * @return
+       */
+      public Instance<T> produce()
+      {
+         if (this.instance != null)
+         {
+            throw new IllegalStateException("Trying to call produce() on already constructed instance");
+         }
+         if (disposed)
+         {
+            throw new IllegalStateException("Trying to call produce() on an already disposed instance");
+         }
+         this.instance = injectionTarget.produce(ctx);
+         return this;
+      }
+
+      /**
+       * Inject the instance
+       * 
+       * @return
+       */
+      public Instance<T> inject()
+      {
+         if (this.instance == null)
+         {
+            throw new IllegalStateException("Trying to call inject() before produce() was called");
+         }
+         if (disposed)
+         {
+            throw new IllegalStateException("Trying to call inject() on already disposed instance");
+         }
+         injectionTarget.inject(instance, ctx);
+         return this;
+      }
+
+      /**
+       * Call the @PostConstruct callback
+       * 
+       * @return
+       */
+      public Instance<T> postConstruct()
+      {
+         if (this.instance == null)
+         {
+            throw new IllegalStateException("Trying to call postConstruct() before produce() was called");
+         }
+         if (disposed)
+         {
+            throw new IllegalStateException("Trying to call preDestroy() on already disposed instance");
+         }
+         injectionTarget.postConstruct(instance);
+         return this;
+      }
+
+      /**
+       * Call the @PreDestroy callback
+       * 
+       * @return
+       */
+      public Instance<T> preDestroy()
+      {
+         if (this.instance == null)
+         {
+            throw new IllegalStateException("Trying to call preDestroy() before produce() was called");
+         }
+         if (disposed)
+         {
+            throw new IllegalStateException("Trying to call preDestroy() on already disposed instance");
+         }
+         injectionTarget.preDestroy(instance);
+         return this;
+      }
+
+      /**
+       * Dispose of the instance, doing any necessary cleanup
+       * 
+       */
+      public Instance<T> dispose()
+      {
+         if (this.instance == null)
+         {
+            throw new IllegalStateException("Trying to call dispose() before produce() was called");
+         }
+         if (disposed)
+         {
+            throw new IllegalStateException("Trying to call dispose() on already disposed instance");
+         }
+         injectionTarget.dispose(instance);
+         ctx.release();
+         return this;
+      }
+
+   }
+
+}
\ No newline at end of file


Property changes on: modules/wicket/tags/1.0.1-CR2/src/main/java/org/jboss/weld/wicket/util/NonContextual.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: modules/wicket/tags/1.0.1-Final/pom.xml
===================================================================
--- modules/wicket/tags/1.0.1-Final/pom.xml	                        (rev 0)
+++ modules/wicket/tags/1.0.1-Final/pom.xml	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,124 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+   <parent>
+      <groupId>org.jboss.weld</groupId>
+      <artifactId>weld-parent</artifactId>
+      <version>9</version>
+   </parent>
+   <modelVersion>4.0.0</modelVersion>
+   <groupId>org.jboss.weld</groupId>
+   <artifactId>weld-wicket</artifactId>
+   <version>1.0.1-Final</version>
+   <name>Weld Wicket support</name>
+
+   <description>Weld support for Apache Wicket</description>
+
+   <developers>
+      <developer>
+         <name>Clint Popetz</name>
+         <roles>
+            <role>Module lead</role>
+         </roles>
+      </developer>
+   </developers>
+   
+   <url>http://www.seamframework.org/Weld</url>
+   <licenses>
+      <license>
+         <name>Apache License, Version 2.0</name>
+         <distribution>repo</distribution>
+         <url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
+      </license>
+   </licenses>
+
+   <issueManagement>
+      <system>JIRA</system>
+      <url>https://jira.jboss.org/jira/browse/WELDX/component/12312752</url>
+   </issueManagement>
+
+
+
+   <properties>
+      <weld.api.version>1.0-SP1</weld.api.version>
+      <weld.core.version>1.0.1-Final</weld.core.version>
+      <testng.version>5.10</testng.version>
+      <wicket.version>1.4.1</wicket.version>
+   </properties>
+
+   <!-- Import the BOMs -->
+   <dependencyManagement>
+      <dependencies>
+         <dependency>
+            <groupId>org.jboss.weld</groupId>
+            <artifactId>weld-api-bom</artifactId>
+            <version>${weld.api.version}</version>
+            <type>pom</type>
+            <scope>import</scope>
+         </dependency>
+         <dependency>
+            <groupId>org.jboss.weld</groupId>
+            <artifactId>weld-core-bom</artifactId>
+            <version>${weld.core.version}</version>
+            <type>pom</type>
+            <scope>import</scope>
+         </dependency>
+         <dependency>
+            <groupId>org.apache.wicket</groupId>
+            <artifactId>wicket</artifactId>
+            <version>${wicket.version}</version>
+         </dependency>
+      </dependencies>
+   </dependencyManagement>
+
+   <dependencies>
+      <dependency>
+         <groupId>org.testng</groupId>
+         <artifactId>testng</artifactId>
+         <scope>test</scope>
+         <version>${testng.version}</version>
+         <classifier>jdk15</classifier>
+         <exclusions>
+            <exclusion>
+               <artifactId>junit</artifactId>
+               <groupId>junit</groupId>
+            </exclusion>
+         </exclusions>
+      </dependency>
+
+      <dependency>
+         <groupId>javax.enterprise</groupId>
+         <artifactId>cdi-api</artifactId>
+      </dependency>
+
+      <dependency>
+         <groupId>org.jboss.weld</groupId>
+         <artifactId>weld-core</artifactId>
+         <scope>provided</scope>
+      </dependency>
+
+      <!-- WELDX-36 -->
+      <dependency>
+         <groupId>javax.portlet</groupId>
+         <artifactId>portlet-api</artifactId>
+         <version>1.0</version>
+      </dependency>
+
+      <dependency>
+         <groupId>javax.servlet</groupId>
+         <artifactId>servlet-api</artifactId>
+         <scope>provided</scope>
+      </dependency>
+
+      <dependency>
+         <groupId>org.apache.wicket</groupId>
+         <artifactId>wicket</artifactId>
+      </dependency>
+
+   </dependencies>
+
+   <scm>
+      <connection>scm:svn:http://anonsvn.jboss.org/repos/weld/wicket/tags/1.0.1-Final</connection>
+      <developerConnection>scm:svn:https://svn.jboss.org/repos/weld/wicket/tags/1.0.1-Final</developerConnection>
+      <url>http://fisheye.jboss.org/browse/weld/wicket/tags/1.0.1-Final</url>
+   </scm>
+
+</project>

Added: modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/BeanManagerLookup.java
===================================================================
--- modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/BeanManagerLookup.java	                        (rev 0)
+++ modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/BeanManagerLookup.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,85 @@
+package org.jboss.weld.wicket;
+
+import javax.enterprise.inject.spi.BeanManager;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.servlet.ServletContext;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.protocol.http.WebApplication;
+
+/**
+ * A utilty class to provide access to the JSR-299 BeanManager
+ * @author cpopetz
+ *
+ */
+public class BeanManagerLookup
+{
+
+   private static BeanManager cachedManager;
+   /**
+    * This is the spec-defined name for the bean manager as registered in JNDI
+    * See JSR-299 11.3
+    */
+   // TODO Change to java:comp/BeanManager when JBoss AS supports it
+   private static String beanManagerJndiName = "java:app/BeanManager";
+
+   public static void setBeanManagerJndiName(String beanManagerJndiName)
+   {
+      BeanManagerLookup.beanManagerJndiName = beanManagerJndiName;
+   }
+
+   public static String getBeanManagerJndiName()
+   {
+      return beanManagerJndiName;
+   }
+
+   /**
+    * This is the name under which the bean manager will be stored in the
+    * servlet context. This is not yet specified in JSR-299.
+    */
+   private static String beanManagerServletContextName = BeanManager.class.getName();
+
+   public static void setBeanManagerServletContextName(String beanManagerServletContextName)
+   {
+      BeanManagerLookup.beanManagerServletContextName = beanManagerServletContextName;
+   }
+
+   public static String getBeanManagerServletContextName()
+   {
+      return beanManagerServletContextName;
+   }
+   
+
+   /**
+    * We will attempt first to obtain the BeanManager instance from JNDI.
+    * Failing that, we will look in the servlet context.
+    */
+   public static BeanManager getBeanManager()
+   {
+      if (cachedManager == null)
+      {
+         // first look in jndi
+         try
+         {
+            Context initialContext = new InitialContext();
+            cachedManager = (BeanManager) initialContext.lookup(getBeanManagerJndiName());
+         }
+         catch (Exception e)
+         {
+            // we ignore this failure; it could mean we are operating in a
+            // non-jndi (SE or Servlet) env
+         }
+
+         if (cachedManager == null)
+         {
+            ServletContext servletContext = ((WebApplication) Application.get()).getServletContext();
+            if (servletContext != null)
+            {
+               cachedManager = (BeanManager) servletContext.getAttribute(getBeanManagerServletContextName());
+            }
+         }
+      }
+      return cachedManager;
+   }
+}


Property changes on: modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/BeanManagerLookup.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldApplication.java
===================================================================
--- modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldApplication.java	                        (rev 0)
+++ modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldApplication.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,77 @@
+package org.jboss.weld.wicket;
+
+import org.apache.wicket.Request;
+import org.apache.wicket.RequestCycle;
+import org.apache.wicket.Response;
+import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.protocol.http.WebRequest;
+import org.apache.wicket.protocol.http.WebResponse;
+import org.apache.wicket.request.IRequestCycleProcessor;
+import org.jboss.weld.wicket.util.NonContextual;
+
+/**
+ * A convenience subclass of wicket's WebApplication which adds the hooks
+ * necessary to use JSR-299 injections in wicket components, as well as manage
+ * JSR-299 conversation scopes with Wicket page metadata. If you have your own
+ * WebApplication subclass, and can't subclass this class, you just need to do
+ * the three things that this class does, i.e. register the
+ * WeldComponentInstantiationListener, and override the two methods below to
+ * return the RequestCycle and IRequestCycleProcessor subclasses specific to
+ * Weld, or your subclasses of those classes.
+ * 
+ * @author cpopetz
+ * @author pmuir
+ * 
+ * @see WebApplication
+ * @see WeldWebRequestCycleProcessor
+ * @see WeldRequestCycle
+ */
+public abstract class WeldApplication extends WebApplication
+{
+   
+   private NonContextual<WeldComponentInstantiationListener> weldComponentInstantiationListener;
+   private NonContextual<WeldWebRequestCycleProcessor> weldWebRequestCycleProcessor;
+
+   /**
+    */
+   public WeldApplication()
+   {
+   }
+
+   /**
+    * Add our component instantiation listener
+    * 
+    * @see WeldComponentInstantiationListener
+    */
+   @Override
+   protected void internalInit() 
+   {
+      super.internalInit();
+      this.weldComponentInstantiationListener = new NonContextual<WeldComponentInstantiationListener>(BeanManagerLookup.getBeanManager(), WeldComponentInstantiationListener.class);
+      this.weldWebRequestCycleProcessor = new NonContextual<WeldWebRequestCycleProcessor>(BeanManagerLookup.getBeanManager(), WeldWebRequestCycleProcessor.class);
+      addComponentInstantiationListener(weldComponentInstantiationListener.newInstance().produce().inject().get());
+   }
+
+
+   /**
+    * Override to return our Weld-specific request cycle processor
+    * 
+    * @see WeldWebRequestCycleProcessor
+    */
+   @Override
+   protected IRequestCycleProcessor newRequestCycleProcessor()
+   {
+      return weldWebRequestCycleProcessor.newInstance().produce().inject().get();
+   }
+
+   /**
+    * Override to return our Weld-specific request cycle
+    * 
+    * @see WeldRequestCycle
+    */
+   @Override
+   public RequestCycle newRequestCycle(final Request request, final Response response)
+   {
+      return new WeldRequestCycle(this, (WebRequest) request, (WebResponse) response);
+   }
+}


Property changes on: modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldApplication.java
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:eol-style
   + native

Added: modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldComponentInstantiationListener.java
===================================================================
--- modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldComponentInstantiationListener.java	                        (rev 0)
+++ modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldComponentInstantiationListener.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,33 @@
+package org.jboss.weld.wicket;
+
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.application.IComponentInstantiationListener;
+import org.jboss.weld.wicket.util.NonContextual;
+
+/**
+ * This listener uses the BeanManager to handle injections for all wicket components.
+ * 
+ * @author cpopetz
+ * 
+ */
+public class WeldComponentInstantiationListener implements IComponentInstantiationListener
+{
+   
+	@Inject
+   private BeanManager manager;
+	
+   public void onInstantiation(Component component)
+   {
+      /*
+       * The manager could be null in unit testing environments
+       */
+      if (manager != null)
+      {
+         // TODO Cache the NonContextual!
+         new NonContextual<Component>(manager, component.getClass()).existingInstance(component).inject();
+      }
+   }
+}
\ No newline at end of file


Property changes on: modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldComponentInstantiationListener.java
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:eol-style
   + native

Added: modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldMetaData.java
===================================================================
--- modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldMetaData.java	                        (rev 0)
+++ modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldMetaData.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,23 @@
+package org.jboss.weld.wicket;
+
+import org.apache.wicket.MetaDataKey;
+
+/**
+ * Public storage for the metadata key used by the Weld integration to store
+ * conversation ids in wicket page metadata.
+ * 
+ * @author cpopetz
+ * 
+ */
+public class WeldMetaData
+{
+
+   /**
+    * This is the key we will use to to store the conversation metadata in the
+    * wicket page.
+    */
+   public static final MetaDataKey<String> CID = new MetaDataKey<String>()
+   {
+      private static final long serialVersionUID = -8788010688731927318L; 
+   }; 
+}


Property changes on: modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldMetaData.java
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:eol-style
   + native

Added: modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldRequestCycle.java
===================================================================
--- modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldRequestCycle.java	                        (rev 0)
+++ modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldRequestCycle.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,166 @@
+package org.jboss.weld.wicket;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Set;
+
+import javax.enterprise.context.Conversation;
+import javax.enterprise.inject.AmbiguousResolutionException;
+import javax.enterprise.inject.UnsatisfiedResolutionException;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+
+import org.apache.wicket.IRequestTarget;
+import org.apache.wicket.Page;
+import org.apache.wicket.Response;
+import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.protocol.http.WebRequest;
+import org.apache.wicket.protocol.http.WebRequestCycle;
+import org.apache.wicket.request.target.component.BookmarkablePageRequestTarget;
+import org.apache.wicket.request.target.component.IPageRequestTarget;
+import org.jboss.weld.Container;
+import org.jboss.weld.context.ContextLifecycle;
+import org.jboss.weld.context.ConversationContext;
+import org.jboss.weld.conversation.ConversationImpl;
+import org.jboss.weld.conversation.ConversationManager;
+import org.jboss.weld.servlet.ConversationBeanStore;
+
+/**
+ * WeldRequestCycle is a subclass of the standard wicket WebRequestCycle which:
+ * <ul>
+ * <li>restores long-running conversations specified in wicket page metadata
+ * when a page target is first used.
+ * <li>propagates long running conversations to new page targets by specifying
+ * the above metadata
+ * <li>propagates long running conversations across redirects through the use of
+ * a request parameter if the redirect is handled with a BookmarkablePageRequest
+ * <li>Sets up the conversational context when the request target is set
+ * <li>Tears down the conversation context on detach() of the RequestCycle
+ * </ul>
+ * 
+ * @see WeldWebRequestCycleProcessor Which handles propogation of conversation
+ *      data for newly-started long running conversations, by storing their ids
+ *      in the page metadata
+ * @author cpopetz
+ * 
+ */
+public class WeldRequestCycle extends WebRequestCycle
+{
+
+   public WeldRequestCycle(WebApplication application, WebRequest request, Response response)
+   {
+      super(application, request, response);
+   }
+
+   /**
+    * Override to set up the conversation context and to choose the conversation
+    * if a conversation id is present in target metadata.
+    */
+   @Override
+   protected void onRequestTargetSet(IRequestTarget target)
+   {
+      super.onRequestTargetSet(target);
+
+      Page page = null;
+      if (target instanceof IPageRequestTarget)
+      {
+         page = ((IPageRequestTarget) target).getPage();
+      }
+
+      // Two possible specifications of cid: page metadata or request url; the
+      // latter is used to propagate the conversation to mounted (bookmarkable)
+      // paths after a redirect
+
+      String specifiedCid = null;
+      if (page != null)
+      {
+         specifiedCid = page.getMetaData(WeldMetaData.CID);
+      }
+      else
+      {
+         specifiedCid = request.getParameter("cid");
+      }
+
+      BeanManager manager = BeanManagerLookup.getBeanManager();
+
+      ConversationImpl conversation = (ConversationImpl) getInstanceByType(manager, Conversation.class);
+
+      // restore a conversation if it exists and we aren't already in it
+      if (specifiedCid != null && (conversation == null || !specifiedCid.equals(conversation.getUnderlyingId())))
+      {
+         getInstanceByType(manager, ConversationManager.class).beginOrRestoreConversation(specifiedCid);
+      }
+
+
+      ConversationContext conversationContext = Container.instance().services().get(ContextLifecycle.class).getConversationContext();
+      // Now set up the conversational context if it isn't already
+      if (!conversationContext.isActive())
+      {
+         // TODO account for invalidated session
+         conversationContext.setBeanStore(new ConversationBeanStore(((WebRequest) request).getHttpServletRequest().getSession(), false, conversation.getUnderlyingId()));
+         conversationContext.setActive(true);
+      }
+
+      // handle propagation of existing long running converstaions to new
+      // targets
+      if (!conversation.isTransient())
+      {
+         // Note that we can't propagate conversations with other redirect
+         // targets like RequestRedirectTarget through this mechanism, because
+         // it does not provide an interface to modify its target URL. If
+         // propagation with those targets is to be supported, it needs a custom
+         // Response subclass.
+         if (isRedirect() && target instanceof BookmarkablePageRequestTarget)
+         {
+            BookmarkablePageRequestTarget bookmark = (BookmarkablePageRequestTarget) target;
+            // if a cid has already been specified, don't override it
+            if (!bookmark.getPageParameters().containsKey("cid"))
+               bookmark.getPageParameters().add("cid", conversation.getUnderlyingId());
+         }
+
+         // If we have a target page, propagate the conversation to the page's
+         // metadata
+         if (page != null)
+         {
+            page.setMetaData(WeldMetaData.CID, conversation.getUnderlyingId());
+         }
+      }
+
+
+   }
+
+   @SuppressWarnings("unchecked")
+   private <T> T getInstanceByType(BeanManager manager, Class<T> beanType, Annotation... bindings)
+   {
+      Bean<T> bean = (Bean<T>) ensureUniqueBean(beanType, manager.getBeans(beanType, bindings));
+      return (T) manager.getReference(bean, beanType, manager.createCreationalContext(bean));
+   }
+
+   private static Bean<?> ensureUniqueBean(Type type, Set<Bean<?>> beans)
+   {
+      if (beans.size() == 0)
+      {
+         throw new UnsatisfiedResolutionException("Unable to resolve any Web Beans of " + type);
+      }
+      else if (beans.size() > 1)
+      {
+         throw new AmbiguousResolutionException("More than one bean available for type " + type);
+      }
+      return beans.iterator().next();
+   }
+
+   @Override
+   public void detach()
+   {
+      super.detach();
+      ConversationContext conversationContext = Container.instance().services().get(ContextLifecycle.class).getConversationContext();
+      // cleanup and deactivate the conversation context
+      if (conversationContext.isActive())
+      {
+         ConversationManager conversationManager = getInstanceByType(BeanManagerLookup.getBeanManager(), ConversationManager.class);
+         conversationManager.cleanupConversation();
+         conversationContext.setActive(false);
+      }
+   }
+
+}
\ No newline at end of file


Property changes on: modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldRequestCycle.java
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:eol-style
   + native

Added: modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldWebRequestCycleProcessor.java
===================================================================
--- modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldWebRequestCycleProcessor.java	                        (rev 0)
+++ modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldWebRequestCycleProcessor.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,41 @@
+package org.jboss.weld.wicket;
+
+import javax.enterprise.context.Conversation;
+import javax.inject.Inject;
+
+import org.apache.wicket.Page;
+import org.apache.wicket.RequestCycle;
+import org.apache.wicket.protocol.http.WebRequestCycleProcessor;
+
+/**
+ * WeldWebRequestCycleProcessor is a subclass of the standard wicket
+ * WebRequestCycleProcessor which saves the conversation id of any long-running
+ * cornversation in wicket page metadata.
+ * 
+ * @author cpopetz
+ * 
+ */
+public class WeldWebRequestCycleProcessor extends WebRequestCycleProcessor
+{
+   @Inject
+   Conversation conversation;
+   
+   /**
+    * If a long running conversation has been started, store its id into page
+    * metadata
+    */
+   @Override
+   public void respond(RequestCycle requestCycle)
+   {
+      super.respond(requestCycle);
+      if (!conversation.isTransient())
+      {
+         Page page = RequestCycle.get().getResponsePage();
+         if (page != null)
+         {
+            page.setMetaData(WeldMetaData.CID, conversation.getId());
+         }
+      }
+      
+   }
+}
\ No newline at end of file


Property changes on: modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/WeldWebRequestCycleProcessor.java
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:eol-style
   + native

Added: modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/util/NonContextual.java
===================================================================
--- modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/util/NonContextual.java	                        (rev 0)
+++ modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/util/NonContextual.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,184 @@
+package org.jboss.weld.wicket.util;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionTarget;
+
+/**
+ * Perform production, injection, lifecycle callbacks and cleanup on a non-contextual object
+ * 
+ * @author pmuir
+ *
+ * @param <T>
+ */
+public class NonContextual<T>
+{
+
+   // Store the injection target. The CDI spec doesn't require an implementation
+   // to cache it, so we do
+   private final InjectionTarget<? extends T> injectionTarget;
+
+   // Store a reference to the CDI BeanManager
+   private final BeanManager beanManager;
+
+   /**
+    * Create an injector for the given class
+    */
+   public NonContextual(BeanManager manager, Class<? extends T> clazz)
+   {
+      this.beanManager = manager;
+
+      // Generate an "Annotated Type"
+      AnnotatedType<? extends T> type = manager.createAnnotatedType(clazz);
+
+      // Generate the InjectionTarget
+      this.injectionTarget = manager.createInjectionTarget(type);
+   }
+
+   public Instance<T> newInstance()
+   {
+      return new Instance<T>(beanManager, (InjectionTarget<T>) injectionTarget);
+   }
+   
+   public Instance<T> existingInstance(T instance)
+   {
+      return new Instance<T>(beanManager, (InjectionTarget<T>) injectionTarget, instance);
+   }
+ 
+   /**
+    * Represents a non-contextual instance
+    * 
+    * @author pmuir
+    * 
+    * @param <T>
+    */
+   public static class Instance<T>
+   {
+
+      private final CreationalContext<T> ctx;
+      private final InjectionTarget<T> injectionTarget;
+      private T instance;
+      private boolean disposed = false;
+
+      private Instance(BeanManager beanManager, InjectionTarget<T> injectionTarget)
+      {
+         this.injectionTarget = injectionTarget;
+         this.ctx = beanManager.createCreationalContext(null);
+      }
+      
+      private Instance(BeanManager beanManager, InjectionTarget<T> injectionTarget, T instance)
+      {
+         this.injectionTarget = injectionTarget;
+         this.ctx = beanManager.createCreationalContext(null);
+         this.instance = instance;
+      }
+
+      /**
+       * Get the instance
+       * 
+       * @return
+       */
+      public T get()
+      {
+         return instance;
+      }
+
+      /**
+       * Create the instance
+       * 
+       * @return
+       */
+      public Instance<T> produce()
+      {
+         if (this.instance != null)
+         {
+            throw new IllegalStateException("Trying to call produce() on already constructed instance");
+         }
+         if (disposed)
+         {
+            throw new IllegalStateException("Trying to call produce() on an already disposed instance");
+         }
+         this.instance = injectionTarget.produce(ctx);
+         return this;
+      }
+
+      /**
+       * Inject the instance
+       * 
+       * @return
+       */
+      public Instance<T> inject()
+      {
+         if (this.instance == null)
+         {
+            throw new IllegalStateException("Trying to call inject() before produce() was called");
+         }
+         if (disposed)
+         {
+            throw new IllegalStateException("Trying to call inject() on already disposed instance");
+         }
+         injectionTarget.inject(instance, ctx);
+         return this;
+      }
+
+      /**
+       * Call the @PostConstruct callback
+       * 
+       * @return
+       */
+      public Instance<T> postConstruct()
+      {
+         if (this.instance == null)
+         {
+            throw new IllegalStateException("Trying to call postConstruct() before produce() was called");
+         }
+         if (disposed)
+         {
+            throw new IllegalStateException("Trying to call preDestroy() on already disposed instance");
+         }
+         injectionTarget.postConstruct(instance);
+         return this;
+      }
+
+      /**
+       * Call the @PreDestroy callback
+       * 
+       * @return
+       */
+      public Instance<T> preDestroy()
+      {
+         if (this.instance == null)
+         {
+            throw new IllegalStateException("Trying to call preDestroy() before produce() was called");
+         }
+         if (disposed)
+         {
+            throw new IllegalStateException("Trying to call preDestroy() on already disposed instance");
+         }
+         injectionTarget.preDestroy(instance);
+         return this;
+      }
+
+      /**
+       * Dispose of the instance, doing any necessary cleanup
+       * 
+       */
+      public Instance<T> dispose()
+      {
+         if (this.instance == null)
+         {
+            throw new IllegalStateException("Trying to call dispose() before produce() was called");
+         }
+         if (disposed)
+         {
+            throw new IllegalStateException("Trying to call dispose() on already disposed instance");
+         }
+         injectionTarget.dispose(instance);
+         ctx.release();
+         return this;
+      }
+
+   }
+
+}
\ No newline at end of file


Property changes on: modules/wicket/tags/1.0.1-Final/src/main/java/org/jboss/weld/wicket/util/NonContextual.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: modules/wicket/trunk/pom.xml
===================================================================
--- modules/wicket/trunk/pom.xml	                        (rev 0)
+++ modules/wicket/trunk/pom.xml	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,124 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+   <parent>
+      <groupId>org.jboss.weld</groupId>
+      <artifactId>weld-parent</artifactId>
+      <version>9</version>
+   </parent>
+   <modelVersion>4.0.0</modelVersion>
+   <groupId>org.jboss.weld</groupId>
+   <artifactId>weld-wicket</artifactId>
+   <version>1.0.2-SNAPSHOT</version>
+   <name>Weld Wicket support</name>
+
+   <description>Weld support for Apache Wicket</description>
+
+   <developers>
+      <developer>
+         <name>Clint Popetz</name>
+         <roles>
+            <role>Module lead</role>
+         </roles>
+      </developer>
+   </developers>
+   
+   <url>http://www.seamframework.org/Weld</url>
+   <licenses>
+      <license>
+         <name>Apache License, Version 2.0</name>
+         <distribution>repo</distribution>
+         <url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
+      </license>
+   </licenses>
+
+   <issueManagement>
+      <system>JIRA</system>
+      <url>https://jira.jboss.org/jira/browse/WELDX/component/12312752</url>
+   </issueManagement>
+
+
+
+   <properties>
+      <weld.api.version>1.0-SP1</weld.api.version>
+      <weld.core.version>1.0.1-Final</weld.core.version>
+      <testng.version>5.10</testng.version>
+      <wicket.version>1.4.1</wicket.version>
+   </properties>
+
+   <!-- Import the BOMs -->
+   <dependencyManagement>
+      <dependencies>
+         <dependency>
+            <groupId>org.jboss.weld</groupId>
+            <artifactId>weld-api-bom</artifactId>
+            <version>${weld.api.version}</version>
+            <type>pom</type>
+            <scope>import</scope>
+         </dependency>
+         <dependency>
+            <groupId>org.jboss.weld</groupId>
+            <artifactId>weld-core-bom</artifactId>
+            <version>${weld.core.version}</version>
+            <type>pom</type>
+            <scope>import</scope>
+         </dependency>
+         <dependency>
+            <groupId>org.apache.wicket</groupId>
+            <artifactId>wicket</artifactId>
+            <version>${wicket.version}</version>
+         </dependency>
+      </dependencies>
+   </dependencyManagement>
+
+   <dependencies>
+      <dependency>
+         <groupId>org.testng</groupId>
+         <artifactId>testng</artifactId>
+         <scope>test</scope>
+         <version>${testng.version}</version>
+         <classifier>jdk15</classifier>
+         <exclusions>
+            <exclusion>
+               <artifactId>junit</artifactId>
+               <groupId>junit</groupId>
+            </exclusion>
+         </exclusions>
+      </dependency>
+
+      <dependency>
+         <groupId>javax.enterprise</groupId>
+         <artifactId>cdi-api</artifactId>
+      </dependency>
+
+      <dependency>
+         <groupId>org.jboss.weld</groupId>
+         <artifactId>weld-core</artifactId>
+         <scope>provided</scope>
+      </dependency>
+
+      <!-- WELDX-36 -->
+      <dependency>
+         <groupId>javax.portlet</groupId>
+         <artifactId>portlet-api</artifactId>
+         <version>1.0</version>
+      </dependency>
+
+      <dependency>
+         <groupId>javax.servlet</groupId>
+         <artifactId>servlet-api</artifactId>
+         <scope>provided</scope>
+      </dependency>
+
+      <dependency>
+         <groupId>org.apache.wicket</groupId>
+         <artifactId>wicket</artifactId>
+      </dependency>
+
+   </dependencies>
+
+   <scm>
+      <connection>scm:svn:http://anonsvn.jboss.org/repos/weld/wicket/trunk</connection>
+      <developerConnection>scm:svn:https://svn.jboss.org/repos/weld/wicket/trunk</developerConnection>
+      <url>http://fisheye.jboss.org/browse/weld/wicket/trunk</url>
+   </scm>
+
+</project>

Added: modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/BeanManagerLookup.java
===================================================================
--- modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/BeanManagerLookup.java	                        (rev 0)
+++ modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/BeanManagerLookup.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,85 @@
+package org.jboss.weld.wicket;
+
+import javax.enterprise.inject.spi.BeanManager;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.servlet.ServletContext;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.protocol.http.WebApplication;
+
+/**
+ * A utilty class to provide access to the JSR-299 BeanManager
+ * @author cpopetz
+ *
+ */
+public class BeanManagerLookup
+{
+
+   private static BeanManager cachedManager;
+   /**
+    * This is the spec-defined name for the bean manager as registered in JNDI
+    * See JSR-299 11.3
+    */
+   // TODO Change to java:comp/BeanManager when JBoss AS supports it
+   private static String beanManagerJndiName = "java:app/BeanManager";
+
+   public static void setBeanManagerJndiName(String beanManagerJndiName)
+   {
+      BeanManagerLookup.beanManagerJndiName = beanManagerJndiName;
+   }
+
+   public static String getBeanManagerJndiName()
+   {
+      return beanManagerJndiName;
+   }
+
+   /**
+    * This is the name under which the bean manager will be stored in the
+    * servlet context. This is not yet specified in JSR-299.
+    */
+   private static String beanManagerServletContextName = BeanManager.class.getName();
+
+   public static void setBeanManagerServletContextName(String beanManagerServletContextName)
+   {
+      BeanManagerLookup.beanManagerServletContextName = beanManagerServletContextName;
+   }
+
+   public static String getBeanManagerServletContextName()
+   {
+      return beanManagerServletContextName;
+   }
+   
+
+   /**
+    * We will attempt first to obtain the BeanManager instance from JNDI.
+    * Failing that, we will look in the servlet context.
+    */
+   public static BeanManager getBeanManager()
+   {
+      if (cachedManager == null)
+      {
+         // first look in jndi
+         try
+         {
+            Context initialContext = new InitialContext();
+            cachedManager = (BeanManager) initialContext.lookup(getBeanManagerJndiName());
+         }
+         catch (Exception e)
+         {
+            // we ignore this failure; it could mean we are operating in a
+            // non-jndi (SE or Servlet) env
+         }
+
+         if (cachedManager == null)
+         {
+            ServletContext servletContext = ((WebApplication) Application.get()).getServletContext();
+            if (servletContext != null)
+            {
+               cachedManager = (BeanManager) servletContext.getAttribute(getBeanManagerServletContextName());
+            }
+         }
+      }
+      return cachedManager;
+   }
+}


Property changes on: modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/BeanManagerLookup.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldApplication.java
===================================================================
--- modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldApplication.java	                        (rev 0)
+++ modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldApplication.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,77 @@
+package org.jboss.weld.wicket;
+
+import org.apache.wicket.Request;
+import org.apache.wicket.RequestCycle;
+import org.apache.wicket.Response;
+import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.protocol.http.WebRequest;
+import org.apache.wicket.protocol.http.WebResponse;
+import org.apache.wicket.request.IRequestCycleProcessor;
+import org.jboss.weld.wicket.util.NonContextual;
+
+/**
+ * A convenience subclass of wicket's WebApplication which adds the hooks
+ * necessary to use JSR-299 injections in wicket components, as well as manage
+ * JSR-299 conversation scopes with Wicket page metadata. If you have your own
+ * WebApplication subclass, and can't subclass this class, you just need to do
+ * the three things that this class does, i.e. register the
+ * WeldComponentInstantiationListener, and override the two methods below to
+ * return the RequestCycle and IRequestCycleProcessor subclasses specific to
+ * Weld, or your subclasses of those classes.
+ * 
+ * @author cpopetz
+ * @author pmuir
+ * 
+ * @see WebApplication
+ * @see WeldWebRequestCycleProcessor
+ * @see WeldRequestCycle
+ */
+public abstract class WeldApplication extends WebApplication
+{
+   
+   private NonContextual<WeldComponentInstantiationListener> weldComponentInstantiationListener;
+   private NonContextual<WeldWebRequestCycleProcessor> weldWebRequestCycleProcessor;
+
+   /**
+    */
+   public WeldApplication()
+   {
+   }
+
+   /**
+    * Add our component instantiation listener
+    * 
+    * @see WeldComponentInstantiationListener
+    */
+   @Override
+   protected void internalInit() 
+   {
+      super.internalInit();
+      this.weldComponentInstantiationListener = new NonContextual<WeldComponentInstantiationListener>(BeanManagerLookup.getBeanManager(), WeldComponentInstantiationListener.class);
+      this.weldWebRequestCycleProcessor = new NonContextual<WeldWebRequestCycleProcessor>(BeanManagerLookup.getBeanManager(), WeldWebRequestCycleProcessor.class);
+      addComponentInstantiationListener(weldComponentInstantiationListener.newInstance().produce().inject().get());
+   }
+
+
+   /**
+    * Override to return our Weld-specific request cycle processor
+    * 
+    * @see WeldWebRequestCycleProcessor
+    */
+   @Override
+   protected IRequestCycleProcessor newRequestCycleProcessor()
+   {
+      return weldWebRequestCycleProcessor.newInstance().produce().inject().get();
+   }
+
+   /**
+    * Override to return our Weld-specific request cycle
+    * 
+    * @see WeldRequestCycle
+    */
+   @Override
+   public RequestCycle newRequestCycle(final Request request, final Response response)
+   {
+      return new WeldRequestCycle(this, (WebRequest) request, (WebResponse) response);
+   }
+}


Property changes on: modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldApplication.java
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:eol-style
   + native

Added: modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldComponentInstantiationListener.java
===================================================================
--- modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldComponentInstantiationListener.java	                        (rev 0)
+++ modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldComponentInstantiationListener.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,33 @@
+package org.jboss.weld.wicket;
+
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.application.IComponentInstantiationListener;
+import org.jboss.weld.wicket.util.NonContextual;
+
+/**
+ * This listener uses the BeanManager to handle injections for all wicket components.
+ * 
+ * @author cpopetz
+ * 
+ */
+public class WeldComponentInstantiationListener implements IComponentInstantiationListener
+{
+   
+	@Inject
+   private BeanManager manager;
+	
+   public void onInstantiation(Component component)
+   {
+      /*
+       * The manager could be null in unit testing environments
+       */
+      if (manager != null)
+      {
+         // TODO Cache the NonContextual!
+         new NonContextual<Component>(manager, component.getClass()).existingInstance(component).inject();
+      }
+   }
+}
\ No newline at end of file


Property changes on: modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldComponentInstantiationListener.java
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:eol-style
   + native

Added: modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldMetaData.java
===================================================================
--- modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldMetaData.java	                        (rev 0)
+++ modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldMetaData.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,23 @@
+package org.jboss.weld.wicket;
+
+import org.apache.wicket.MetaDataKey;
+
+/**
+ * Public storage for the metadata key used by the Weld integration to store
+ * conversation ids in wicket page metadata.
+ * 
+ * @author cpopetz
+ * 
+ */
+public class WeldMetaData
+{
+
+   /**
+    * This is the key we will use to to store the conversation metadata in the
+    * wicket page.
+    */
+   public static final MetaDataKey<String> CID = new MetaDataKey<String>()
+   {
+      private static final long serialVersionUID = -8788010688731927318L; 
+   }; 
+}


Property changes on: modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldMetaData.java
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:eol-style
   + native

Added: modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldRequestCycle.java
===================================================================
--- modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldRequestCycle.java	                        (rev 0)
+++ modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldRequestCycle.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,166 @@
+package org.jboss.weld.wicket;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Set;
+
+import javax.enterprise.context.Conversation;
+import javax.enterprise.inject.AmbiguousResolutionException;
+import javax.enterprise.inject.UnsatisfiedResolutionException;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+
+import org.apache.wicket.IRequestTarget;
+import org.apache.wicket.Page;
+import org.apache.wicket.Response;
+import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.protocol.http.WebRequest;
+import org.apache.wicket.protocol.http.WebRequestCycle;
+import org.apache.wicket.request.target.component.BookmarkablePageRequestTarget;
+import org.apache.wicket.request.target.component.IPageRequestTarget;
+import org.jboss.weld.Container;
+import org.jboss.weld.context.ContextLifecycle;
+import org.jboss.weld.context.ConversationContext;
+import org.jboss.weld.conversation.ConversationImpl;
+import org.jboss.weld.conversation.ConversationManager;
+import org.jboss.weld.servlet.ConversationBeanStore;
+
+/**
+ * WeldRequestCycle is a subclass of the standard wicket WebRequestCycle which:
+ * <ul>
+ * <li>restores long-running conversations specified in wicket page metadata
+ * when a page target is first used.
+ * <li>propagates long running conversations to new page targets by specifying
+ * the above metadata
+ * <li>propagates long running conversations across redirects through the use of
+ * a request parameter if the redirect is handled with a BookmarkablePageRequest
+ * <li>Sets up the conversational context when the request target is set
+ * <li>Tears down the conversation context on detach() of the RequestCycle
+ * </ul>
+ * 
+ * @see WeldWebRequestCycleProcessor Which handles propogation of conversation
+ *      data for newly-started long running conversations, by storing their ids
+ *      in the page metadata
+ * @author cpopetz
+ * 
+ */
+public class WeldRequestCycle extends WebRequestCycle
+{
+
+   public WeldRequestCycle(WebApplication application, WebRequest request, Response response)
+   {
+      super(application, request, response);
+   }
+
+   /**
+    * Override to set up the conversation context and to choose the conversation
+    * if a conversation id is present in target metadata.
+    */
+   @Override
+   protected void onRequestTargetSet(IRequestTarget target)
+   {
+      super.onRequestTargetSet(target);
+
+      Page page = null;
+      if (target instanceof IPageRequestTarget)
+      {
+         page = ((IPageRequestTarget) target).getPage();
+      }
+
+      // Two possible specifications of cid: page metadata or request url; the
+      // latter is used to propagate the conversation to mounted (bookmarkable)
+      // paths after a redirect
+
+      String specifiedCid = null;
+      if (page != null)
+      {
+         specifiedCid = page.getMetaData(WeldMetaData.CID);
+      }
+      else
+      {
+         specifiedCid = request.getParameter("cid");
+      }
+
+      BeanManager manager = BeanManagerLookup.getBeanManager();
+
+      ConversationImpl conversation = (ConversationImpl) getInstanceByType(manager, Conversation.class);
+
+      // restore a conversation if it exists and we aren't already in it
+      if (specifiedCid != null && (conversation == null || !specifiedCid.equals(conversation.getUnderlyingId())))
+      {
+         getInstanceByType(manager, ConversationManager.class).beginOrRestoreConversation(specifiedCid);
+      }
+
+
+      ConversationContext conversationContext = Container.instance().services().get(ContextLifecycle.class).getConversationContext();
+      // Now set up the conversational context if it isn't already
+      if (!conversationContext.isActive())
+      {
+         // TODO account for invalidated session
+         conversationContext.setBeanStore(new ConversationBeanStore(((WebRequest) request).getHttpServletRequest().getSession(), false, conversation.getUnderlyingId()));
+         conversationContext.setActive(true);
+      }
+
+      // handle propagation of existing long running converstaions to new
+      // targets
+      if (!conversation.isTransient())
+      {
+         // Note that we can't propagate conversations with other redirect
+         // targets like RequestRedirectTarget through this mechanism, because
+         // it does not provide an interface to modify its target URL. If
+         // propagation with those targets is to be supported, it needs a custom
+         // Response subclass.
+         if (isRedirect() && target instanceof BookmarkablePageRequestTarget)
+         {
+            BookmarkablePageRequestTarget bookmark = (BookmarkablePageRequestTarget) target;
+            // if a cid has already been specified, don't override it
+            if (!bookmark.getPageParameters().containsKey("cid"))
+               bookmark.getPageParameters().add("cid", conversation.getUnderlyingId());
+         }
+
+         // If we have a target page, propagate the conversation to the page's
+         // metadata
+         if (page != null)
+         {
+            page.setMetaData(WeldMetaData.CID, conversation.getUnderlyingId());
+         }
+      }
+
+
+   }
+
+   @SuppressWarnings("unchecked")
+   private <T> T getInstanceByType(BeanManager manager, Class<T> beanType, Annotation... bindings)
+   {
+      Bean<T> bean = (Bean<T>) ensureUniqueBean(beanType, manager.getBeans(beanType, bindings));
+      return (T) manager.getReference(bean, beanType, manager.createCreationalContext(bean));
+   }
+
+   private static Bean<?> ensureUniqueBean(Type type, Set<Bean<?>> beans)
+   {
+      if (beans.size() == 0)
+      {
+         throw new UnsatisfiedResolutionException("Unable to resolve any Web Beans of " + type);
+      }
+      else if (beans.size() > 1)
+      {
+         throw new AmbiguousResolutionException("More than one bean available for type " + type);
+      }
+      return beans.iterator().next();
+   }
+
+   @Override
+   public void detach()
+   {
+      super.detach();
+      ConversationContext conversationContext = Container.instance().services().get(ContextLifecycle.class).getConversationContext();
+      // cleanup and deactivate the conversation context
+      if (conversationContext.isActive())
+      {
+         ConversationManager conversationManager = getInstanceByType(BeanManagerLookup.getBeanManager(), ConversationManager.class);
+         conversationManager.cleanupConversation();
+         conversationContext.setActive(false);
+      }
+   }
+
+}
\ No newline at end of file


Property changes on: modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldRequestCycle.java
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:eol-style
   + native

Added: modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldWebRequestCycleProcessor.java
===================================================================
--- modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldWebRequestCycleProcessor.java	                        (rev 0)
+++ modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldWebRequestCycleProcessor.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,41 @@
+package org.jboss.weld.wicket;
+
+import javax.enterprise.context.Conversation;
+import javax.inject.Inject;
+
+import org.apache.wicket.Page;
+import org.apache.wicket.RequestCycle;
+import org.apache.wicket.protocol.http.WebRequestCycleProcessor;
+
+/**
+ * WeldWebRequestCycleProcessor is a subclass of the standard wicket
+ * WebRequestCycleProcessor which saves the conversation id of any long-running
+ * cornversation in wicket page metadata.
+ * 
+ * @author cpopetz
+ * 
+ */
+public class WeldWebRequestCycleProcessor extends WebRequestCycleProcessor
+{
+   @Inject
+   Conversation conversation;
+   
+   /**
+    * If a long running conversation has been started, store its id into page
+    * metadata
+    */
+   @Override
+   public void respond(RequestCycle requestCycle)
+   {
+      super.respond(requestCycle);
+      if (!conversation.isTransient())
+      {
+         Page page = RequestCycle.get().getResponsePage();
+         if (page != null)
+         {
+            page.setMetaData(WeldMetaData.CID, conversation.getId());
+         }
+      }
+      
+   }
+}
\ No newline at end of file


Property changes on: modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/WeldWebRequestCycleProcessor.java
___________________________________________________________________
Name: svn:executable
   + 
Name: svn:eol-style
   + native

Added: modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/util/NonContextual.java
===================================================================
--- modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/util/NonContextual.java	                        (rev 0)
+++ modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/util/NonContextual.java	2010-04-20 16:15:07 UTC (rev 12528)
@@ -0,0 +1,184 @@
+package org.jboss.weld.wicket.util;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionTarget;
+
+/**
+ * Perform production, injection, lifecycle callbacks and cleanup on a non-contextual object
+ * 
+ * @author pmuir
+ *
+ * @param <T>
+ */
+public class NonContextual<T>
+{
+
+   // Store the injection target. The CDI spec doesn't require an implementation
+   // to cache it, so we do
+   private final InjectionTarget<? extends T> injectionTarget;
+
+   // Store a reference to the CDI BeanManager
+   private final BeanManager beanManager;
+
+   /**
+    * Create an injector for the given class
+    */
+   public NonContextual(BeanManager manager, Class<? extends T> clazz)
+   {
+      this.beanManager = manager;
+
+      // Generate an "Annotated Type"
+      AnnotatedType<? extends T> type = manager.createAnnotatedType(clazz);
+
+      // Generate the InjectionTarget
+      this.injectionTarget = manager.createInjectionTarget(type);
+   }
+
+   public Instance<T> newInstance()
+   {
+      return new Instance<T>(beanManager, (InjectionTarget<T>) injectionTarget);
+   }
+   
+   public Instance<T> existingInstance(T instance)
+   {
+      return new Instance<T>(beanManager, (InjectionTarget<T>) injectionTarget, instance);
+   }
+ 
+   /**
+    * Represents a non-contextual instance
+    * 
+    * @author pmuir
+    * 
+    * @param <T>
+    */
+   public static class Instance<T>
+   {
+
+      private final CreationalContext<T> ctx;
+      private final InjectionTarget<T> injectionTarget;
+      private T instance;
+      private boolean disposed = false;
+
+      private Instance(BeanManager beanManager, InjectionTarget<T> injectionTarget)
+      {
+         this.injectionTarget = injectionTarget;
+         this.ctx = beanManager.createCreationalContext(null);
+      }
+      
+      private Instance(BeanManager beanManager, InjectionTarget<T> injectionTarget, T instance)
+      {
+         this.injectionTarget = injectionTarget;
+         this.ctx = beanManager.createCreationalContext(null);
+         this.instance = instance;
+      }
+
+      /**
+       * Get the instance
+       * 
+       * @return
+       */
+      public T get()
+      {
+         return instance;
+      }
+
+      /**
+       * Create the instance
+       * 
+       * @return
+       */
+      public Instance<T> produce()
+      {
+         if (this.instance != null)
+         {
+            throw new IllegalStateException("Trying to call produce() on already constructed instance");
+         }
+         if (disposed)
+         {
+            throw new IllegalStateException("Trying to call produce() on an already disposed instance");
+         }
+         this.instance = injectionTarget.produce(ctx);
+         return this;
+      }
+
+      /**
+       * Inject the instance
+       * 
+       * @return
+       */
+      public Instance<T> inject()
+      {
+         if (this.instance == null)
+         {
+            throw new IllegalStateException("Trying to call inject() before produce() was called");
+         }
+         if (disposed)
+         {
+            throw new IllegalStateException("Trying to call inject() on already disposed instance");
+         }
+         injectionTarget.inject(instance, ctx);
+         return this;
+      }
+
+      /**
+       * Call the @PostConstruct callback
+       * 
+       * @return
+       */
+      public Instance<T> postConstruct()
+      {
+         if (this.instance == null)
+         {
+            throw new IllegalStateException("Trying to call postConstruct() before produce() was called");
+         }
+         if (disposed)
+         {
+            throw new IllegalStateException("Trying to call preDestroy() on already disposed instance");
+         }
+         injectionTarget.postConstruct(instance);
+         return this;
+      }
+
+      /**
+       * Call the @PreDestroy callback
+       * 
+       * @return
+       */
+      public Instance<T> preDestroy()
+      {
+         if (this.instance == null)
+         {
+            throw new IllegalStateException("Trying to call preDestroy() before produce() was called");
+         }
+         if (disposed)
+         {
+            throw new IllegalStateException("Trying to call preDestroy() on already disposed instance");
+         }
+         injectionTarget.preDestroy(instance);
+         return this;
+      }
+
+      /**
+       * Dispose of the instance, doing any necessary cleanup
+       * 
+       */
+      public Instance<T> dispose()
+      {
+         if (this.instance == null)
+         {
+            throw new IllegalStateException("Trying to call dispose() before produce() was called");
+         }
+         if (disposed)
+         {
+            throw new IllegalStateException("Trying to call dispose() on already disposed instance");
+         }
+         injectionTarget.dispose(instance);
+         ctx.release();
+         return this;
+      }
+
+   }
+
+}
\ No newline at end of file


Property changes on: modules/wicket/trunk/src/main/java/org/jboss/weld/wicket/util/NonContextual.java
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the seam-commits mailing list