You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by pa...@apache.org on 2013/11/22 09:42:25 UTC
[03/11] revert wicket-cdi-1.1 to wicket-cdi
http://git-wip-us.apache.org/repos/asf/wicket/blob/10326bf7/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ConversationPropagation.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ConversationPropagation.java b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ConversationPropagation.java
index e75b795..e70ff9c 100644
--- a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ConversationPropagation.java
+++ b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ConversationPropagation.java
@@ -1,79 +1,78 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.cdi;
-
-
-import org.apache.wicket.Page;
-import org.apache.wicket.request.IRequestHandler;
-
-/**
- * Various modes of propagating persistent conversations across requests.
- *
- * @author igor
- */
-public enum ConversationPropagation implements IConversationPropagation {
- /**
- * No conversational propagation takes place
- */
- NONE {
- @Override
- public boolean propagatesViaPage(Page page, IRequestHandler handler)
- {
- return false;
- }
-
- @Override
- public boolean propagatesViaParameters(IRequestHandler handler)
- {
- return false;
- }
- },
- /**
- * Persistent conversations are propagated between non-bookmarkable pages
- * only
- */
- NONBOOKMARKABLE {
- @Override
- public boolean propagatesViaPage(Page page, IRequestHandler handler)
- {
- return true;
- }
-
- @Override
- public boolean propagatesViaParameters(IRequestHandler handler)
- {
- return false;
- }
- },
- /**
- * Persistent conversations are propagated between bookmarkable and
- * non-bookmarkable pages
- */
- ALL {
- @Override
- public boolean propagatesViaPage(Page page, IRequestHandler handler)
- {
- return true;
- }
-
- @Override
- public boolean propagatesViaParameters(IRequestHandler handler)
- {
- return true;
- }
- };
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.cdi;
+
+import javax.enterprise.context.ConversationScoped;
+
+import org.apache.wicket.Page;
+import org.apache.wicket.request.IRequestHandler;
+
+/**
+ * Various modes of propagating persistent conversations across requests.
+ *
+ * @see ConversationScoped
+ *
+ * @author igor
+ */
+public enum ConversationPropagation implements IConversationPropagation {
+ /** No conversational propagation takes place */
+ NONE {
+ @Override
+ public boolean propagatesViaPage(Page page, IRequestHandler handler)
+ {
+ return false;
+ }
+
+ @Override
+ public boolean propagatesViaParameters(IRequestHandler handler)
+ {
+ return false;
+ }
+ },
+ /**
+ * Pesistent conversations are propagated between non-bookmarkable pages only
+ */
+ NONBOOKMARKABLE {
+ @Override
+ public boolean propagatesViaPage(Page page, IRequestHandler handler)
+ {
+ return true;
+ }
+
+ @Override
+ public boolean propagatesViaParameters(IRequestHandler handler)
+ {
+ return false;
+ }
+ },
+ /**
+ * Persistent conversations are propagated between bookmarkable and non-bookmarkable pages
+ */
+ ALL {
+ @Override
+ public boolean propagatesViaPage(Page page, IRequestHandler handler)
+ {
+ return true;
+ }
+
+ @Override
+ public boolean propagatesViaParameters(IRequestHandler handler)
+ {
+ return true;
+ }
+ };
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/10326bf7/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ConversationPropagator.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ConversationPropagator.java b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ConversationPropagator.java
index d9d4e1c..568e117 100644
--- a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ConversationPropagator.java
+++ b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ConversationPropagator.java
@@ -1,505 +1,472 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.cdi;
-
-
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.context.Conversation;
-import javax.enterprise.context.NonexistentConversationException;
-import javax.inject.Inject;
-
-import org.apache.wicket.Component;
-import org.apache.wicket.MetaDataKey;
-import org.apache.wicket.Page;
-import org.apache.wicket.core.request.handler.BufferedResponseRequestHandler;
-import org.apache.wicket.core.request.handler.IPageClassRequestHandler;
-import org.apache.wicket.core.request.handler.IPageRequestHandler;
-import org.apache.wicket.core.request.mapper.StalePageException;
-import org.apache.wicket.request.IRequestHandler;
-import org.apache.wicket.request.IRequestHandlerDelegate;
-import org.apache.wicket.request.Url;
-import org.apache.wicket.request.component.IRequestablePage;
-import org.apache.wicket.request.cycle.AbstractRequestCycleListener;
-import org.apache.wicket.request.cycle.RequestCycle;
-import org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
-import org.apache.wicket.request.resource.PackageResourceReference;
-import org.apache.wicket.util.lang.Objects;
-import org.apache.wicket.util.visit.IVisit;
-import org.apache.wicket.util.visit.IVisitor;
-import org.apache.wicket.util.visit.Visits;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A request cycle listener that takes care of propagating persistent
- * conversations.
- *
- * @author igor
- */
-@ApplicationScoped
-public class ConversationPropagator extends AbstractRequestCycleListener
-{
-
- private static final Logger logger = LoggerFactory.getLogger(ConversationPropagator.class);
-
- private static final MetaDataKey<String> CID_KEY = ConversationIdMetaKey.INSTANCE;
-
- static final String CID_ATTR = "cid";
-
- @Inject
- CdiConfiguration cdiConfiguration;
-
- @Inject
- AbstractCdiContainer container;
-
- @Inject
- ConversationManager conversationManager;
-
-
- private Conversation getConversation()
- {
- return container.getCurrentConversation();
- }
-
- @Override
- public void onRequestHandlerResolved(RequestCycle cycle, IRequestHandler handler)
- {
- Conversation conversation = getConversation();
- logger.debug("In onRequestHandlerResolved id = {}", conversation.getId());
- String cid = cycle.getRequest().getRequestParameters().getParameterValue(CID_ATTR)
- .toString();
- Page page = getPage(handler);
-
- if (page == null)
- {
- return;
- }
-
- if (cid == null)
- {
- cid = page.getMetaData(CID_KEY);
- }
-
-
- if (cid != null && !conversation.isTransient()
- && !Objects.isEqual(conversation.getId(), cid))
- {
- logger.info("Conversation {} has expired for {}", cid, page);
- throw new ConversationExpiredException(null, cid, page, handler);
- }
-
- activateConversationIfNeeded(page, cycle, handler, cid);
- }
-
- @Override
- public IRequestHandler onException(RequestCycle cycle, Exception ex)
- {
- // if we are handling a stale page exception then use its conversation
- // since we are most
- // likely about to rerender it.
-
- if (ex instanceof StalePageException)
- {
- IRequestablePage requestable = ((StalePageException)ex).getPage();
- if (requestable instanceof Page)
- {
- Page page = (Page)requestable;
- String cid = container.getConversationMarker(page);
- if (cid != null)
- {
- try
- {
- activateConversationIfNeeded(page, cycle, null, cid);
- return null;
- }
- catch (ConversationExpiredException e)
- {
- // ignore, we will start a new one below
- }
- }
- }
- }
-
- activateConversationIfNeeded(null, cycle, null, null);
- return null;
- }
-
- private void activateConversationIfNeeded(Page page, RequestCycle cycle,
- IRequestHandler handler, String cid)
- {
- if (!activateForHandler(handler))
- {
- return;
- }
-
- try
- {
- Conversation conversation = getConversation();
-
- if (!(conversation.isTransient() && cid == null))
- {
- logger.debug("Activating conversation {}", cid);
- container.activateConversationalContext(cycle, cid);
- }
-
- }
- catch (NonexistentConversationException e)
- {
- logger.info("Unable to restore conversation with id {}", cid, e.getMessage());
- logger.debug("Unable to restore conversation", e);
- throw new ConversationExpiredException(e, cid, getPage(handler), handler);
- }
-
- }
-
- @Override
- public void onRequestHandlerExecuted(RequestCycle cycle, IRequestHandler handler)
- {
- Conversation conversation = getConversation();
- logger.debug("In onRequestHandlerExecuted id = {}", conversation.getId());
- Page page = getPage(handler);
-
- if (page == null)
- {
- return;
- }
-
- if (autoEndIfNecessary(page, handler, conversation))
- {
- container.activateConversationalContext(cycle, null);
- }
- else
- {
- autoBeginIfNecessary(page, handler);
- }
- if (getPropagation().propagatesViaPage(page, handler))
- {
- // propagate a conversation across non-bookmarkable page instances
- setConversationOnPage(page);
- }
- }
-
- @Override
- public void onRequestHandlerScheduled(RequestCycle cycle, IRequestHandler handler)
- {
- // propagate current non-transient conversation to the newly scheduled
- // page
-
- Conversation conversation = getConversation();
- logger.debug("In onRequestHandlerScheduled id = {}", conversation.getId());
- if (conversation.isTransient())
- {
- return;
- }
- boolean propagated = false;
- Page page = getPage(handler);
- if (page != null)
- {
- if (getPropagation().propagatesViaPage(page, handler))
- {
- // propagate a conversation across non-bookmarkable page
- // instances
- setConversationOnPage(page);
- propagated = true;
- }
- }
-
- if (getPropagation().propagatesViaParameters(handler))
- {
- // propagate cid to a scheduled bookmarkable page
-
- logger.debug(
- "Propagating non-transient conversation {} via page parameters of handler {}",
- conversation.getId(), handler);
-
- PageParameters parameters = getPageParameters(handler);
- if (parameters != null)
- {
- parameters.set(CID_ATTR, conversation.getId());
- propagated = true;
- }
- }
- if (!propagated && getAuto())
- {
- getConversationManager().scheduleConversationEnd();
- }
- }
-
- protected void setConversationOnPage(Page page)
- {
- Conversation conversation = getConversation();
- if (conversation.isTransient())
- {
- clearConversationOnPage(page);
- }
- else
- {
-
- logger.debug("Propagating non-transient conversation {} via meta of page instance {}",
- conversation.getId(), page);
-
- page.setMetaData(CID_KEY, conversation.getId());
- }
- }
-
- protected void clearConversationOnPage(Page page)
- {
- Conversation conversation = getConversation();
- logger.debug("Detaching transient conversation {} via meta of page instance {}",
- conversation.getId(), page);
-
- page.setMetaData(CID_KEY, null);
- }
-
- @Override
- public void onUrlMapped(RequestCycle cycle, IRequestHandler handler, Url url)
- {
- Conversation conversation = getConversation();
- logger.debug("In onUrlMapped id = {}", conversation.getId());
- // no need to propagate the conversation to packaged resources, they
- // should never change
- if (handler instanceof ResourceReferenceRequestHandler)
- {
- if (((ResourceReferenceRequestHandler)handler).getResourceReference() instanceof PackageResourceReference)
- {
- return;
- }
- }
-
-
- if (conversation.isTransient())
- {
- return;
- }
-
- if (getPropagation().propagatesViaParameters(handler))
- {
- // propagate cid to bookmarkable pages via urls
-
- logger.debug("Propagating non-transient conversation {} via url", conversation.getId());
-
- url.setQueryParameter(CID_ATTR, conversation.getId());
- }
- else
- {
- // we did not propagate.
- // Cancel scheduled conversation end if page is auto.
- Page page = getPage(handler);
- if (page != null)
- {
- Conversational annotation = page.getClass().getAnnotation(Conversational.class);
- if (annotation != null)
- {
- if (annotation.auto()
- && getConversationManager().isConversationScheduledForEnd())
- {
- getConversationManager().cancelConversationEnd(); // was
- // scheduled
- // to
- // end
- // but
- // next
- // page
- // is
- // auto
- }
- }
- }
- }
- }
-
- /**
- * Determines whether or not a conversation should be activated for the
- * specified handler. This method is used to filter out conversation
- * activation for utility handlers such as the
- * {@link BufferedResponseRequestHandler}
- *
- * @param handler
- * @return {@code true} iff a conversation should be activated
- */
- protected boolean activateForHandler(IRequestHandler handler)
- {
- if (handler != null)
- {
- if (handler instanceof BufferedResponseRequestHandler)
- {
- // we do not care about pages that are being rendered from a
- // buffer
- return false;
- }
- }
- return true;
- }
-
- protected void autoBeginIfNecessary(Page page, IRequestHandler handler)
- {
-
- if (page == null)
- {
- return;
- }
-
- Conversational annotation = page.getClass().getAnnotation(Conversational.class);
-
- boolean auto = getAuto();
- auto |= annotation == null ? false : annotation.auto();
-
- // possibly changing propagation and auto is not set
- if (annotation == null && !auto)
- {
- return;
- }
-
- if (getConversation().isTransient())
- {
- if (auto)
- {
- getConversation().begin();
- logger.debug("Auto-began conversation {} for page {}", getConversation().getId(),
- page);
- }
- }
- IConversationPropagation prop = annotation != null ? annotation.prop() : getPropagation();
- // The conversationManager is attached to a conversation so update
- if (!getConversation().isTransient())
- {
- getConversationManager().setPropagation(prop);
- getConversationManager().setManageConversation(auto);
- }
- else
- {
- if (prop != getPropagation())
- {
- logger.info("Not setting propagation to {} because no conversation is started.",
- prop);
- }
- }
- }
-
- protected boolean autoEndIfNecessary(Page page, IRequestHandler handler,
- Conversation conversation)
- {
- if (page == null || conversation.isTransient())
- {
- return false;
- }
-
- boolean endConversation = getConversationManager().isConversationScheduledForEnd();
- if (endConversation)
- {
- String cid = conversation.getId();
- getConversation().end();
- logger.debug("Auto-ended conversation {} for page {}", cid, page);
- }
- return endConversation;
- }
-
-
- // Currently not being used will reinvestigate this concept.
- protected boolean hasConversationalComponent(Page page)
- {
- Boolean hasConversational = Visits.visit(page, new IVisitor<Component, Boolean>()
- {
- @Override
- public void component(Component object, IVisit<Boolean> visit)
- {
- Conversational annotation = object.getClass().getAnnotation(Conversational.class);
- if (annotation != null)
- {
- visit.stop(true);
- }
- }
- });
-
- return hasConversational == null ? false : hasConversational;
- }
-
- /**
- * Resolves a page instance from the request handler iff the page instance
- * is already created
- *
- * @param handler
- * @return page or {@code null} if none
- */
- public static Page getPage(IRequestHandler handler)
- {
- while (handler instanceof IRequestHandlerDelegate)
- {
- handler = ((IRequestHandlerDelegate)handler).getDelegateHandler();
- }
-
- if (handler instanceof IPageRequestHandler)
- {
- IPageRequestHandler pageHandler = (IPageRequestHandler)handler;
- if (pageHandler.isPageInstanceCreated())
- {
- return (Page)pageHandler.getPage();
- }
- }
- return null;
- }
-
- /**
- * Resolves page parameters from a request handler
- *
- * @param handler
- * @return page parameters or {@code null} if none
- */
- protected PageParameters getPageParameters(IRequestHandler handler)
- {
- if (handler instanceof IPageClassRequestHandler)
- {
- IPageClassRequestHandler pageHandler = (IPageClassRequestHandler)handler;
- return pageHandler.getPageParameters();
- }
- return null;
- }
-
- ConversationManager getConversationManager()
- {
- if (getConversation().isTransient())
- {
- logger.warn("Accessing Conversation Manager from transient Conversation Context");
- }
- return conversationManager;
- }
-
- Boolean getAuto()
- {
- if (getConversation().isTransient())
- {
- logger.debug("Getting Global Auto setting");
- return cdiConfiguration.isAutoConversationManagement();
- }
- logger.debug("Getting Auto setting for conversation = {}", getConversation().getId());
- return getConversationManager().getManageConversation();
- }
-
- IConversationPropagation getPropagation()
- {
- if (getConversation().isTransient())
- {
- logger.debug("Getting global Propagation {}.", cdiConfiguration.getPropagation());
- return cdiConfiguration.getPropagation();
- }
- logger.debug("Propagation is set to {} with id = {}", getConversationManager()
- .getPropagation(), getConversation().getId());
- return getConversationManager().getPropagation();
- }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.cdi;
+
+import javax.enterprise.context.Conversation;
+import javax.enterprise.context.ConversationScoped;
+import javax.enterprise.context.NonexistentConversationException;
+import javax.inject.Inject;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.Component;
+import org.apache.wicket.MetaDataKey;
+import org.apache.wicket.Page;
+import org.apache.wicket.core.request.handler.BufferedResponseRequestHandler;
+import org.apache.wicket.core.request.handler.IPageClassRequestHandler;
+import org.apache.wicket.core.request.handler.IPageRequestHandler;
+import org.apache.wicket.core.request.mapper.StalePageException;
+import org.apache.wicket.request.IRequestHandler;
+import org.apache.wicket.request.IRequestHandlerDelegate;
+import org.apache.wicket.request.Url;
+import org.apache.wicket.request.component.IRequestablePage;
+import org.apache.wicket.request.cycle.AbstractRequestCycleListener;
+import org.apache.wicket.request.cycle.IRequestCycleListener;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.resource.PackageResourceReference;
+import org.apache.wicket.util.lang.Args;
+import org.apache.wicket.util.lang.Objects;
+import org.apache.wicket.util.visit.IVisit;
+import org.apache.wicket.util.visit.IVisitor;
+import org.apache.wicket.util.visit.Visits;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A request cycle listener that takes care of propagating persistent conversations.
+ *
+ * @see ConversationScoped
+ *
+ * @author igor
+ */
+public class ConversationPropagator extends AbstractRequestCycleListener
+{
+ private static final Logger logger = LoggerFactory.getLogger(ConversationPropagator.class);
+
+ private static final MetaDataKey<String> CID_KEY = ConversationIdMetaKey.INSTANCE;
+
+ private static final MetaDataKey<Boolean> CONVERSATION_STARTED_KEY = new MetaDataKey<Boolean>()
+ {
+ };
+
+
+ public static final String CID = "cid";
+
+ private final CdiContainer container;
+
+ /** propagation mode to use */
+ private final IConversationPropagation propagation;
+
+ private final Application application;
+
+ private final boolean auto;
+
+ @Inject
+ Conversation conversation_;
+
+ @Inject
+ AutoConversation autoConversation;
+
+ /**
+ * Constructor
+ *
+ * @param container
+ * @param propagation
+ */
+ public ConversationPropagator(Application application, CdiContainer container,
+ IConversationPropagation propagation)
+ {
+ this(application, container, propagation, false);
+ }
+
+
+ /**
+ * Constructor
+ *
+ * @param container
+ * @param propagation
+ */
+ public ConversationPropagator(Application application, CdiContainer container,
+ IConversationPropagation propagation, boolean auto)
+ {
+ Args.notNull(application, "application");
+ Args.notNull(container, "container");
+ Args.notNull(propagation, "propagation");
+
+ if (propagation == ConversationPropagation.NONE)
+ {
+ throw new IllegalArgumentException(
+ "If propagation is NONE do not set up the propagator");
+ }
+
+ this.application = application;
+ this.container = container;
+ this.propagation = propagation;
+ this.auto = auto;
+
+ container.getNonContextualManager().postConstruct(this);
+ }
+
+ private Conversation getConversation(RequestCycle cycle)
+ {
+ return Boolean.TRUE.equals(cycle.getMetaData(CONVERSATION_STARTED_KEY)) ? conversation_
+ : null;
+ }
+
+ @Override
+ public void onRequestHandlerResolved(RequestCycle cycle, IRequestHandler handler)
+ {
+ String cid = cycle.getRequest().getRequestParameters().getParameterValue(CID).toString();
+ Page page = getPage(handler);
+
+ if (cid == null && page != null)
+ {
+ cid = page.getMetaData(CID_KEY);
+ }
+
+ Conversation current = getConversation(cycle);
+ if (current != null && !Objects.isEqual(current.getId(), cid))
+ {
+ logger.info("Conversation {} has expired for {}", cid, page);
+ throw new ConversationExpiredException(null, cid, page, handler);
+ }
+
+ activateConversationIfNeeded(cycle, handler, cid);
+ }
+
+ @Override
+ public IRequestHandler onException(RequestCycle cycle, Exception ex)
+ {
+ // if we are handling a stale page exception then use its conversation since we are most
+ // likely about to rerender it.
+
+ if (ex instanceof StalePageException)
+ {
+ IRequestablePage requestable = ((StalePageException)ex).getPage();
+ if (requestable instanceof Page)
+ {
+ String cid = container.getConversationMarker((Page)requestable);
+ if (cid != null)
+ {
+ try
+ {
+ activateConversationIfNeeded(cycle, null, cid);
+ return null;
+ }
+ catch (ConversationExpiredException e)
+ {
+ // ignore, we will start a new one below
+ }
+ }
+ }
+ }
+
+ activateConversationIfNeeded(cycle, null, null);
+ return null;
+ }
+
+ private void activateConversationIfNeeded(RequestCycle cycle, IRequestHandler handler,
+ String cid)
+ {
+ Conversation current = getConversation(cycle);
+
+ if (current != null || !activateForHandler(handler))
+ {
+ return;
+ }
+
+ logger.debug("Activating conversation {}", cid);
+
+ try
+ {
+ container.activateConversationalContext(cycle, cid);
+ fireOnAfterConversationStarted(cycle);
+ }
+ catch (NonexistentConversationException e)
+ {
+ logger.info("Unable to restore conversation with id {}", cid, e.getMessage());
+ logger.debug("Unable to restore conversation", e);
+ fireOnAfterConversationStarted(cycle);
+ throw new ConversationExpiredException(e, cid, getPage(handler), handler);
+ }
+
+ cycle.setMetaData(CONVERSATION_STARTED_KEY, true);
+ }
+
+ private void fireOnAfterConversationStarted(RequestCycle cycle)
+ {
+ for (IRequestCycleListener listener : application.getRequestCycleListeners())
+ {
+ if (listener instanceof ICdiAwareRequestCycleListener)
+ {
+ ((ICdiAwareRequestCycleListener)listener).onAfterConversationActivated(cycle);
+ }
+ }
+ }
+
+ @Override
+ public void onRequestHandlerExecuted(RequestCycle cycle, IRequestHandler handler)
+ {
+ Conversation conversation = getConversation(cycle);
+
+ if (conversation == null)
+ {
+ return;
+ }
+
+ Page page = getPage(handler);
+
+ if (page == null)
+ {
+ return;
+ }
+
+ // apply auto semantics
+
+ autoEndIfNecessary(page, handler, conversation);
+ autoBeginIfNecessary(page, handler, conversation);
+
+ if (propagation.propagatesViaPage(page, handler))
+ {
+ // propagate a conversation across non-bookmarkable page instances
+ setConversationOnPage(conversation, page);
+ }
+ }
+
+ @Override
+ public void onRequestHandlerScheduled(RequestCycle cycle, IRequestHandler handler)
+ {
+ // propagate current non-transient conversation to the newly scheduled page
+
+ Conversation conversation = getConversation(cycle);
+
+ if (conversation == null || conversation.isTransient())
+ {
+ return;
+ }
+
+ Page page = getPage(handler);
+ if (page != null)
+ {
+ if (propagation.propagatesViaPage(page, handler))
+ {
+ // propagate a conversation across non-bookmarkable page instances
+ setConversationOnPage(conversation, page);
+ }
+ }
+
+ if (propagation.propagatesViaParameters(handler))
+ {
+ // propagate cid to a scheduled bookmarkable page
+
+ logger.debug(
+ "Propagating non-transient conversation {} via page parameters of handler {}",
+ conversation.getId(), handler);
+
+ PageParameters parameters = getPageParameters(handler);
+ if (parameters != null)
+ {
+ parameters.set(CID, conversation.getId());
+ }
+ }
+ }
+
+ protected void setConversationOnPage(Conversation conversation, Page page)
+ {
+ if (conversation == null || conversation.isTransient())
+ {
+ logger.debug("Detaching transient conversation {} via meta of page instance {}",
+ (conversation == null ? "null" : conversation.getId()), page);
+
+ page.setMetaData(CID_KEY, null);
+ }
+ else
+ {
+
+ logger.debug("Propagating non-transient conversation {} via meta of page instance {}",
+ conversation.getId(), page);
+
+ page.setMetaData(CID_KEY, conversation.getId());
+ }
+ }
+
+ @Override
+ public void onUrlMapped(RequestCycle cycle, IRequestHandler handler, Url url)
+ {
+ // no need to propagate the conversation to packaged resources, they should never change
+ if (handler instanceof ResourceReferenceRequestHandler)
+ {
+ if (((ResourceReferenceRequestHandler)handler).getResourceReference() instanceof PackageResourceReference)
+ {
+ return;
+ }
+ }
+
+ Conversation conversation = getConversation(cycle);
+
+ if (conversation == null || conversation.isTransient())
+ {
+ return;
+ }
+
+ if (propagation.propagatesViaParameters(handler))
+ {
+ // propagate cid to bookmarkable pages via urls
+
+ logger.debug("Propagating non-transient conversation {} via url", conversation.getId());
+
+ url.setQueryParameter(CID, conversation.getId());
+ }
+ }
+
+ @Override
+ public void onDetach(RequestCycle cycle)
+ {
+ Conversation conversation = getConversation(cycle);
+ if (conversation != null)
+ {
+ logger.debug("Deactivating conversation {}", conversation.getId());
+
+ for (IRequestCycleListener listener : application.getRequestCycleListeners())
+ {
+ if (listener instanceof ICdiAwareRequestCycleListener)
+ {
+ ((ICdiAwareRequestCycleListener)listener).onBeforeConversationDeactivated(cycle);
+ }
+ }
+ container.deactivateConversationalContext(cycle);
+
+ cycle.setMetaData(CONVERSATION_STARTED_KEY, null);
+ }
+ }
+
+ /**
+ * Determines whether or not a conversation should be activated fro the specified handler. This
+ * method is used to filter out conversation activation for utility handlers such as the
+ * {@link BufferedResponseRequestHandler}
+ *
+ * @param handler
+ * @return {@code true} iff a conversation should be activated
+ */
+ protected boolean activateForHandler(IRequestHandler handler)
+ {
+ if (handler != null)
+ {
+ if (handler instanceof BufferedResponseRequestHandler)
+ {
+ // we do not care about pages that are being rendered from a buffer
+ return false;
+ }
+ }
+ return true;
+ }
+
+ protected void autoBeginIfNecessary(Page page, IRequestHandler handler,
+ Conversation conversation)
+ {
+ if (!auto || conversation == null || !conversation.isTransient() || page == null ||
+ !propagation.propagatesViaPage(page, handler) || !hasConversationalComponent(page))
+ {
+ return;
+ }
+
+ // auto activate conversation
+
+ conversation.begin();
+ autoConversation.setAutomatic(true);
+
+ logger.debug("Auto-began conversation {} for page {}", conversation.getId(), page);
+ }
+
+ protected void autoEndIfNecessary(Page page, IRequestHandler handler, Conversation conversation)
+ {
+ if (!auto || conversation == null || conversation.isTransient() || page == null ||
+ !propagation.propagatesViaPage(page, handler) || hasConversationalComponent(page) ||
+ autoConversation.isAutomatic() == false)
+ {
+ return;
+ }
+
+ // auto de-activate conversation
+
+ String cid = conversation.getId();
+
+ autoConversation.setAutomatic(false);
+ conversation.end();
+
+ logger.debug("Auto-ended conversation {} for page {}", cid, page);
+ }
+
+
+ protected boolean hasConversationalComponent(Page page)
+ {
+ Boolean hasConversational = Visits.visit(page, new IVisitor<Component, Boolean>()
+ {
+ @Override
+ public void component(Component object, IVisit<Boolean> visit)
+ {
+ if (object instanceof ConversationalComponent)
+ {
+ visit.stop(true);
+ }
+ }
+ });
+
+ return hasConversational == null ? false : hasConversational;
+ }
+
+ /**
+ * Resolves a page instance from the request handler iff the page instance is already created
+ *
+ * @param handler
+ * @return page or {@code null} if none
+ */
+ public static Page getPage(IRequestHandler handler)
+ {
+ while (handler instanceof IRequestHandlerDelegate)
+ {
+ handler = ((IRequestHandlerDelegate)handler).getDelegateHandler();
+ }
+
+ if (handler instanceof IPageRequestHandler)
+ {
+ IPageRequestHandler pageHandler = (IPageRequestHandler)handler;
+ if (pageHandler.isPageInstanceCreated())
+ {
+ return (Page)pageHandler.getPage();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Resolves page parameters from a request handler
+ *
+ * @param handler
+ * @return page parameters or {@code null} if none
+ */
+ protected PageParameters getPageParameters(IRequestHandler handler)
+ {
+ if (handler instanceof IPageClassRequestHandler)
+ {
+ IPageClassRequestHandler pageHandler = (IPageClassRequestHandler)handler;
+ return pageHandler.getPageParameters();
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/10326bf7/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/Conversational.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/Conversational.java b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/Conversational.java
deleted file mode 100644
index 01cb046..0000000
--- a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/Conversational.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.cdi;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import javax.enterprise.inject.Typed;
-
-import org.apache.wicket.Page;
-
-/**
- * @author jsarman
- */
-@Documented
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-@Typed(Page.class)
-public @interface Conversational {
- ConversationPropagation prop() default ConversationPropagation.NONBOOKMARKABLE;
-
- boolean auto() default true;
-}
http://git-wip-us.apache.org/repos/asf/wicket/blob/10326bf7/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ConversationalComponent.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ConversationalComponent.java b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ConversationalComponent.java
index 05190f1..e041a87 100644
--- a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ConversationalComponent.java
+++ b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ConversationalComponent.java
@@ -17,16 +17,13 @@
package org.apache.wicket.cdi;
/**
- * Marks a component that requires a conversation. This marker is used by the
- * automatic conversation management feature (
- * {@link CdiConfiguration#setAutoConversationManagement(boolean)}) to
- * automatically begin and end conversations based on the presence of these
- * components in the component hierarchy of pages (can be applied to the page
- * itself).
+ * Marks a component that requires a conversation. This marker is used by the automatic conversation
+ * management feature ({@link CdiConfiguration#setAutoConversationManagement(boolean)}) to
+ * automatically begin and end conversations based on the presence of these components in the
+ * component hierarchy of pages (can be applied to the page itself).
*
* @author igor
*/
-@Conversational
public interface ConversationalComponent
{
http://git-wip-us.apache.org/repos/asf/wicket/blob/10326bf7/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/DetachEvent.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/DetachEvent.java b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/DetachEvent.java
index 8f59642..ac99ec3 100644
--- a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/DetachEvent.java
+++ b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/DetachEvent.java
@@ -20,6 +20,7 @@ package org.apache.wicket.cdi;
* Fired when request cycle is detached
*
* @author igor
+ *
*/
public class DetachEvent
{
http://git-wip-us.apache.org/repos/asf/wicket/blob/10326bf7/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/DetachEventEmitter.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/DetachEventEmitter.java b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/DetachEventEmitter.java
index 0259543..55065cb 100644
--- a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/DetachEventEmitter.java
+++ b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/DetachEventEmitter.java
@@ -16,9 +16,6 @@
*/
package org.apache.wicket.cdi;
-import java.io.Serializable;
-
-import javax.enterprise.context.SessionScoped;
import javax.enterprise.event.Event;
import javax.inject.Inject;
@@ -26,6 +23,7 @@ import org.apache.wicket.MetaDataKey;
import org.apache.wicket.request.IRequestHandler;
import org.apache.wicket.request.cycle.AbstractRequestCycleListener;
import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.util.lang.Args;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -33,16 +31,14 @@ import org.slf4j.LoggerFactory;
* Request cycle listener that fires the {@link DetachEvent} event
*
* @author igor
+ *
*/
-@SessionScoped
-public class DetachEventEmitter extends AbstractRequestCycleListener implements Serializable
+public class DetachEventEmitter extends AbstractRequestCycleListener
{
- private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(DetachEventEmitter.class);
private static final MetaDataKey<Boolean> DETACH_SCHEDULED_KEY = new MetaDataKey<Boolean>()
{
- private static final long serialVersionUID = 1L;
};
@Inject
@@ -53,8 +49,10 @@ public class DetachEventEmitter extends AbstractRequestCycleListener implements
*
* @param container
*/
- public DetachEventEmitter()
+ public DetachEventEmitter(CdiContainer container)
{
+ Args.notNull(container, "container");
+ container.getNonContextualManager().postConstruct(this);
}
@Override
@@ -73,7 +71,7 @@ public class DetachEventEmitter extends AbstractRequestCycleListener implements
logger.debug("Firing Detach event {}", cycle.getRequest().getUrl());
detachEvent.fire(new DetachEvent());
-
+
cycle.setMetaData(DETACH_SCHEDULED_KEY, null);
}
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/10326bf7/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ICdiAwareRequestCycleListener.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ICdiAwareRequestCycleListener.java b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ICdiAwareRequestCycleListener.java
new file mode 100644
index 0000000..d3ded47
--- /dev/null
+++ b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/ICdiAwareRequestCycleListener.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.cdi;
+
+import org.apache.wicket.request.cycle.IRequestCycleListener;
+import org.apache.wicket.request.cycle.RequestCycle;
+
+public interface ICdiAwareRequestCycleListener extends IRequestCycleListener
+{
+ /**
+ * Called right after a conversation context for this request is activated
+ *
+ * @param cycle
+ * request cycle
+ */
+ void onAfterConversationActivated(RequestCycle cycle);
+
+ /**
+ * Called right before the current conversation context is deactivated
+ *
+ * @param cycle
+ * request cycle
+ */
+ void onBeforeConversationDeactivated(RequestCycle cycle);
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/10326bf7/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/IConversationPropagation.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/IConversationPropagation.java b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/IConversationPropagation.java
index 757448d..154b077 100644
--- a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/IConversationPropagation.java
+++ b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/IConversationPropagation.java
@@ -20,36 +20,32 @@ import org.apache.wicket.Page;
import org.apache.wicket.request.IRequestHandler;
/**
- * A strategy that specifies how conversations should be propagated between
- * pages/resources. {@link ConversationPropagation} provides sensible default
- * implementations of this interface.
+ * A strategy that specifies how conversations should be propagated between pages/resources.
+ * {@link ConversationPropagation} provides sensible default implementations of this interface.
*
* @author papegaaij
*/
public interface IConversationPropagation
{
/**
- * Indicates if the conversation should be propagated via page metadata (on
- * an instance) for the given page and request handler.
+ * Indicates if the conversation should be propagated via page metadata (on an instance) for the
+ * given page and request handler.
*
* @param page
* The page on which the tag will be set.
* @param handler
* The current request handler
- * @return true if the conversation should be propagated to the given page
- * instance.
+ * @return true if the conversation should be propagated to the given page instance.
*/
public boolean propagatesViaPage(Page page, IRequestHandler handler);
/**
- * Indicates if the conversation should be propagated via url-parameters for
- * the given request handler. This can either be a get parameter in a
- * rendered url, or via page parameters.
+ * Indicates if the conversation should be propagated via url-parameters for the given request
+ * handler. This can either be a get parameter in a rendered url, or via page parameters.
*
* @param handler
* The current request handler
- * @return true if the conversation should be propagated for the given
- * request handler.
+ * @return true if the conversation should be propagated for the given request handler.
*/
public boolean propagatesViaParameters(IRequestHandler handler);
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/10326bf7/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/INonContextualManager.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/INonContextualManager.java b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/INonContextualManager.java
index 606d060..7a7c6dc 100644
--- a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/INonContextualManager.java
+++ b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/INonContextualManager.java
@@ -1,56 +1,55 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.cdi;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-
-import org.apache.wicket.Component;
-
-/**
- * Manages lifecycle of non-contextual objects like {@link Component} instances,
- * etc
- *
- * @author igor
- */
-public interface INonContextualManager
-{
- /**
- * Inject a noncontextual instance
- *
- * @param <T>
- * @param instance
- */
- <T> void inject(T instance);
-
- /**
- * Inject a noncontextual instance and invokes any {@link PostConstruct}
- * callbacks
- *
- * @param <T>
- * @param instance
- */
- <T> void postConstruct(T instance);
-
- /**
- * Invokes any {@link PreDestroy} callbacks and cleans up
- *
- * @param <T>
- * @param instance
- */
- <T> void preDestroy(T instance);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.cdi;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+import org.apache.wicket.Component;
+
+/**
+ * Manages lifecycle of non-contextual objects like {@link Component} instances, etc
+ *
+ * @author igor
+ *
+ */
+public interface INonContextualManager
+{
+ /**
+ * Inject a noncontextual instance
+ *
+ * @param <T>
+ * @param instance
+ */
+ <T> void inject(T instance);
+
+ /**
+ * Inject a noncontextual instance and invokes any {@link PostConstruct} callbacks
+ *
+ * @param <T>
+ * @param instance
+ */
+ <T> void postConstruct(T instance);
+
+ /**
+ * Invokes any {@link PreDestroy} callbacks and cleans up
+ *
+ * @param <T>
+ * @param instance
+ */
+ <T> void preDestroy(T instance);
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/10326bf7/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/NonContextual.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/NonContextual.java b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/NonContextual.java
index 4dea0ac..2af8641 100644
--- a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/NonContextual.java
+++ b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/NonContextual.java
@@ -1,154 +1,154 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.cdi;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.enterprise.context.spi.CreationalContext;
-import javax.enterprise.inject.spi.AnnotatedType;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.inject.spi.InjectionTarget;
-
-import org.apache.wicket.util.collections.ClassMetaCache;
-
-/**
- * Manages lifecycle of non-contextual (non-CDI-managed) objects
- *
- * @param <T>
- * @author igor
- */
-public class NonContextual<T>
-{
- private static final Object lock = new Object();
- private static volatile Map<BeanManager, ClassMetaCache<NonContextual<?>>> cache = Collections
- .emptyMap();
-
- final InjectionTarget<T> it;
-
- /**
- * Undeploys specified bean manager from cache
- *
- * @param beanManager
- */
- public static void undeploy()
- {
- if (cache.containsKey(BeanManagerLookup.lookup()))
- {
- synchronized (lock)
- {
- // copy-on-write the cache
- Map<BeanManager, ClassMetaCache<NonContextual<?>>> newCache = new WeakHashMap<BeanManager, ClassMetaCache<NonContextual<?>>>(
- cache);
- newCache.remove(BeanManagerLookup.lookup());
- cache = Collections.unmodifiableMap(newCache);
- }
- }
- }
-
- /**
- * Factory method for creating noncontextual instances
- *
- * @param <T>
- * @param clazz
- * @param manager
- * @return
- */
- public static <T> NonContextual<T> of(Class<? extends T> clazz)
- {
- ClassMetaCache<NonContextual<?>> meta = getCache();
-
- @SuppressWarnings("unchecked")
- NonContextual<T> nc = (NonContextual<T>)meta.get(clazz);
-
- if (nc == null)
- {
- nc = new NonContextual<T>(clazz);
- meta.put(clazz, nc);
- }
- return nc;
- }
-
- private static ClassMetaCache<NonContextual<?>> getCache()
- {
- ClassMetaCache<NonContextual<?>> meta = cache.get(BeanManagerLookup.lookup());
- if (meta == null)
- {
- synchronized (lock)
- {
- BeanManager manager = BeanManagerLookup.lookup();
- meta = cache.get(manager);
- if (meta == null)
- {
- meta = new ClassMetaCache<NonContextual<?>>();
-
- // copy-on-write the cache
- Map<BeanManager, ClassMetaCache<NonContextual<?>>> newCache = new WeakHashMap<BeanManager, ClassMetaCache<NonContextual<?>>>(
- cache);
- newCache.put(manager, meta);
- cache = Collections.unmodifiableMap(newCache);
- }
- }
- }
- return meta;
- }
-
- @SuppressWarnings("unchecked")
- private NonContextual(Class<? extends T> clazz)
- {
- BeanManager manager = BeanManagerLookup.lookup();
- AnnotatedType<? extends T> type = manager.createAnnotatedType(clazz);
- this.it = (InjectionTarget<T>)manager.createInjectionTarget(type);
- }
-
- /**
- * Injects the instance and calls any {@link PostConstruct} methods
- *
- * @param instance
- */
- public void postConstruct(T instance)
- {
- CreationalContext<T> cc = BeanManagerLookup.lookup().createCreationalContext(null);
- it.inject(instance, cc);
- it.postConstruct(instance);
- }
-
- /**
- * Injects the instance
- *
- * @param instance
- */
- public void inject(T instance)
- {
- CreationalContext<T> cc = BeanManagerLookup.lookup().createCreationalContext(null);
- it.inject(instance, cc);
- }
-
- /**
- * Calls any {@link PreDestroy} methods and destroys any injected
- * dependencies that need to be destroyed.
- *
- * @param instance
- */
- public void preDestroy(T instance)
- {
- it.preDestroy(instance);
- }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.cdi;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionTarget;
+
+import org.apache.wicket.util.collections.ClassMetaCache;
+
+/**
+ * Manages lifecycle of non-contextual (non-CDI-managed) objects
+ *
+ * @author igor
+ *
+ * @param <T>
+ */
+public class NonContextual<T>
+{
+ private static final Object lock = new Object();
+ private static volatile Map<BeanManager, ClassMetaCache<NonContextual<?>>> cache = Collections.emptyMap();
+
+ final InjectionTarget<T> it;
+ final BeanManager manager;
+
+ /**
+ * Undeploys specified bean manager from cache
+ *
+ * @param beanManager
+ */
+ public static void undeploy(BeanManager beanManager)
+ {
+ if (cache.containsKey(beanManager))
+ {
+ synchronized (lock)
+ {
+ // copy-on-write the cache
+ Map<BeanManager, ClassMetaCache<NonContextual<?>>> newCache = new WeakHashMap<BeanManager, ClassMetaCache<NonContextual<?>>>(
+ cache);
+ newCache.remove(beanManager);
+ cache = Collections.unmodifiableMap(newCache);
+ }
+ }
+ }
+
+ /**
+ * Factory method for creating noncontextual instances
+ *
+ * @param <T>
+ * @param clazz
+ * @param manager
+ * @return
+ */
+ public static <T> NonContextual<T> of(Class<? extends T> clazz, BeanManager manager)
+ {
+ ClassMetaCache<NonContextual<?>> meta = getCache(manager);
+
+ @SuppressWarnings("unchecked")
+ NonContextual<T> nc = (NonContextual<T>)meta.get(clazz);
+
+ if (nc == null)
+ {
+ nc = new NonContextual<T>(manager, clazz);
+ meta.put(clazz, nc);
+ }
+ return nc;
+ }
+
+ private static ClassMetaCache<NonContextual<?>> getCache(BeanManager manager)
+ {
+ ClassMetaCache<NonContextual<?>> meta = cache.get(manager);
+ if (meta == null)
+ {
+ synchronized (lock)
+ {
+ meta = cache.get(manager);
+ if (meta == null)
+ {
+ meta = new ClassMetaCache<NonContextual<?>>();
+
+ // copy-on-write the cache
+ Map<BeanManager, ClassMetaCache<NonContextual<?>>> newCache = new WeakHashMap<BeanManager, ClassMetaCache<NonContextual<?>>>(
+ cache);
+ newCache.put(manager, meta);
+ cache = Collections.unmodifiableMap(newCache);
+ }
+ }
+ }
+ return meta;
+ }
+
+ @SuppressWarnings("unchecked")
+ private NonContextual(BeanManager manager, Class<? extends T> clazz)
+ {
+ this.manager = manager;
+ AnnotatedType<? extends T> type = manager.createAnnotatedType(clazz);
+ this.it = (InjectionTarget<T>)manager.createInjectionTarget(type);
+ }
+
+ /**
+ * Injects the instance and calls any {@link PostConstruct} methods
+ *
+ * @param instance
+ */
+ public void postConstruct(T instance)
+ {
+ CreationalContext<T> cc = manager.createCreationalContext(null);
+ it.inject(instance, cc);
+ it.postConstruct(instance);
+ }
+
+ /**
+ * Injects the instance
+ *
+ * @param instance
+ */
+ public void inject(T instance)
+ {
+ CreationalContext<T> cc = manager.createCreationalContext(null);
+ it.inject(instance, cc);
+ }
+
+ /**
+ * Calls any {@link PreDestroy} methods and destroys any injected dependencies that need to be
+ * destroyed.
+ *
+ * @param instance
+ */
+ public void preDestroy(T instance)
+ {
+ it.preDestroy(instance);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/wicket/blob/10326bf7/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/NonContextualManager.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/NonContextualManager.java b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/NonContextualManager.java
index bd84344..a738629 100644
--- a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/NonContextualManager.java
+++ b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/NonContextualManager.java
@@ -1,74 +1,78 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.cdi;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.enterprise.context.ApplicationScoped;
-
-import org.apache.wicket.util.lang.Args;
-
-/**
- * Default implementation of {@link INonContextualManager} using
- * {@link NonContextual} helper
- *
- * @author igor
- */
-@ApplicationScoped
-class NonContextualManager implements INonContextualManager
-{
-
- /**
- * Constructor
- */
- public NonContextualManager()
- {
- }
-
- /**
- * Performs dependency injection on the noncontextual instance
- */
- @Override
- public <T> void inject(T instance)
- {
- Args.notNull(instance, "instance");
- NonContextual.of(instance.getClass()).inject(instance);
- }
-
- /**
- * Performs dependency injection on the noncontextual instance and invokes
- * any {@link PostConstruct} callbacks
- */
- @Override
- public <T> void postConstruct(T instance)
- {
- Args.notNull(instance, "instance");
- NonContextual.of(instance.getClass()).postConstruct(instance);
- }
-
- /**
- * Invokes any {@link PreDestroy} callbacks and cleans up any injected
- * dependencies
- */
- @Override
- public <T> void preDestroy(T instance)
- {
- Args.notNull(instance, "instance");
- NonContextual.of(instance.getClass()).preDestroy(instance);
- }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.cdi;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.enterprise.inject.spi.BeanManager;
+
+import org.apache.wicket.util.lang.Args;
+
+/**
+ * Default implementation of {@link INonContextualManager} using {@link NonContextual} helper
+ *
+ * @author igor
+ *
+ */
+class NonContextualManager implements INonContextualManager
+{
+ private final BeanManager beanManager;
+
+ /**
+ * Constructor
+ *
+ * @param beanManager
+ */
+ public NonContextualManager(BeanManager beanManager)
+ {
+ Args.notNull(beanManager, "beanManager");
+
+ this.beanManager = beanManager;
+ }
+
+ /**
+ * Performs dependency injection on the noncontextual instance
+ */
+ @Override
+ public <T> void inject(T instance)
+ {
+ Args.notNull(instance, "instance");
+ NonContextual.of(instance.getClass(), beanManager).inject(instance);
+ }
+
+ /**
+ * Performs dependency injection on the noncontextual instance and invokes any
+ * {@link PostConstruct} callbacks
+ */
+ @Override
+ public <T> void postConstruct(T instance)
+ {
+ Args.notNull(instance, "instance");
+ NonContextual.of(instance.getClass(), beanManager).postConstruct(instance);
+ }
+
+ /**
+ * Invokes any {@link PreDestroy} callbacks and cleans up any injected dependencies
+ */
+ @Override
+ public <T> void preDestroy(T instance)
+ {
+ Args.notNull(instance, "instance");
+ NonContextual.of(instance.getClass(), beanManager).preDestroy(instance);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/10326bf7/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/Propagation.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/Propagation.java b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/Propagation.java
deleted file mode 100644
index 446e5f3..0000000
--- a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/Propagation.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.cdi;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import javax.inject.Qualifier;
-
-/**
- * Qualifier used to inject the Propagation Method
- *
- * @author jsarman
- */
-@Qualifier
-@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD })
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Propagation {
-
-}
http://git-wip-us.apache.org/repos/asf/wicket/blob/10326bf7/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/SessionInjector.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/SessionInjector.java b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/SessionInjector.java
index 6b94111..c4c6bdc 100644
--- a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/SessionInjector.java
+++ b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/SessionInjector.java
@@ -1,37 +1,46 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.cdi;
-
-import javax.enterprise.context.ApplicationScoped;
-
-import org.apache.wicket.ISessionListener;
-import org.apache.wicket.Session;
-
-/**
- * Injects components with CDI dependencies
- *
- * @author igor
- */
-@ApplicationScoped
-class SessionInjector extends AbstractInjector<Session> implements ISessionListener
-{
- @Override
- public void onCreated(Session session)
- {
- postConstruct(session);
- }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.cdi;
+
+import org.apache.wicket.ISessionListener;
+import org.apache.wicket.Session;
+
+/**
+ * Injects components with CDI dependencies
+ *
+ * @author igor
+ *
+ */
+class SessionInjector extends AbstractInjector implements ISessionListener
+{
+ /**
+ * Constructor
+ *
+ * @param container
+ */
+ public SessionInjector(CdiContainer container)
+ {
+ super(container);
+ }
+
+ @Override
+ public void onCreated(Session session)
+ {
+ postConstruct(session);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/10326bf7/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/WicketApp.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/WicketApp.java b/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/WicketApp.java
deleted file mode 100644
index 157833c..0000000
--- a/wicket-experimental/wicket-cdi-1.1/wicket-cdi-1.1-core/src/main/java/org/apache/wicket/cdi/WicketApp.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.cdi;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import javax.enterprise.context.Dependent;
-import javax.enterprise.inject.Typed;
-import javax.inject.Qualifier;
-
-import org.apache.wicket.protocol.http.WebApplication;
-
-/**
- * Bean Qualifier for Cdi enable WebApplication. This Qualifier allows for the
- * WebApplication to be named so that the CdiApplicationFactory can select the
- * WebApplication when multiple WebApplication exist in the ClassLoader. This
- * Annotation also marks the WebApplication as Dependent. This prevents the
- * WebApplication from being proxied, which will cause failures in an EE
- * container.
- *
- * @author jsarman
- */
-@Qualifier
-@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD })
-@Retention(RUNTIME)
-@Documented
-@Dependent
-@Typed(WebApplication.class)
-public @interface WicketApp {
- String value() default "";
-}