[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