This is an automated email from the ASF dual-hosted git repository. pedrosans pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/wicket.git
commit e31d45e062aa610c63e0989bf352ee65d3d38904 Author: Pedro Santos <[email protected]> AuthorDate: Thu Sep 3 15:23:46 2026 -0300 Normalize line terminators in org.apache.wicket.cdi to LF The package mixed both conventions, twelve files with CRLF against seven with LF. Editing a CRLF file and saving it with LF rewrote every line, so the real change ended up buried in whitespace. There is no .gitattributes and core.autocrlf is unset, but LF is the de facto convention in the tree: a 400 file sample under wicket-core/src/main/java is 349 LF to 51 CRLF. Convert the package to match it. Whitespace only, no content changes: git diff --ignore-cr-at-eol against the parent commit is empty. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> --- .../org/apache/wicket/cdi/AbstractInjector.java | 78 +-- .../apache/wicket/cdi/AutoConversationManager.java | 240 +++++----- .../org/apache/wicket/cdi/BehaviorInjector.java | 84 ++-- .../org/apache/wicket/cdi/CdiConfiguration.java | 300 ++++++------ .../org/apache/wicket/cdi/CdiShutdownCleaner.java | 78 +-- .../org/apache/wicket/cdi/ComponentInjector.java | 86 ++-- .../wicket/cdi/ConversationExpiredException.java | 104 ++-- .../wicket/cdi/ConversationExpiryChecker.java | 140 +++--- .../apache/wicket/cdi/ConversationPropagation.java | 124 ++--- .../apache/wicket/cdi/ConversationPropagator.java | 530 ++++++++++----------- .../wicket/cdi/ICdiAwareRequestCycleListener.java | 82 ++-- .../org/apache/wicket/cdi/SessionInjector.java | 84 ++-- 12 files changed, 965 insertions(+), 965 deletions(-) diff --git a/wicket-cdi/src/main/java/org/apache/wicket/cdi/AbstractInjector.java b/wicket-cdi/src/main/java/org/apache/wicket/cdi/AbstractInjector.java index cf8d67f8fc..ca8b1c04e5 100644 --- a/wicket-cdi/src/main/java/org/apache/wicket/cdi/AbstractInjector.java +++ b/wicket-cdi/src/main/java/org/apache/wicket/cdi/AbstractInjector.java @@ -1,39 +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; - -/** - * Base class for injectors - * - * @author igor - */ -class AbstractInjector -{ - public AbstractInjector() - { - } - - protected <T> void postConstruct(T instance) - { - NonContextual.of(instance).postConstruct(instance); - } - - protected <T> void inject(T instance) - { - NonContextual.of(instance).inject(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; + +/** + * Base class for injectors + * + * @author igor + */ +class AbstractInjector +{ + public AbstractInjector() + { + } + + protected <T> void postConstruct(T instance) + { + NonContextual.of(instance).postConstruct(instance); + } + + protected <T> void inject(T instance) + { + NonContextual.of(instance).inject(instance); + } +} diff --git a/wicket-cdi/src/main/java/org/apache/wicket/cdi/AutoConversationManager.java b/wicket-cdi/src/main/java/org/apache/wicket/cdi/AutoConversationManager.java index ed60208fe6..aa9377dbb7 100644 --- a/wicket-cdi/src/main/java/org/apache/wicket/cdi/AutoConversationManager.java +++ b/wicket-cdi/src/main/java/org/apache/wicket/cdi/AutoConversationManager.java @@ -1,120 +1,120 @@ -/* - * 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 jakarta.enterprise.context.Conversation; -import jakarta.inject.Inject; - -import org.apache.wicket.Component; -import org.apache.wicket.Page; -import org.apache.wicket.application.IComponentOnBeforeRenderListener; -import org.apache.wicket.request.IRequestHandler; -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; - -/** - * Automatically starts and ends conversations for pages with a - * {@link ConversationalComponent}. - * - * @author papegaaij - */ -public class AutoConversationManager implements IComponentOnBeforeRenderListener -{ - private static final Logger logger = LoggerFactory.getLogger(AutoConversationManager.class); - - @Inject - private Conversation conversation; - - @Inject - private AutoConversation autoConversation; - - private IConversationPropagation propagation; - - public AutoConversationManager(IConversationPropagation propagation) - { - NonContextual.of(AutoConversationManager.class).inject(this); - this.propagation = propagation; - } - - @Override - public void onBeforeRender(Component component) - { - if (component instanceof Page) - { - Page page = (Page)component; - IRequestHandler activeRequestHandler = page.getRequestCycle().getActiveRequestHandler(); - autoEndIfNecessary(page, activeRequestHandler); - autoBeginIfNecessary(page, activeRequestHandler); - } - } - - protected void autoBeginIfNecessary(Page page, IRequestHandler handler) - { - if (conversation == null || !conversation.isTransient() || page == null - || !hasConversationalComponent(page) || !propagation.propagatesVia(handler, 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) - { - if (conversation == null || conversation.isTransient() || page == null - || hasConversationalComponent(page) || !propagation.propagatesVia(handler, page) - || autoConversation.isAutomatic() == false) - { - return; - } - - // auto de-activate conversation - - String cid = conversation.getId(); - - autoConversation.setAutomatic(false); - conversation.end(); - ConversationPropagator.removeConversationIdFromPage(page); - - 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; - } -} +/* + * 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 jakarta.enterprise.context.Conversation; +import jakarta.inject.Inject; + +import org.apache.wicket.Component; +import org.apache.wicket.Page; +import org.apache.wicket.application.IComponentOnBeforeRenderListener; +import org.apache.wicket.request.IRequestHandler; +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; + +/** + * Automatically starts and ends conversations for pages with a + * {@link ConversationalComponent}. + * + * @author papegaaij + */ +public class AutoConversationManager implements IComponentOnBeforeRenderListener +{ + private static final Logger logger = LoggerFactory.getLogger(AutoConversationManager.class); + + @Inject + private Conversation conversation; + + @Inject + private AutoConversation autoConversation; + + private IConversationPropagation propagation; + + public AutoConversationManager(IConversationPropagation propagation) + { + NonContextual.of(AutoConversationManager.class).inject(this); + this.propagation = propagation; + } + + @Override + public void onBeforeRender(Component component) + { + if (component instanceof Page) + { + Page page = (Page)component; + IRequestHandler activeRequestHandler = page.getRequestCycle().getActiveRequestHandler(); + autoEndIfNecessary(page, activeRequestHandler); + autoBeginIfNecessary(page, activeRequestHandler); + } + } + + protected void autoBeginIfNecessary(Page page, IRequestHandler handler) + { + if (conversation == null || !conversation.isTransient() || page == null + || !hasConversationalComponent(page) || !propagation.propagatesVia(handler, 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) + { + if (conversation == null || conversation.isTransient() || page == null + || hasConversationalComponent(page) || !propagation.propagatesVia(handler, page) + || autoConversation.isAutomatic() == false) + { + return; + } + + // auto de-activate conversation + + String cid = conversation.getId(); + + autoConversation.setAutomatic(false); + conversation.end(); + ConversationPropagator.removeConversationIdFromPage(page); + + 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; + } +} diff --git a/wicket-cdi/src/main/java/org/apache/wicket/cdi/BehaviorInjector.java b/wicket-cdi/src/main/java/org/apache/wicket/cdi/BehaviorInjector.java index 15979f6135..8525540d72 100644 --- a/wicket-cdi/src/main/java/org/apache/wicket/cdi/BehaviorInjector.java +++ b/wicket-cdi/src/main/java/org/apache/wicket/cdi/BehaviorInjector.java @@ -1,42 +1,42 @@ -/* - * 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.IBehaviorInstantiationListener; -import org.apache.wicket.behavior.Behavior; - -/** - * Injects components with CDI dependencies - * - * @author igor - * - */ -public class BehaviorInjector extends AbstractInjector implements IBehaviorInstantiationListener -{ - /** - * Constructor - */ - public BehaviorInjector() - { - } - - @Override - public void onInstantiation(Behavior behavior) - { - inject(behavior); - } -} +/* + * 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.IBehaviorInstantiationListener; +import org.apache.wicket.behavior.Behavior; + +/** + * Injects components with CDI dependencies + * + * @author igor + * + */ +public class BehaviorInjector extends AbstractInjector implements IBehaviorInstantiationListener +{ + /** + * Constructor + */ + public BehaviorInjector() + { + } + + @Override + public void onInstantiation(Behavior behavior) + { + inject(behavior); + } +} diff --git a/wicket-cdi/src/main/java/org/apache/wicket/cdi/CdiConfiguration.java b/wicket-cdi/src/main/java/org/apache/wicket/cdi/CdiConfiguration.java index 692e83d015..7d10149d8c 100644 --- a/wicket-cdi/src/main/java/org/apache/wicket/cdi/CdiConfiguration.java +++ b/wicket-cdi/src/main/java/org/apache/wicket/cdi/CdiConfiguration.java @@ -1,150 +1,150 @@ -/* - * 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 jakarta.enterprise.inject.spi.BeanManager; - -import org.apache.wicket.Application; -import org.apache.wicket.MetaDataKey; -import org.apache.wicket.request.cycle.RequestCycleListenerCollection; - -/** - * Configures CDI integration - * - * @author igor - * - */ -public class CdiConfiguration -{ - private static final MetaDataKey<CdiConfiguration> CDI_CONFIGURATION_KEY = new MetaDataKey<>() - { - private static final long serialVersionUID = 1L; - }; - - private IConversationPropagation propagation = ConversationPropagation.NONBOOKMARKABLE; - - private BeanManager beanManager; - - private BeanManager fallbackBeanManager; - - /** - * Constructor - */ - public CdiConfiguration() - { - } - - public IConversationPropagation getPropagation() - { - return propagation; - } - - public CdiConfiguration setPropagation(IConversationPropagation propagation) - { - this.propagation = propagation; - return this; - } - - public BeanManager getBeanManager() - { - return beanManager; - } - - /** - * Sets a BeanManager that should be used at first. - * - * @param beanManager - * @return this instance - */ - public CdiConfiguration setBeanManager(BeanManager beanManager) - { - - if (Application.exists() && CdiConfiguration.get(Application.get()) != null) - throw new IllegalStateException( - "A CdiConfiguration is already set for the application."); - - this.beanManager = beanManager; - return this; - } - - public BeanManager getFallbackBeanManager() - { - return fallbackBeanManager; - } - - /** - * Sets a BeanManager that should be used if all strategies to lookup a - * BeanManager fail. This can be used in scenarios where you do not have - * JNDI available and do not want to bootstrap the CDI provider. It should - * be noted that the fallback BeanManager can only be used within the - * context of a Wicket application (ie. Application.get() should return the - * application that was configured with this CdiConfiguration). - * - * @param fallbackBeanManager - * @return this instance - */ - public CdiConfiguration setFallbackBeanManager(BeanManager fallbackBeanManager) - { - this.fallbackBeanManager = fallbackBeanManager; - return this; - } - - /** - * Configures the specified application - * - * @param application - */ - public void configure(Application application) - { - if (application.getMetaData(CDI_CONFIGURATION_KEY) != null) - { - throw new IllegalStateException("Cdi already configured for this application"); - } - application.setMetaData(CDI_CONFIGURATION_KEY, this); - - RequestCycleListenerCollection listeners = new RequestCycleListenerCollection(); - application.getRequestCycleListeners().add(listeners); - - // enable conversation propagation - if (getPropagation() != ConversationPropagation.NONE) - { - listeners.add(new ConversationPropagator(application, getPropagation())); - application.getComponentPreOnBeforeRenderListeners().add( - new AutoConversationManager(getPropagation())); - application.getComponentPreOnBeforeRenderListeners().add( - new ConversationExpiryChecker()); - } - - // enable detach event - listeners.add(new DetachEventEmitter()); - - NonContextual.of(application).postConstruct(application); - - // enable injection of various framework components - application.getSessionListeners().add(new SessionInjector()); - application.getComponentInstantiationListeners().add(new ComponentInjector()); - application.getBehaviorInstantiationListeners().add(new BehaviorInjector()); - - // enable cleanup - application.getApplicationListeners().add(new CdiShutdownCleaner()); - } - - public static CdiConfiguration get(Application application) - { - return application.getMetaData(CDI_CONFIGURATION_KEY); - } -} +/* + * 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 jakarta.enterprise.inject.spi.BeanManager; + +import org.apache.wicket.Application; +import org.apache.wicket.MetaDataKey; +import org.apache.wicket.request.cycle.RequestCycleListenerCollection; + +/** + * Configures CDI integration + * + * @author igor + * + */ +public class CdiConfiguration +{ + private static final MetaDataKey<CdiConfiguration> CDI_CONFIGURATION_KEY = new MetaDataKey<>() + { + private static final long serialVersionUID = 1L; + }; + + private IConversationPropagation propagation = ConversationPropagation.NONBOOKMARKABLE; + + private BeanManager beanManager; + + private BeanManager fallbackBeanManager; + + /** + * Constructor + */ + public CdiConfiguration() + { + } + + public IConversationPropagation getPropagation() + { + return propagation; + } + + public CdiConfiguration setPropagation(IConversationPropagation propagation) + { + this.propagation = propagation; + return this; + } + + public BeanManager getBeanManager() + { + return beanManager; + } + + /** + * Sets a BeanManager that should be used at first. + * + * @param beanManager + * @return this instance + */ + public CdiConfiguration setBeanManager(BeanManager beanManager) + { + + if (Application.exists() && CdiConfiguration.get(Application.get()) != null) + throw new IllegalStateException( + "A CdiConfiguration is already set for the application."); + + this.beanManager = beanManager; + return this; + } + + public BeanManager getFallbackBeanManager() + { + return fallbackBeanManager; + } + + /** + * Sets a BeanManager that should be used if all strategies to lookup a + * BeanManager fail. This can be used in scenarios where you do not have + * JNDI available and do not want to bootstrap the CDI provider. It should + * be noted that the fallback BeanManager can only be used within the + * context of a Wicket application (ie. Application.get() should return the + * application that was configured with this CdiConfiguration). + * + * @param fallbackBeanManager + * @return this instance + */ + public CdiConfiguration setFallbackBeanManager(BeanManager fallbackBeanManager) + { + this.fallbackBeanManager = fallbackBeanManager; + return this; + } + + /** + * Configures the specified application + * + * @param application + */ + public void configure(Application application) + { + if (application.getMetaData(CDI_CONFIGURATION_KEY) != null) + { + throw new IllegalStateException("Cdi already configured for this application"); + } + application.setMetaData(CDI_CONFIGURATION_KEY, this); + + RequestCycleListenerCollection listeners = new RequestCycleListenerCollection(); + application.getRequestCycleListeners().add(listeners); + + // enable conversation propagation + if (getPropagation() != ConversationPropagation.NONE) + { + listeners.add(new ConversationPropagator(application, getPropagation())); + application.getComponentPreOnBeforeRenderListeners().add( + new AutoConversationManager(getPropagation())); + application.getComponentPreOnBeforeRenderListeners().add( + new ConversationExpiryChecker()); + } + + // enable detach event + listeners.add(new DetachEventEmitter()); + + NonContextual.of(application).postConstruct(application); + + // enable injection of various framework components + application.getSessionListeners().add(new SessionInjector()); + application.getComponentInstantiationListeners().add(new ComponentInjector()); + application.getBehaviorInstantiationListeners().add(new BehaviorInjector()); + + // enable cleanup + application.getApplicationListeners().add(new CdiShutdownCleaner()); + } + + public static CdiConfiguration get(Application application) + { + return application.getMetaData(CDI_CONFIGURATION_KEY); + } +} diff --git a/wicket-cdi/src/main/java/org/apache/wicket/cdi/CdiShutdownCleaner.java b/wicket-cdi/src/main/java/org/apache/wicket/cdi/CdiShutdownCleaner.java index 25c29dd59b..4a5b6c8611 100644 --- a/wicket-cdi/src/main/java/org/apache/wicket/cdi/CdiShutdownCleaner.java +++ b/wicket-cdi/src/main/java/org/apache/wicket/cdi/CdiShutdownCleaner.java @@ -1,39 +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.Application; -import org.apache.wicket.IApplicationListener; - -/** - * Listens to application shutdown and cleans up - * - * @author igor - */ -class CdiShutdownCleaner implements IApplicationListener -{ - public CdiShutdownCleaner() - { - } - - @Override - public void onBeforeDestroyed(Application application) - { - NonContextual.of(application).preDestroy(application); - NonContextual.undeploy(); - } -} +/* + * 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.Application; +import org.apache.wicket.IApplicationListener; + +/** + * Listens to application shutdown and cleans up + * + * @author igor + */ +class CdiShutdownCleaner implements IApplicationListener +{ + public CdiShutdownCleaner() + { + } + + @Override + public void onBeforeDestroyed(Application application) + { + NonContextual.of(application).preDestroy(application); + NonContextual.undeploy(); + } +} diff --git a/wicket-cdi/src/main/java/org/apache/wicket/cdi/ComponentInjector.java b/wicket-cdi/src/main/java/org/apache/wicket/cdi/ComponentInjector.java index 65a4879b9a..e4461a5f61 100644 --- a/wicket-cdi/src/main/java/org/apache/wicket/cdi/ComponentInjector.java +++ b/wicket-cdi/src/main/java/org/apache/wicket/cdi/ComponentInjector.java @@ -1,43 +1,43 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.wicket.cdi; - -import org.apache.wicket.Component; -import org.apache.wicket.application.IComponentInstantiationListener; - -/** - * Injects components with CDI dependencies - * - * @author igor - * - */ -class ComponentInjector extends AbstractInjector implements IComponentInstantiationListener -{ - /** - * Constructor - */ - public ComponentInjector() - { - } - - @Override - public void onInstantiation(Component component) - { - inject(component); - } - -} +/* + * 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.Component; +import org.apache.wicket.application.IComponentInstantiationListener; + +/** + * Injects components with CDI dependencies + * + * @author igor + * + */ +class ComponentInjector extends AbstractInjector implements IComponentInstantiationListener +{ + /** + * Constructor + */ + public ComponentInjector() + { + } + + @Override + public void onInstantiation(Component component) + { + inject(component); + } + +} diff --git a/wicket-cdi/src/main/java/org/apache/wicket/cdi/ConversationExpiredException.java b/wicket-cdi/src/main/java/org/apache/wicket/cdi/ConversationExpiredException.java index 16df7b1da6..8d6c61fc2d 100644 --- a/wicket-cdi/src/main/java/org/apache/wicket/cdi/ConversationExpiredException.java +++ b/wicket-cdi/src/main/java/org/apache/wicket/cdi/ConversationExpiredException.java @@ -1,52 +1,52 @@ -/* - * 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; - -public class ConversationExpiredException extends RuntimeException -{ - private static final long serialVersionUID = 1L; - private String cid; - private Page page; - private IRequestHandler handler; - - public ConversationExpiredException(Throwable cause, String cid, Page page, - IRequestHandler handler) - { - super(cause); - this.cid = cid; - this.page = page; - this.handler = handler; - } - - public String getCid() - { - return cid; - } - - public Page getPage() - { - return page; - } - - public IRequestHandler getHandler() - { - return handler; - } -} +/* + * 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; + +public class ConversationExpiredException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + private String cid; + private Page page; + private IRequestHandler handler; + + public ConversationExpiredException(Throwable cause, String cid, Page page, + IRequestHandler handler) + { + super(cause); + this.cid = cid; + this.page = page; + this.handler = handler; + } + + public String getCid() + { + return cid; + } + + public Page getPage() + { + return page; + } + + public IRequestHandler getHandler() + { + return handler; + } +} diff --git a/wicket-cdi/src/main/java/org/apache/wicket/cdi/ConversationExpiryChecker.java b/wicket-cdi/src/main/java/org/apache/wicket/cdi/ConversationExpiryChecker.java index cd55227672..d1a49d81c9 100644 --- a/wicket-cdi/src/main/java/org/apache/wicket/cdi/ConversationExpiryChecker.java +++ b/wicket-cdi/src/main/java/org/apache/wicket/cdi/ConversationExpiryChecker.java @@ -1,70 +1,70 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.wicket.cdi; - -import jakarta.enterprise.context.Conversation; -import jakarta.inject.Inject; - -import org.apache.wicket.Component; -import org.apache.wicket.Page; -import org.apache.wicket.application.IComponentOnBeforeRenderListener; -import org.apache.wicket.core.request.handler.IPartialPageRequestHandler; -import org.apache.wicket.request.cycle.RequestCycle; -import org.apache.wicket.util.lang.Objects; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Checks for conversation expiration during page render and throws a - * {@link ConversationExpiredException} when an expired conversation is - * detected. - * - * For example a link that calls {@link Conversation#end()} but does not - * redirect to a non-conversation-dependent page will be caught by this - * listener. - * - * @author igor - * - */ -public class ConversationExpiryChecker implements IComponentOnBeforeRenderListener -{ - private static final Logger logger = LoggerFactory.getLogger(ConversationExpiryChecker.class); - - @Inject - private Conversation conversation; - - public ConversationExpiryChecker() - { - NonContextual.of(ConversationExpiryChecker.class).inject(this); - } - - @Override - public void onBeforeRender(Component component) - { - if (component instanceof Page || RequestCycle.get().find(IPartialPageRequestHandler.class).isPresent()) - { - Page page = component.getPage(); - String cid = ConversationPropagator.getConversationIdFromPage(page); - if (cid != null && !Objects.isEqual(conversation.getId(), cid)) - { - logger.info("Conversation {} has expired for {}", cid, page); - throw new ConversationExpiredException(null, cid, page, RequestCycle.get() - .getActiveRequestHandler()); - } - } - } -} +/* + * 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 jakarta.enterprise.context.Conversation; +import jakarta.inject.Inject; + +import org.apache.wicket.Component; +import org.apache.wicket.Page; +import org.apache.wicket.application.IComponentOnBeforeRenderListener; +import org.apache.wicket.core.request.handler.IPartialPageRequestHandler; +import org.apache.wicket.request.cycle.RequestCycle; +import org.apache.wicket.util.lang.Objects; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Checks for conversation expiration during page render and throws a + * {@link ConversationExpiredException} when an expired conversation is + * detected. + * + * For example a link that calls {@link Conversation#end()} but does not + * redirect to a non-conversation-dependent page will be caught by this + * listener. + * + * @author igor + * + */ +public class ConversationExpiryChecker implements IComponentOnBeforeRenderListener +{ + private static final Logger logger = LoggerFactory.getLogger(ConversationExpiryChecker.class); + + @Inject + private Conversation conversation; + + public ConversationExpiryChecker() + { + NonContextual.of(ConversationExpiryChecker.class).inject(this); + } + + @Override + public void onBeforeRender(Component component) + { + if (component instanceof Page || RequestCycle.get().find(IPartialPageRequestHandler.class).isPresent()) + { + Page page = component.getPage(); + String cid = ConversationPropagator.getConversationIdFromPage(page); + if (cid != null && !Objects.isEqual(conversation.getId(), cid)) + { + logger.info("Conversation {} has expired for {}", cid, page); + throw new ConversationExpiredException(null, cid, page, RequestCycle.get() + .getActiveRequestHandler()); + } + } + } +} diff --git a/wicket-cdi/src/main/java/org/apache/wicket/cdi/ConversationPropagation.java b/wicket-cdi/src/main/java/org/apache/wicket/cdi/ConversationPropagation.java index a5fe19f435..f77a1c5c54 100644 --- a/wicket-cdi/src/main/java/org/apache/wicket/cdi/ConversationPropagation.java +++ b/wicket-cdi/src/main/java/org/apache/wicket/cdi/ConversationPropagation.java @@ -1,62 +1,62 @@ -/* - * 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 jakarta.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 propagatesVia(IRequestHandler handler, Page page) - { - return false; - } - }, - /** - * Pesistent conversations are propagated between non-bookmarkable pages - * only - */ - NONBOOKMARKABLE { - @Override - public boolean propagatesVia(IRequestHandler handler, Page page) - { - return page != null; - } - }, - /** - * Persistent conversations are propagated between bookmarkable and - * non-bookmarkable pages - */ - ALL { - @Override - public boolean propagatesVia(IRequestHandler handler, Page page) - { - 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 jakarta.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 propagatesVia(IRequestHandler handler, Page page) + { + return false; + } + }, + /** + * Pesistent conversations are propagated between non-bookmarkable pages + * only + */ + NONBOOKMARKABLE { + @Override + public boolean propagatesVia(IRequestHandler handler, Page page) + { + return page != null; + } + }, + /** + * Persistent conversations are propagated between bookmarkable and + * non-bookmarkable pages + */ + ALL { + @Override + public boolean propagatesVia(IRequestHandler handler, Page page) + { + return true; + } + }; +} diff --git a/wicket-cdi/src/main/java/org/apache/wicket/cdi/ConversationPropagator.java b/wicket-cdi/src/main/java/org/apache/wicket/cdi/ConversationPropagator.java index b28c6b5f78..c0089e71e1 100644 --- a/wicket-cdi/src/main/java/org/apache/wicket/cdi/ConversationPropagator.java +++ b/wicket-cdi/src/main/java/org/apache/wicket/cdi/ConversationPropagator.java @@ -1,265 +1,265 @@ -/* - * 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 jakarta.enterprise.context.ContextNotActiveException; -import jakarta.enterprise.context.Conversation; -import jakarta.enterprise.context.ConversationScoped; -import jakarta.inject.Inject; - -import org.apache.wicket.Application; -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.request.IRequestHandler; -import org.apache.wicket.request.Url; -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.Classes; -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 implements IRequestCycleListener -{ - private static final Logger logger = LoggerFactory.getLogger(ConversationPropagator.class); - - private static final MetaDataKey<Boolean> CONVERSATION_STARTED_KEY = new MetaDataKey<>() - { - private static final long serialVersionUID = 1L; - }; - - private static final MetaDataKey<String> CONVERSATION_ID_KEY = new MetaDataKey<>() - { - private static final long serialVersionUID = 1L; - }; - - public static final String CID = "cid"; - - /** propagation mode to use */ - private final IConversationPropagation propagation; - - private final Application application; - - @Inject - private Conversation conversation; - - /** - * Constructor - * - * @param application - * @param propagation - */ - public ConversationPropagator(Application application, IConversationPropagation propagation) - { - Args.notNull(application, "application"); - 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.propagation = propagation; - - NonContextual.of(ConversationPropagator.class).postConstruct(this); - } - - public IConversationPropagation getPropagation() - { - return propagation; - } - - @Override - public void onRequestHandlerResolved(RequestCycle cycle, IRequestHandler handler) - { - if (activateForHandler(handler)) - { - logger.debug("Activating conversation {}", conversation.getId()); - fireOnAfterConversationStarted(cycle); - } - } - - private void fireOnAfterConversationStarted(RequestCycle cycle) - { - cycle.setMetaData(CONVERSATION_STARTED_KEY, true); - for (IRequestCycleListener listener : application.getRequestCycleListeners()) - { - if (listener instanceof ICdiAwareRequestCycleListener) - { - ((ICdiAwareRequestCycleListener)listener).onAfterConversationActivated(cycle); - } - } - } - - @Override - public void onRequestHandlerExecuted(RequestCycle cycle, IRequestHandler handler) - { - // propagate current non-transient conversation to the newly scheduled - // page - try - { - if (conversation.isTransient()) - { - return; - } - } catch (ContextNotActiveException cnax) - { - logger.debug("There is no active context for the requested scope!", cnax); - return; - } - - if (propagation.propagatesVia(handler, IPageRequestHandler.getPage(handler))) - { - 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()); - markPageWithConversationId(handler, 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; - } - } - - if (conversation.isTransient()) - { - return; - } - - if (propagation.propagatesVia(handler, IPageRequestHandler.getPage(handler))) - { - logger.debug("Propagating non-transient conversation {} via url", conversation.getId()); - url.setQueryParameter(CID, conversation.getId()); - markPageWithConversationId(handler, conversation.getId()); - } - } - - @Override - public void onDetach(RequestCycle cycle) - { - if (!Boolean.TRUE.equals(cycle.getMetaData(CONVERSATION_STARTED_KEY))) - { - return; - } - - logger.debug("Deactivating conversation {}", conversation.getId()); - for (IRequestCycleListener listener : application.getRequestCycleListeners()) - { - if (listener instanceof ICdiAwareRequestCycleListener) - { - ((ICdiAwareRequestCycleListener)listener).onBeforeConversationDeactivated(cycle); - } - } - } - - /** - * 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) - { - String handlerClassName = Classes.name(handler.getClass()); - - if (handler instanceof BufferedResponseRequestHandler) - { - // we do not care about pages that are being rendered from a buffer - return false; - } else if ("org.apache.wicket.protocol.ws.api.WebSocketMessageBroadcastHandler".equals(handlerClassName)) - { - return false; - } else if ("org.apache.wicket.protocol.ws.api.WebSocketRequestHandler".equals(handlerClassName)) { - // injection is not supported in web sockets communication - return false; - } - } - return true; - } - - public static void markPageWithConversationId(IRequestHandler handler, String cid) - { - Page page = IPageRequestHandler.getPage(handler); - if (page != null) - { - page.setMetaData(CONVERSATION_ID_KEY, cid); - } - } - - public static String getConversationIdFromPage(Page page) - { - return page.getMetaData(CONVERSATION_ID_KEY); - } - - public static void removeConversationIdFromPage(Page page) - { - page.setMetaData(CONVERSATION_ID_KEY, 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; - } -} +/* + * 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 jakarta.enterprise.context.ContextNotActiveException; +import jakarta.enterprise.context.Conversation; +import jakarta.enterprise.context.ConversationScoped; +import jakarta.inject.Inject; + +import org.apache.wicket.Application; +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.request.IRequestHandler; +import org.apache.wicket.request.Url; +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.Classes; +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 implements IRequestCycleListener +{ + private static final Logger logger = LoggerFactory.getLogger(ConversationPropagator.class); + + private static final MetaDataKey<Boolean> CONVERSATION_STARTED_KEY = new MetaDataKey<>() + { + private static final long serialVersionUID = 1L; + }; + + private static final MetaDataKey<String> CONVERSATION_ID_KEY = new MetaDataKey<>() + { + private static final long serialVersionUID = 1L; + }; + + public static final String CID = "cid"; + + /** propagation mode to use */ + private final IConversationPropagation propagation; + + private final Application application; + + @Inject + private Conversation conversation; + + /** + * Constructor + * + * @param application + * @param propagation + */ + public ConversationPropagator(Application application, IConversationPropagation propagation) + { + Args.notNull(application, "application"); + 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.propagation = propagation; + + NonContextual.of(ConversationPropagator.class).postConstruct(this); + } + + public IConversationPropagation getPropagation() + { + return propagation; + } + + @Override + public void onRequestHandlerResolved(RequestCycle cycle, IRequestHandler handler) + { + if (activateForHandler(handler)) + { + logger.debug("Activating conversation {}", conversation.getId()); + fireOnAfterConversationStarted(cycle); + } + } + + private void fireOnAfterConversationStarted(RequestCycle cycle) + { + cycle.setMetaData(CONVERSATION_STARTED_KEY, true); + for (IRequestCycleListener listener : application.getRequestCycleListeners()) + { + if (listener instanceof ICdiAwareRequestCycleListener) + { + ((ICdiAwareRequestCycleListener)listener).onAfterConversationActivated(cycle); + } + } + } + + @Override + public void onRequestHandlerExecuted(RequestCycle cycle, IRequestHandler handler) + { + // propagate current non-transient conversation to the newly scheduled + // page + try + { + if (conversation.isTransient()) + { + return; + } + } catch (ContextNotActiveException cnax) + { + logger.debug("There is no active context for the requested scope!", cnax); + return; + } + + if (propagation.propagatesVia(handler, IPageRequestHandler.getPage(handler))) + { + 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()); + markPageWithConversationId(handler, 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; + } + } + + if (conversation.isTransient()) + { + return; + } + + if (propagation.propagatesVia(handler, IPageRequestHandler.getPage(handler))) + { + logger.debug("Propagating non-transient conversation {} via url", conversation.getId()); + url.setQueryParameter(CID, conversation.getId()); + markPageWithConversationId(handler, conversation.getId()); + } + } + + @Override + public void onDetach(RequestCycle cycle) + { + if (!Boolean.TRUE.equals(cycle.getMetaData(CONVERSATION_STARTED_KEY))) + { + return; + } + + logger.debug("Deactivating conversation {}", conversation.getId()); + for (IRequestCycleListener listener : application.getRequestCycleListeners()) + { + if (listener instanceof ICdiAwareRequestCycleListener) + { + ((ICdiAwareRequestCycleListener)listener).onBeforeConversationDeactivated(cycle); + } + } + } + + /** + * 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) + { + String handlerClassName = Classes.name(handler.getClass()); + + if (handler instanceof BufferedResponseRequestHandler) + { + // we do not care about pages that are being rendered from a buffer + return false; + } else if ("org.apache.wicket.protocol.ws.api.WebSocketMessageBroadcastHandler".equals(handlerClassName)) + { + return false; + } else if ("org.apache.wicket.protocol.ws.api.WebSocketRequestHandler".equals(handlerClassName)) { + // injection is not supported in web sockets communication + return false; + } + } + return true; + } + + public static void markPageWithConversationId(IRequestHandler handler, String cid) + { + Page page = IPageRequestHandler.getPage(handler); + if (page != null) + { + page.setMetaData(CONVERSATION_ID_KEY, cid); + } + } + + public static String getConversationIdFromPage(Page page) + { + return page.getMetaData(CONVERSATION_ID_KEY); + } + + public static void removeConversationIdFromPage(Page page) + { + page.setMetaData(CONVERSATION_ID_KEY, 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; + } +} diff --git a/wicket-cdi/src/main/java/org/apache/wicket/cdi/ICdiAwareRequestCycleListener.java b/wicket-cdi/src/main/java/org/apache/wicket/cdi/ICdiAwareRequestCycleListener.java index a57795405b..fb7c61ec2f 100644 --- a/wicket-cdi/src/main/java/org/apache/wicket/cdi/ICdiAwareRequestCycleListener.java +++ b/wicket-cdi/src/main/java/org/apache/wicket/cdi/ICdiAwareRequestCycleListener.java @@ -1,41 +1,41 @@ -/* - * 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 - */ - default void onAfterConversationActivated(RequestCycle cycle) - {} - - /** - * Called right before the current conversation context is deactivated - * - * @param cycle - * request cycle - */ - default void onBeforeConversationDeactivated(RequestCycle cycle) - {} -} +/* + * 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 + */ + default void onAfterConversationActivated(RequestCycle cycle) + {} + + /** + * Called right before the current conversation context is deactivated + * + * @param cycle + * request cycle + */ + default void onBeforeConversationDeactivated(RequestCycle cycle) + {} +} diff --git a/wicket-cdi/src/main/java/org/apache/wicket/cdi/SessionInjector.java b/wicket-cdi/src/main/java/org/apache/wicket/cdi/SessionInjector.java index a6fb4d263d..3dedf56f33 100644 --- a/wicket-cdi/src/main/java/org/apache/wicket/cdi/SessionInjector.java +++ b/wicket-cdi/src/main/java/org/apache/wicket/cdi/SessionInjector.java @@ -1,42 +1,42 @@ -/* - * 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 - */ - public SessionInjector() - { - } - - @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 + */ + public SessionInjector() + { + } + + @Override + public void onCreated(Session session) + { + postConstruct(session); + } +}
