http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/WebRequestCycleForIsis.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/WebRequestCycleForIsis.java b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/WebRequestCycleForIsis.java new file mode 100644 index 0000000..e4cfa30 --- /dev/null +++ b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/WebRequestCycleForIsis.java @@ -0,0 +1,232 @@ +/* + * 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.isis.viewer.wicket.viewer.integration.wicket; + +import java.util.List; + +import com.google.common.base.Function; +import com.google.common.collect.Lists; + +import org.apache.wicket.RestartResponseException; +import org.apache.wicket.Session; +import org.apache.wicket.authroles.authentication.AuthenticatedWebSession; +import org.apache.wicket.core.request.handler.PageProvider; +import org.apache.wicket.core.request.handler.RenderPageRequestHandler; +import org.apache.wicket.core.request.handler.RenderPageRequestHandler.RedirectPolicy; +import org.apache.wicket.model.Model; +import org.apache.wicket.protocol.http.PageExpiredException; +import org.apache.wicket.request.IRequestHandler; +import org.apache.wicket.request.component.IRequestablePage; +import org.apache.wicket.request.cycle.AbstractRequestCycleListener; +import org.apache.wicket.request.cycle.RequestCycle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer; +import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerComposite; +import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerForType; +import org.apache.isis.core.commons.authentication.AuthenticationSession; +import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector; +import org.apache.isis.core.runtime.system.context.IsisContext; +import org.apache.isis.core.runtime.system.session.IsisSession; +import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager; +import org.apache.isis.viewer.wicket.ui.errors.ExceptionModel; +import org.apache.isis.viewer.wicket.ui.pages.error.ErrorPage; +import org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage; +import org.apache.isis.viewer.wicket.ui.pages.mmverror.MmvErrorPage; +import org.apache.isis.viewer.wicket.viewer.IsisWicketApplication; + +/** + * Isis-specific implementation of the Wicket's {@link RequestCycle}, + * automatically opening a {@link IsisSession} at the beginning of the request + * and committing the transaction and closing the session at the end. + */ +public class WebRequestCycleForIsis extends AbstractRequestCycleListener { + + private static final Logger LOG = LoggerFactory.getLogger(WebRequestCycleForIsis.class); + + @Override + public synchronized void onBeginRequest(RequestCycle requestCycle) { + + if (!Session.exists()) { + return; + } + final AuthenticatedWebSessionForIsis wicketSession = AuthenticatedWebSessionForIsis.get(); + final AuthenticationSession authenticationSession = wicketSession.getAuthenticationSession(); + if (authenticationSession == null) { + return; + } + + getIsisContext().openSessionInstance(authenticationSession); + getTransactionManager().startTransaction(); + } + + + /** + * Is called prior to {@link #onEndRequest(RequestCycle)}, and offers the opportunity to + * throw an exception. + */ + @Override + public void onRequestHandlerExecuted(RequestCycle cycle, IRequestHandler handler) { + if(LOG.isDebugEnabled()) { + LOG.debug("onRequestHandlerExecuted: handler: " + handler); + } + + final IsisSession session = getIsisContext().getSessionInstance(); + if (session != null) { + try { + // will commit (or abort) the transaction; + // an abort will cause the exception to be thrown. + getTransactionManager().endTransaction(); + } catch(Exception ex) { + // will redirect to error page after this, + // so make sure there is a new transaction ready to go. + if(getTransactionManager().getTransaction().getState().isComplete()) { + getTransactionManager().startTransaction(); + } + if(handler instanceof RenderPageRequestHandler) { + RenderPageRequestHandler requestHandler = (RenderPageRequestHandler) handler; + if(requestHandler.getPage() instanceof ErrorPage) { + // do nothing + return; + } + } + + // shouldn't return null given that we're in a session ... + PageProvider errorPageProvider = errorPageProviderFor(ex); + throw new RestartResponseException(errorPageProvider, RedirectPolicy.ALWAYS_REDIRECT); + } + } + } + + /** + * It is not possible to throw exceptions here, hence use of {@link #onRequestHandlerExecuted(RequestCycle, IRequestHandler)}. + */ + @Override + public synchronized void onEndRequest(RequestCycle cycle) { + final IsisSession session = getIsisContext().getSessionInstance(); + if (session != null) { + try { + // belt and braces + getTransactionManager().endTransaction(); + } finally { + getIsisContext().closeSessionInstance(); + } + } + } + + + @Override + public IRequestHandler onException(RequestCycle cycle, Exception ex) { + PageProvider errorPageProvider = errorPageProviderFor(ex); + // avoid infinite redirect loops + RedirectPolicy redirectPolicy = ex instanceof PageExpiredException? RedirectPolicy.NEVER_REDIRECT: RedirectPolicy.ALWAYS_REDIRECT; + return errorPageProvider != null + ? new RenderPageRequestHandler(errorPageProvider, redirectPolicy) + : null; + } + + protected PageProvider errorPageProviderFor(Exception ex) { + IRequestablePage errorPage = errorPageFor(ex); + return errorPage != null? new PageProvider(errorPage): null; + } + + // special case handling for PageExpiredException, otherwise infinite loop + private final static ExceptionRecognizerForType pageExpiredExceptionRecognizer = + new ExceptionRecognizerForType(PageExpiredException.class, new Function<String,String>(){ + @Override + public String apply(String input) { + return "Requested page is no longer available. Please navigate back to the home page or select an object from the bookmark bar."; + } + }); + + protected IRequestablePage errorPageFor(Exception ex) { + List<ExceptionRecognizer> exceptionRecognizers = Lists.newArrayList(); + exceptionRecognizers.add(pageExpiredExceptionRecognizer); + + if(inIsisSession()) { + exceptionRecognizers.addAll(getServicesInjector().lookupServices(ExceptionRecognizer.class)); + } else { + List<String> validationErrors = IsisWicketApplication.get().getValidationErrors(); + if(!validationErrors.isEmpty()) { + return new MmvErrorPage(Model.ofList(validationErrors)); + } + // not sure whether this can ever happen now... + LOG.warn("Unable to obtain exceptionRecognizers (no session), will be treated as unrecognized exception"); + } + String recognizedMessageIfAny = new ExceptionRecognizerComposite(exceptionRecognizers).recognize(ex); + ExceptionModel exceptionModel = ExceptionModel.create(recognizedMessageIfAny, ex); + + return isSignedIn() ? new ErrorPage(exceptionModel) : new WicketSignInPage(null, exceptionModel); + } + + /** + * TODO: this is very hacky... + * + * <p> + * Matters should improve once ISIS-299 gets implemented... + */ + protected boolean isSignedIn() { + if(!inIsisSession()) { + return false; + } + if(getAuthenticationSession() == null) { + return false; + } + return getWicketAuthenticationSession().isSignedIn(); + } + + + + + /////////////////////////////////////////////////////////////// + // Dependencies (from isis' context) + /////////////////////////////////////////////////////////////// + + protected ServicesInjector getServicesInjector() { + return IsisContext.getPersistenceSession().getServicesInjector(); + } + + protected IsisContext getIsisContext() { + return IsisContext.getInstance(); + } + + protected IsisTransactionManager getTransactionManager() { + return IsisContext.getTransactionManager(); + } + + protected boolean inIsisSession() { + return IsisContext.inSession(); + } + + protected AuthenticationSession getAuthenticationSession() { + return IsisContext.getAuthenticationSession(); + } + + /////////////////////////////////////////////////////////////// + // Dependencies (from wicket) + /////////////////////////////////////////////////////////////// + + + protected AuthenticatedWebSession getWicketAuthenticationSession() { + return AuthenticatedWebSession.get(); + } + +}
http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java new file mode 100644 index 0000000..479b474 --- /dev/null +++ b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java @@ -0,0 +1,267 @@ +/* + * 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.isis.viewer.wicket.viewer.registries.components; + +import java.util.ServiceLoader; +import com.google.inject.Singleton; +import org.apache.isis.viewer.wicket.ui.ComponentFactory; +import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistrar; +import org.apache.isis.viewer.wicket.ui.components.about.AboutPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.actionlink.ActionLinkPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.actionmenu.serviceactions.TertiaryMenuPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.actions.ActionInfoPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.actions.ActionPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.actions.ActionParametersFormPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.actionmenu.serviceactions.ServiceActionsPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.bookmarkedpages.BookmarkedPagesPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.collection.CollectionPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable.CollectionContentsAsAjaxTablePanelFactory; +import org.apache.isis.viewer.wicket.ui.components.collectioncontents.multiple.CollectionContentsMultipleViewsPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.collectioncontents.summary.CollectionContentsAsSummaryFactory; +import org.apache.isis.viewer.wicket.ui.components.collectioncontents.unresolved.CollectionContentsAsUnresolvedPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.empty.EmptyCollectionPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.entity.collections.EntityCollectionsPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.entity.combined.EntityCombinedPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.entity.header.EntityHeaderPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.entity.icontitle.EntityIconAndTitlePanelFactory; +import org.apache.isis.viewer.wicket.ui.components.entity.icontitle.EntityIconTitleAndCopyLinkPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.entity.properties.EntityPropertiesPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.entity.selector.links.EntityLinksSelectorPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.footer.FooterPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.header.HeaderPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.*; +import org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates.JavaSqlDatePanelFactory; +import org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates.JavaSqlTimePanelFactory; +import org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates.JavaSqlTimestampPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates.JavaUtilDatePanelFactory; +import org.apache.isis.viewer.wicket.ui.components.scalars.jdkmath.JavaMathBigDecimalPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.scalars.jdkmath.JavaMathBigIntegerPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.scalars.jodatime.JodaDateTimePanelFactory; +import org.apache.isis.viewer.wicket.ui.components.scalars.jodatime.JodaLocalDatePanelFactory; +import org.apache.isis.viewer.wicket.ui.components.scalars.jodatime.JodaLocalDateTimePanelFactory; +import org.apache.isis.viewer.wicket.ui.components.scalars.primitive.*; +import org.apache.isis.viewer.wicket.ui.components.scalars.reference.ReferencePanelFactory; +import org.apache.isis.viewer.wicket.ui.components.scalars.string.StringPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.scalars.value.ValuePanelFactory; +import org.apache.isis.viewer.wicket.ui.components.standalonecollection.StandaloneCollectionPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.unknown.UnknownModelPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.value.StandaloneValuePanelFactory; +import org.apache.isis.viewer.wicket.ui.components.voidreturn.VoidReturnPanelFactory; +import org.apache.isis.viewer.wicket.ui.components.welcome.WelcomePanelFactory; +import org.apache.isis.viewer.wicket.ui.components.widgets.entitysimplelink.EntityLinkSimplePanelFactory; +import org.apache.isis.viewer.wicket.ui.components.widgets.valuechoices.ValueChoicesSelect2PanelFactory; + +/** + * Default implementation of {@link ComponentFactoryRegistrar} that registers a + * hardcoded set of built-in {@link ComponentFactory}s, along with any + * implementations loaded using {@link ServiceLoader} (ie from + * <tt>META-INF/services</tt>). + */ +@Singleton +public class ComponentFactoryRegistrarDefault implements ComponentFactoryRegistrar { + + @Override + public void addComponentFactories(final ComponentFactoryList componentFactories) { + + addComponentFactoriesActingAsSelectors(componentFactories); + + addComponentFactoriesUsingServiceLoader(componentFactories); + + addBuiltInComponentFactories(componentFactories); + } + + /** + * Any {@link ComponentFactory}s that act as selectors of other factories + * should be registered here; they will be loaded first, to ensure that they + * are found first. + */ + protected void addComponentFactoriesActingAsSelectors(final ComponentFactoryList componentFactories) { + addLinksSelectorFactories(componentFactories); + componentFactories.add(new CollectionContentsAsUnresolvedPanelFactory()); // to prevent eager loading + } + + protected void addLinksSelectorFactories(final ComponentFactoryList componentFactories) { + componentFactories.add(new EntityLinksSelectorPanelFactory()); + componentFactories.add(new CollectionContentsMultipleViewsPanelFactory()); + } + + protected void addComponentFactoriesUsingServiceLoader(final ComponentFactoryList componentFactories) { + final ServiceLoader<ComponentFactory> serviceLoader = ServiceLoader.load(ComponentFactory.class); + + for (final ComponentFactory componentFactory : serviceLoader) { + componentFactories.add(componentFactory); + } + } + + private void addBuiltInComponentFactories(final ComponentFactoryList componentFactories) { + addComponentFactoriesForWelcomeAndAbout(componentFactories); + addComponentFactoriesForApplicationActions(componentFactories); + addComponentFactoriesForEntity(componentFactories); + addComponentFactoriesForActionInfo(componentFactories); + addComponentFactoriesForAction(componentFactories); + addComponentFactoriesForActionLink(componentFactories); + addComponentFactoriesForEntityCollection(componentFactories); + addComponentFactoriesForEntityCollectionContents(componentFactories); + addComponentFactoriesForEmptyCollection(componentFactories); + addComponentFactoriesForScalar(componentFactories); + addComponentFactoriesForEntityLink(componentFactories); + addComponentFactoriesForVoidReturn(componentFactories); + addComponentFactoriesForValue(componentFactories); + addComponentFactoriesForParameters(componentFactories); + addComponentFactoriesForBreadcrumbs(componentFactories); + addComponentFactoriesForPageHeader(componentFactories); + addComponentFactoriesForPageFooter(componentFactories); + + addComponentFactoriesForUnknown(componentFactories); + } + + protected void addComponentFactoriesForPageHeader(ComponentFactoryList componentFactories) { + componentFactories.add(new HeaderPanelFactory()); + } + + protected void addComponentFactoriesForPageFooter(ComponentFactoryList componentFactories) { + componentFactories.add(new FooterPanelFactory()); + } + + protected void addComponentFactoriesForWelcomeAndAbout(final ComponentFactoryList componentFactories) { + componentFactories.add(new WelcomePanelFactory()); + componentFactories.add(new AboutPanelFactory()); + } + + protected void addComponentFactoriesForEntity(final ComponentFactoryList componentFactories) { + + // top-level + componentFactories.add(new EntityCombinedPanelFactory()); + + // lower-level + componentFactories.add(new EntityIconAndTitlePanelFactory()); + componentFactories.add(new EntityIconTitleAndCopyLinkPanelFactory()); + componentFactories.add(new EntityHeaderPanelFactory()); + componentFactories.add(new EntityPropertiesPanelFactory()); + componentFactories.add(new EntityCollectionsPanelFactory()); + } + + protected void addComponentFactoriesForEntityCollectionContents(final ComponentFactoryList componentFactories) { + componentFactories.add(new CollectionContentsAsAjaxTablePanelFactory()); + + // // work-in-progress + // componentFactories.add(new CollectionContentsAsIconsPanelFactory()); + + componentFactories.add(new CollectionContentsAsSummaryFactory()); + } + + protected void addComponentFactoriesForEntityCollection(final ComponentFactoryList componentFactories) { + componentFactories.add(new CollectionPanelFactory()); + } + + protected void addComponentFactoriesForEmptyCollection(final ComponentFactoryList componentFactories) { + componentFactories.add(new EmptyCollectionPanelFactory()); + } + + protected void addComponentFactoriesForValue(final ComponentFactoryList componentFactories) { + componentFactories.add(new StandaloneValuePanelFactory()); + } + + protected void addComponentFactoriesForScalar(final ComponentFactoryList componentFactories) { + + componentFactories.add(new ReferencePanelFactory()); + + componentFactories.add(new BooleanPanelFactory()); + componentFactories.add(new BytePanelFactory()); + componentFactories.add(new ShortPanelFactory()); + componentFactories.add(new IntegerPanelFactory()); + componentFactories.add(new LongPanelFactory()); + componentFactories.add(new CharacterPanelFactory()); + componentFactories.add(new FloatPanelFactory()); + componentFactories.add(new DoublePanelFactory()); + + componentFactories.add(new StringPanelFactory()); + + // work-in-progress + // componentFactories.add(new JavaAwtImagePanelFactory()); + componentFactories.add(new JavaUtilDatePanelFactory()); + componentFactories.add(new JavaSqlTimestampPanelFactory()); + componentFactories.add(new JavaSqlDatePanelFactory()); + componentFactories.add(new JavaSqlTimePanelFactory()); + + componentFactories.add(new IsisMoneyPanelFactory()); + componentFactories.add(new IsisDatePanelFactory()); + componentFactories.add(new IsisDateTimePanelFactory()); + componentFactories.add(new IsisTimePanelFactory()); + componentFactories.add(new IsisTimeStampPanelFactory()); + componentFactories.add(new IsisColorPanelFactory()); + componentFactories.add(new IsisPercentagePanelFactory()); + componentFactories.add(new IsisPasswordPanelFactory()); + + componentFactories.add(new IsisBlobPanelFactory()); + componentFactories.add(new IsisClobPanelFactory()); + + componentFactories.add(new JavaMathBigIntegerPanelFactory()); + componentFactories.add(new JavaMathBigDecimalPanelFactory()); + + componentFactories.add(new JodaLocalDatePanelFactory()); + componentFactories.add(new JodaLocalDateTimePanelFactory()); + componentFactories.add(new JodaDateTimePanelFactory()); + + componentFactories.add(new ValuePanelFactory()); + + // or for choices + componentFactories.add(new ValueChoicesSelect2PanelFactory()); + } + + protected void addComponentFactoriesForEntityLink(final ComponentFactoryList componentFactories) { + componentFactories.add(new EntityLinkSimplePanelFactory()); + } + + protected void addComponentFactoriesForVoidReturn(final ComponentFactoryList componentFactories) { + componentFactories.add(new VoidReturnPanelFactory()); + } + + protected void addComponentFactoriesForActionInfo(final ComponentFactoryList componentFactories) { + componentFactories.add(new ActionInfoPanelFactory()); + } + + protected void addComponentFactoriesForParameters(final ComponentFactoryList componentFactories) { + componentFactories.add(new ActionParametersFormPanelFactory()); + } + + protected void addComponentFactoriesForAction(final ComponentFactoryList componentFactories) { + componentFactories.add(new ActionPanelFactory()); + componentFactories.add(new StandaloneCollectionPanelFactory()); + } + + protected void addComponentFactoriesForActionLink(final ComponentFactoryList componentFactories) { + componentFactories.add(new ActionLinkPanelFactory()); + } + + protected void addComponentFactoriesForApplicationActions(final ComponentFactoryList componentFactories) { + componentFactories.add(new ServiceActionsPanelFactory()); + componentFactories.add(new TertiaryMenuPanelFactory()); + } + + protected void addComponentFactoriesForBreadcrumbs(ComponentFactoryList componentFactories) { + componentFactories.add(new BookmarkedPagesPanelFactory()); + } + + protected void addComponentFactoriesForUnknown(final ComponentFactoryList componentFactories) { + componentFactories.add(new UnknownModelPanelFactory()); + } + +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistryDefault.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistryDefault.java b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistryDefault.java new file mode 100644 index 0000000..00f7a4d --- /dev/null +++ b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistryDefault.java @@ -0,0 +1,177 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.isis.viewer.wicket.viewer.registries.components; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +import javax.inject.Inject; + +import com.google.common.base.Supplier; +import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; +import com.google.inject.Singleton; + +import org.apache.wicket.Component; +import org.apache.wicket.MarkupContainer; +import org.apache.wicket.model.IModel; + +import org.apache.isis.viewer.wicket.ui.ComponentFactory; +import org.apache.isis.viewer.wicket.ui.ComponentFactory.ApplicationAdvice; +import org.apache.isis.viewer.wicket.ui.ComponentType; +import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistrar; +import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistrar.ComponentFactoryList; +import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistry; + +/** + * Implementation of {@link ComponentFactoryRegistry} that delegates to a + * provided {@link ComponentFactoryRegistrar}. + */ +@Singleton +public class ComponentFactoryRegistryDefault implements ComponentFactoryRegistry { + + private final Multimap<ComponentType, ComponentFactory> componentFactoriesByType; + + @Inject + public ComponentFactoryRegistryDefault(final ComponentFactoryRegistrar componentFactoryList) { + componentFactoriesByType = Multimaps.newListMultimap(new HashMap<ComponentType, Collection<ComponentFactory>>(), new Supplier<List<ComponentFactory>>() { + @Override + public List<ComponentFactory> get() { + return Lists.newArrayList(); + } + }); + + registerComponentFactories(componentFactoryList); + } + + // /////////////////////////////////////////////////////// + // Registration + // /////////////////////////////////////////////////////// + + /** + * Registers the provided set of component factories. + */ + protected void registerComponentFactories(final ComponentFactoryRegistrar componentFactoryRegistrar) { + + final ComponentFactoryList componentFactories = new ComponentFactoryList(); + componentFactoryRegistrar.addComponentFactories(componentFactories); + + for (final ComponentFactory componentFactory : componentFactories) { + registerComponentFactory(componentFactory); + } + + ensureAllComponentTypesRegistered(); + } + + protected synchronized void registerComponentFactory(final ComponentFactory componentFactory) { + componentFactoriesByType.put(componentFactory.getComponentType(), componentFactory); + } + + private void ensureAllComponentTypesRegistered() { + for (final ComponentType componentType : ComponentType.values()) { + final Collection<ComponentFactory> componentFactories = componentFactoriesByType.get(componentType); + if (componentFactories.isEmpty()) { + throw new IllegalStateException("No component factories registered for " + componentType); + } + } + } + + // /////////////////////////////////////////////////////// + // Public API + // /////////////////////////////////////////////////////// + + + @Override + public Component addOrReplaceComponent(final MarkupContainer markupContainer, final ComponentType componentType, final IModel<?> model) { + final Component component = createComponent(componentType, model); + markupContainer.addOrReplace(component); + return component; + } + + @Override + public Component addOrReplaceComponent(final MarkupContainer markupContainer, final String id, final ComponentType componentType, final IModel<?> model) { + final Component component = createComponent(componentType, id, model); + markupContainer.addOrReplace(component); + return component; + } + + @Override + public Component createComponent(final ComponentType componentType, final IModel<?> model) { + final ComponentFactory componentFactory = findComponentFactoryElseFailFast(componentType, model); + final Component component = componentFactory.createComponent(model); + return component; + } + + @Override + public Component createComponent(final ComponentType componentType, final String id, final IModel<?> model) { + final ComponentFactory componentFactory = findComponentFactoryElseFailFast(componentType, model); + final Component component = componentFactory.createComponent(id, model); + return component; + } + + @Override + public List<ComponentFactory> findComponentFactories(final ComponentType componentType, final IModel<?> model) { + final Collection<ComponentFactory> componentFactoryList = componentFactoriesByType.get(componentType); + final List<ComponentFactory> matching = Lists.newArrayList(); + for (final ComponentFactory componentFactory : componentFactoryList) { + final ApplicationAdvice appliesTo = componentFactory.appliesTo(componentType, model); + if (appliesTo.applies()) { + matching.add(componentFactory); + } + if (appliesTo.exclusively()) { + break; + } + } + if (matching.isEmpty()) { + // will just be one + matching.addAll(componentFactoriesByType.get(ComponentType.UNKNOWN)); + } + return matching; + } + + @Override + public ComponentFactory findComponentFactory(final ComponentType componentType, final IModel<?> model) { + final Collection<ComponentFactory> componentFactories = findComponentFactories(componentType, model); + return firstOrNull(componentFactories); + } + + @Override + public ComponentFactory findComponentFactoryElseFailFast(final ComponentType componentType, final IModel<?> model) { + final ComponentFactory componentFactory = findComponentFactory(componentType, model); + if (componentFactory == null) { + throw new RuntimeException(String.format("could not find component for componentType = '%s'; model object is of type %s", componentType, model.getClass().getName())); + } + return componentFactory; + } + + private static <T> T firstOrNull(final Collection<T> collection) { + final Iterator<T> iterator = collection.iterator(); + return iterator.hasNext() ? iterator.next() : null; + } + + @Override + public Collection<ComponentFactory> listComponentFactories() { + return componentFactoriesByType.values(); + } + +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassListDefault.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassListDefault.java b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassListDefault.java new file mode 100644 index 0000000..5d15946 --- /dev/null +++ b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassListDefault.java @@ -0,0 +1,141 @@ +/* + * 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.isis.viewer.wicket.viewer.registries.pages; + +import com.google.inject.Singleton; + +import org.apache.wicket.Page; + +import org.apache.isis.viewer.wicket.model.models.PageType; +import org.apache.isis.viewer.wicket.ui.pages.PageClassList; +import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistrySpi; +import org.apache.isis.viewer.wicket.ui.pages.about.AboutPage; +import org.apache.isis.viewer.wicket.ui.pages.actionprompt.ActionPromptPage; +import org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage; +import org.apache.isis.viewer.wicket.ui.pages.home.HomePage; +import org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage; +import org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage; +import org.apache.isis.viewer.wicket.ui.pages.accmngt.register.RegisterPage; +import org.apache.isis.viewer.wicket.ui.pages.accmngt.signup.RegistrationFormPage; +import org.apache.isis.viewer.wicket.ui.pages.standalonecollection.StandaloneCollectionPage; +import org.apache.isis.viewer.wicket.ui.pages.value.ValuePage; +import org.apache.isis.viewer.wicket.ui.pages.voidreturn.VoidReturnPage; + +/** + * Default implementation of {@link PageClassList}, specifying the default pages + * for each of the {@link PageType}s. + */ +@Singleton +public class PageClassListDefault implements PageClassList { + + private static final long serialVersionUID = 1L; + + @Override + public void registerPages(final PageClassRegistrySpi pageRegistry) { + pageRegistry.registerPage(PageType.SIGN_IN, getSignInPageClass()); + pageRegistry.registerPage(PageType.SIGN_UP, getSignUpPageClass()); + pageRegistry.registerPage(PageType.SIGN_UP_VERIFY, getSignUpVerifyPageClass()); + pageRegistry.registerPage(PageType.PASSWORD_RESET, getPasswordResetPageClass()); + pageRegistry.registerPage(PageType.ABOUT, getAboutPageClass()); + pageRegistry.registerPage(PageType.ENTITY, getEntityPageClass()); + pageRegistry.registerPage(PageType.HOME, getHomePageClass()); + pageRegistry.registerPage(PageType.ACTION_PROMPT, getActionPromptPageClass()); + pageRegistry.registerPage(PageType.STANDALONE_COLLECTION, getStandaloneCollectionPageClass()); + pageRegistry.registerPage(PageType.VALUE, getValuePageClass()); + pageRegistry.registerPage(PageType.VOID_RETURN, getVoidReturnPageClass()); + } + + /** + * For subclassing if required. + */ + protected Class<? extends Page> getActionPromptPageClass() { + return ActionPromptPage.class; + } + + /** + * For subclassing if required. + */ + protected Class<? extends Page> getEntityPageClass() { + return EntityPage.class; + } + + /** + * For subclassing if required. + */ + protected Class<? extends Page> getStandaloneCollectionPageClass() { + return StandaloneCollectionPage.class; + } + + /** + * For subclassing if required. + */ + protected Class<? extends Page> getValuePageClass() { + return ValuePage.class; + } + + /** + * For subclassing if required. + */ + protected Class<? extends Page> getVoidReturnPageClass() { + return VoidReturnPage.class; + } + + /** + * For subclassing if required. + */ + protected Class<? extends Page> getSignInPageClass() { + return WicketSignInPage.class; + } + + /** + * For subclassing if required. + */ + protected Class<? extends Page> getSignUpPageClass() { + return RegistrationFormPage.class; + } + + /** + * For subclassing if required. + */ + protected Class<? extends Page> getSignUpVerifyPageClass() { + return RegisterPage.class; + } + + /** + * For subclassing if required. + */ + protected Class<? extends Page> getPasswordResetPageClass() { + return PasswordResetPage.class; + } + + /** + * For subclassing if required. + */ + protected Class<? extends Page> getHomePageClass() { + return HomePage.class; + } + + /** + * For subclassing if required. + */ + protected Class<? extends Page> getAboutPageClass() { + return AboutPage.class; + } +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassRegistryDefault.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassRegistryDefault.java b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassRegistryDefault.java new file mode 100644 index 0000000..56550c7 --- /dev/null +++ b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassRegistryDefault.java @@ -0,0 +1,85 @@ +/* + * 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.isis.viewer.wicket.viewer.registries.pages; + +import java.util.Map; + +import com.google.common.collect.Maps; +import com.google.inject.Inject; +import com.google.inject.Singleton; + +import org.apache.wicket.Page; + +import org.apache.isis.viewer.wicket.model.models.PageType; +import org.apache.isis.viewer.wicket.ui.pages.PageClassList; +import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry; +import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistrySpi; + +/** + * Default implementation of {@link PageClassRegistry}; just delegates to an + * underlying {@link PageClassList}. + */ +@Singleton +public class PageClassRegistryDefault implements PageClassRegistry, PageClassRegistrySpi { + + private static final long serialVersionUID = 1L; + + private final Map<PageType, Class<? extends Page>> pagesByType = Maps.newHashMap(); + + /** + * {@link Inject}ed in {@link #PageClassRegistryDefault(PageClassList) + * constructor}. + */ + @SuppressWarnings("unused") + private final PageClassList pageClassList; + + @Inject + public PageClassRegistryDefault(final PageClassList pageClassList) { + this.pageClassList = pageClassList; + pageClassList.registerPages(this); + ensureAllPageTypesRegistered(); + } + + private void ensureAllPageTypesRegistered() { + for (final PageType pageType : PageType.values()) { + if (getPageClass(pageType) == null) { + throw new IllegalStateException("No page registered for " + pageType); + } + } + } + + // ///////////////////////////////////////////////////////// + // API + // ///////////////////////////////////////////////////////// + + @Override + public final Class<? extends Page> getPageClass(final PageType pageType) { + return pagesByType.get(pageType); + } + + // ///////////////////////////////////////////////////////// + // API + // ///////////////////////////////////////////////////////// + + @Override + public final void registerPage(final PageType pageType, final Class<? extends Page> pageClass) { + pagesByType.put(pageType, pageClass); + } +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageNavigationServiceDefault.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageNavigationServiceDefault.java b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageNavigationServiceDefault.java new file mode 100644 index 0000000..ab45158 --- /dev/null +++ b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageNavigationServiceDefault.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.isis.viewer.wicket.viewer.registries.pages; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import org.apache.wicket.Page; +import org.apache.wicket.RestartResponseAtInterceptPageException; +import org.apache.wicket.RestartResponseException; +import org.apache.wicket.request.cycle.RequestCycle; +import org.apache.wicket.request.mapper.parameter.PageParameters; +import org.apache.isis.viewer.wicket.model.models.PageType; +import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry; +import org.apache.isis.viewer.wicket.ui.pages.PageNavigationService; + +/** + * Default implementation of {@link org.apache.isis.viewer.wicket.ui.pages.PageNavigationService} + */ +@Singleton +public class PageNavigationServiceDefault implements PageNavigationService { + + private static final long serialVersionUID = 1L; + + private final PageClassRegistry pageClassRegistry; + + @Inject + public PageNavigationServiceDefault(final PageClassRegistry pageClassRegistry) { + this.pageClassRegistry = pageClassRegistry; + } + + @Override + public void navigateTo(PageType pageType) { + navigateTo(pageType, new PageParameters()); + } + + @Override + public void navigateTo(PageType pageType, PageParameters parameters) { + Class<? extends Page> pageClass = pageClassRegistry.getPageClass(pageType); + RequestCycle.get().setResponsePage(pageClass, parameters); + } + + @Override + public void restartAt(PageType pageType) { + Class<? extends Page> pageClass = pageClassRegistry.getPageClass(pageType); + throw new RestartResponseException(pageClass); + } + + @Override + public void interceptAndRestartAt(PageType pageType) { + Class<? extends Page> pageClass = pageClassRegistry.getPageClass(pageType); + throw new RestartResponseAtInterceptPageException(pageClass); + } +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/DeepLinkServiceWicket.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/DeepLinkServiceWicket.java b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/DeepLinkServiceWicket.java new file mode 100644 index 0000000..e597489 --- /dev/null +++ b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/DeepLinkServiceWicket.java @@ -0,0 +1,70 @@ +package org.apache.isis.viewer.wicket.viewer.services; + +import java.net.URI; +import java.net.URISyntaxException; +import org.apache.wicket.Page; +import org.apache.wicket.request.Url; +import org.apache.wicket.request.cycle.RequestCycle; +import org.apache.wicket.request.mapper.parameter.PageParameters; +import org.apache.isis.applib.annotation.DomainService; +import org.apache.isis.applib.annotation.Programmatic; +import org.apache.isis.applib.services.linking.DeepLinkService; +import org.apache.isis.core.metamodel.adapter.ObjectAdapter; +import org.apache.isis.core.runtime.persistence.adaptermanager.AdapterManagerDefault; +import org.apache.isis.core.runtime.system.context.IsisContext; +import org.apache.isis.core.runtime.system.persistence.PersistenceSession; +import org.apache.isis.viewer.wicket.model.models.EntityModel; +import org.apache.isis.viewer.wicket.model.models.PageType; +import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry; +import org.apache.isis.viewer.wicket.viewer.registries.pages.PageClassListDefault; +import org.apache.isis.viewer.wicket.viewer.registries.pages.PageClassRegistryDefault; + +/** + * An implementation of {@link org.apache.isis.applib.services.linking.DeepLinkService} + * for Wicket Viewer + */ +@DomainService +public class DeepLinkServiceWicket implements DeepLinkService { + + private final PageClassRegistry pageClassRegistry; + + /** + * Note: we instantiate {@link org.apache.isis.viewer.wicket.viewer.registries.pages.PageClassRegistryDefault} and + * {@link org.apache.isis.viewer.wicket.viewer.registries.pages.PageClassListDefault} because there is no easy + * way to inject these objects. In other words we do <i>not</i> honour any custom implementations of these service + * that are bound in {@link org.apache.isis.viewer.wicket.viewer.IsisWicketModule}. We expect to address this + * limitation as and when we refactor to using CDI. + */ + public DeepLinkServiceWicket() { + this.pageClassRegistry = new PageClassRegistryDefault(new PageClassListDefault()); + } + + + @Programmatic + @Override + public URI deepLinkFor(final Object domainObject) { + + final AdapterManagerDefault adapterManager = getAdapterManager(); + final ObjectAdapter objectAdapter = adapterManager.adapterFor(domainObject); + final PageParameters pageParameters = EntityModel.createPageParameters(objectAdapter); + + final Class<? extends Page> pageClass = pageClassRegistry.getPageClass(PageType.ENTITY); + + final RequestCycle requestCycle = RequestCycle.get(); + final CharSequence urlForPojo = requestCycle.urlFor(pageClass, pageParameters); + final String fullUrl = requestCycle.getUrlRenderer().renderFullUrl(Url.parse(urlForPojo)); + try { + return new URI(fullUrl); + } catch (final URISyntaxException ex) { + throw new RuntimeException("Cannot create a deep link to domain object: " + domainObject, ex); + } + } + + protected AdapterManagerDefault getAdapterManager() { + return getPersistenceSession().getAdapterManager(); + } + + protected PersistenceSession getPersistenceSession() { + return IsisContext.getPersistenceSession(); + } +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/LocaleProviderWicket.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/LocaleProviderWicket.java b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/LocaleProviderWicket.java new file mode 100644 index 0000000..9f3b58d --- /dev/null +++ b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/LocaleProviderWicket.java @@ -0,0 +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.isis.viewer.wicket.viewer.services; + +import java.util.Locale; +import org.apache.wicket.Application; +import org.apache.wicket.Session; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.apache.isis.applib.annotation.DomainService; +import org.apache.isis.applib.annotation.NatureOfService; +import org.apache.isis.applib.annotation.Programmatic; +import org.apache.isis.applib.services.i18n.LocaleProvider; + + +/** + * An implementation that provides the locale of the current session. + */ +@DomainService( + nature = NatureOfService.DOMAIN +) +public class LocaleProviderWicket implements LocaleProvider { + + public static Logger LOG = LoggerFactory.getLogger(LocaleProviderWicket.class); + + @Programmatic + @Override + public Locale getLocale() { + if(!Application.exists()) { + // eg if request from RO viewer + return null; + } + return getSession().getLocale(); + } + + protected Session getSession() { + return Session.get(); + } +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/TranslationsResolverWicket.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/TranslationsResolverWicket.java b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/TranslationsResolverWicket.java new file mode 100644 index 0000000..2abbbba --- /dev/null +++ b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/services/TranslationsResolverWicket.java @@ -0,0 +1,93 @@ +/* + * 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.isis.viewer.wicket.viewer.services; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.nio.file.Path; +import java.util.List; +import javax.servlet.ServletContext; +import com.google.common.base.Charsets; +import com.google.common.io.CharSource; +import com.google.common.io.Files; +import com.google.common.io.Resources; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.apache.isis.applib.annotation.DomainService; +import org.apache.isis.applib.annotation.NatureOfService; +import org.apache.isis.applib.annotation.Programmatic; +import org.apache.isis.applib.services.i18n.TranslationsResolver; +import org.apache.isis.core.webapp.WebAppConstants; +import org.apache.isis.viewer.wicket.viewer.IsisWicketApplication; + + +/** + * An implementation that reads from /WEB-INF/... + */ +@DomainService( + nature = NatureOfService.DOMAIN +) +public class TranslationsResolverWicket implements TranslationsResolver { + + public static Logger LOG = LoggerFactory.getLogger(TranslationsResolverWicket.class); + + @Override + @Programmatic + public List<String> readLines(final String file) { + final ServletContext servletContext = getServletContext(); + + final String configLocation = servletContext.getInitParameter(WebAppConstants.CONFIG_DIR_PARAM); + try { + if(configLocation != null) { + LOG.info( "Reading translations relative to config override location: " + configLocation ); + return Files.readLines(newFile(configLocation, file), Charsets.UTF_8); + } else { + final URL url = servletContext.getResource("/WEB-INF/" + file); + return readLines(url); + } + } catch (final RuntimeException | IOException ignored) { + return null; + } + } + + static File newFile(final String dir, final String file) { + final File base = new File(dir); + final Path path = base.toPath(); + final Path resolve = path.resolve(file); + return resolve.toFile(); + } + + protected ServletContext getServletContext() { + return getIsisWicketApplication().getServletContext(); + } + + private static List<String> readLines(final URL url) throws IOException { + if(url == null) { + return null; + } + final CharSource charSource = Resources.asCharSource(url, Charsets.UTF_8); + return charSource.readLines(); + } + + protected IsisWicketApplication getIsisWicketApplication() { + return IsisWicketApplication.get(); + } + +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/settings/IsisResourceSettings.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/settings/IsisResourceSettings.java b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/settings/IsisResourceSettings.java new file mode 100644 index 0000000..ddb3da6 --- /dev/null +++ b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/settings/IsisResourceSettings.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.isis.viewer.wicket.viewer.settings; + +import java.util.List; +import org.apache.wicket.Application; +import org.apache.wicket.resource.loader.*; +import org.apache.wicket.settings.def.ResourceSettings; +import org.apache.wicket.util.lang.Generics; + +public class IsisResourceSettings extends ResourceSettings { + + /** Chain of string resource loaders to use */ + private final List<IStringResourceLoader> stringResourceLoaders = Generics.newArrayList(4); + + /** + * Configures Wicket's default ResourceLoaders. + * + * <p> + * In contrast to the default lookup strategy, Isis' searches for application-specific properties first. + * + * </p> + * For an example in {@code FooApplication} let {@code bar.Foo} extend {@link org.apache.wicket.Component}, this + * results in the following ordering: + * <dl> + * <dt>application specific</dt> + * <dd> + * <ul> + * <li>FooApplication.properties</li> + * <li>Application.properties</li> + * </ul> + * </dd> + * <dt>component specific</dt> + * <dd> + * <ul> + * <li>bar/Foo.properties</li> + * <li>org/apache/wicket/Component.properties</li> + * </ul> + * </dd> + * <dt>package specific</dt> + * <dd> + * <ul> + * <li>bar/package.properties</li> + * <li>package.properties (on Foo's class loader)</li> + * <li>org/apache/wicket/package.properties</li> + * <li>org/apache/package.properties</li> + * <li>org/package.properties</li> + * <li>package.properties (on Component's class loader)</li> + * </ul> + * </dd> + * <dt>validator specific</dt> + * <dt>Initializer specific</dt> + * <dd> + * <ul> + * <li>bar.Foo.properties (Foo implementing IInitializer)</li> + * </ul> + * </dd> + * </dl> + * + * @param application + */ + public IsisResourceSettings(Application application) { + super(application); + + // consult first (the default implementation checks this only third) + stringResourceLoaders.add(new ClassStringResourceLoader(application.getClass())); + + stringResourceLoaders.add(new ComponentStringResourceLoader()); + stringResourceLoaders.add(new PackageStringResourceLoader()); + // this is where the default implementation registered the search. + //stringResourceLoaders.add(new ClassStringResourceLoader(application.getClass())); + stringResourceLoaders.add(new ValidatorStringResourceLoader()); + stringResourceLoaders.add(new InitializerStringResourceLoader(application.getInitializers())); + } + + /** + * @see org.apache.wicket.settings.IResourceSettings#getStringResourceLoaders() + */ + @Override + public List<IStringResourceLoader> getStringResourceLoaders() + { + return stringResourceLoaders; + } +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/settings/WicketViewerSettingsDefault.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/settings/WicketViewerSettingsDefault.java b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/settings/WicketViewerSettingsDefault.java new file mode 100644 index 0000000..5e01d0b --- /dev/null +++ b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/settings/WicketViewerSettingsDefault.java @@ -0,0 +1,100 @@ +/* + * 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.isis.viewer.wicket.viewer.settings; + +import com.google.inject.Singleton; + +import org.apache.isis.core.commons.config.IsisConfiguration; +import org.apache.isis.core.runtime.system.context.IsisContext; +import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings; +import org.apache.isis.viewer.wicket.ui.components.scalars.datepicker.TextFieldWithDatePicker; + +@Singleton +public class WicketViewerSettingsDefault implements WicketViewerSettings { + + private static final long serialVersionUID = 1L; + + IsisConfiguration getConfiguration() { + return IsisContext.getConfiguration(); + } + + /** + * The maximum length that a title of an object will be shown when rendered in a standalone table; + * will be truncated beyond this (with ellipses to indicate the truncation). + */ + @Override + public int getMaxTitleLengthInStandaloneTables() { + return getConfiguration().getInteger("isis.viewer.wicket.maxTitleLengthInStandaloneTables", getMaxTitleLengthInTables()); + } + + /** + * The maximum length that a title of an object will be shown when rendered in a parented table; + * will be truncated beyond this (with ellipses to indicate the truncation). + */ + @Override + public int getMaxTitleLengthInParentedTables() { + return getConfiguration().getInteger("isis.viewer.wicket.maxTitleLengthInParentedTables", getMaxTitleLengthInTables()); + } + + /** + * Fallback for either {@link #getMaxTitleLengthInParentedTables()} and {@link #getMaxTitleLengthInParentedTables()} + */ + private int getMaxTitleLengthInTables() { + return getConfiguration().getInteger("isis.viewer.wicket.maxTitleLengthInTables", 12); + } + + /** + * The pattern used for rendering and parsing dates. + */ + @Override + public String getDatePattern() { + return getConfiguration().getString("isis.viewer.wicket.datePattern", "dd-MM-yyyy"); + } + + /** + * The pattern used for rendering and parsing date/times. + */ + @Override + public String getDateTimePattern() { + return getConfiguration().getString("isis.viewer.wicket.dateTimePattern", "dd-MM-yyyy HH:mm"); + } + + /** + * The pattern used for rendering and parsing timestamps. + */ + @Override + public String getTimestampPattern() { + return getConfiguration().getString("isis.viewer.wicket.timestampPattern", "yyyy-MM-dd HH:mm:ss.SSS"); + } + + /** + * The pattern used for rendering dates chosen by the {@link TextFieldWithDatePicker}. + * + * <p> + * This pattern is different from {@link #getDatePattern()} because it is interpreted by + * <a href="https://github.com/Eonasdan/bootstrap-datetimepicker">Bootstrap Datetime Picker</a> component + * that uses <a href="http://momentjs.com/docs/#/parsing/string-format/">Moment.js formats</a>, rather + * than by Java code. + */ + @Override + public String getDatePickerPattern() { + return getConfiguration().getString("isis.viewer.wicket.datePickerPattern", "DD-MM-YYYY"); + } +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/impl/src/main/resources/log4j.properties ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/impl/src/main/resources/log4j.properties b/core/viewer-wicket/impl/src/main/resources/log4j.properties new file mode 100644 index 0000000..f275d06 --- /dev/null +++ b/core/viewer-wicket/impl/src/main/resources/log4j.properties @@ -0,0 +1,28 @@ +# 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. +log4j.appender.Stdout=org.apache.log4j.ConsoleAppender +log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.Stdout.layout.conversionPattern=%-5p - %-26.26c{1} - %m\n + +log4j.rootLogger=INFO,Stdout + +log4j.logger.org.apache.wicket=INFO +log4j.logger.org.apache.wicket.protocol.http.HttpSessionStore=INFO +log4j.logger.org.apache.wicket.version=INFO +log4j.logger.org.apache.wicket.RequestCycle=INFO + + http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Defaults.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Defaults.java b/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Defaults.java new file mode 100644 index 0000000..904d74c --- /dev/null +++ b/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Defaults.java @@ -0,0 +1,79 @@ +/* + * 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.isis.viewer.wicket.viewer; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; + +import org.apache.wicket.IConverterLocator; +import org.apache.wicket.authroles.authentication.AuthenticatedWebSession; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; + +import org.apache.isis.core.metamodel.adapter.ObjectAdapter; +import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2; +import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode; +import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento; +import org.apache.isis.viewer.wicket.viewer.integration.wicket.AuthenticatedWebSessionForIsis; + +public class IsisWicketApplication_Defaults { + + @Rule + public final JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES); + + private IsisWicketApplication application; + + @Before + public void setUp() throws Exception { + application = new IsisWicketApplication(); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void usesCustomSubclassOfAuthenticatedWebSession() { + final Class<? extends AuthenticatedWebSession> webSessionClass = application.getWebSessionClass(); + assertThat(webSessionClass.equals(AuthenticatedWebSessionForIsis.class), is(true)); + } + + @Ignore // 6.0.0 does it differently + @Test + public void providesCustomRequestCycle() { +// final WebRequest mockRequest = context.mock(WebRequest.class); +// final Response mockResponse = context.mock(Response.class); +// final RequestCycle newRequestCycle = application.newRequestCycle(mockRequest, mockResponse); +// assertThat(newRequestCycle, is(WebRequestCycleForIsis.class)); + } + + @Test + public void providesConverterLocatorRegistersIsisSpecificConverters() { + final IConverterLocator converterLocator = application.newConverterLocator(); + assertThat(converterLocator.getConverter(ObjectAdapter.class), is(not(nullValue()))); + assertThat(converterLocator.getConverter(ObjectAdapterMemento.class), is(not(nullValue()))); + } + +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Pages.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Pages.java b/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Pages.java new file mode 100644 index 0000000..5e754b0 --- /dev/null +++ b/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication_Pages.java @@ -0,0 +1,97 @@ +/* + * 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.isis.viewer.wicket.viewer; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import org.apache.wicket.Page; +import org.apache.wicket.markup.html.WebPage; +import org.jmock.Expectations; +import org.jmock.auto.Mock; +import org.junit.Rule; +import org.junit.Test; + +import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2; +import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode; +import org.apache.isis.viewer.wicket.model.models.PageType; +import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry; +import org.apache.isis.viewer.wicket.ui.pages.home.HomePage; + +public class IsisWicketApplication_Pages { + + @Rule + public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_ONLY); + + @Mock + private PageClassRegistry mockPageClassRegistry; + + private IsisWicketApplication application; + + @Test + public void delegatesToPageClassRegistryToObtainPageTypes() { + final PageType pageType = PageType.HOME; + final Class<HomePage> expectedPageClass = HomePage.class; + + application = new IsisWicketApplication() { + private static final long serialVersionUID = 1L; + + @Override + public PageClassRegistry getPageClassRegistry() { + return mockPageClassRegistry; + } + + }; + context.checking(new Expectations() { + { + one(mockPageClassRegistry).getPageClass(pageType); + will(returnValue(expectedPageClass)); + } + }); + final Class<? extends Page> pageClass = application.getHomePage(); + assertThat(expectedPageClass.isAssignableFrom(pageClass), is(true)); + } + + @Test + public void delegatesToPageClassRegistryToObtainPageTypes_ForSignIn() { + + final PageType pageType = PageType.SIGN_IN; + final Class<WebPage> expectedPageClass = WebPage.class; + + final PageClassRegistry mockPageClassRegistry = context.mock(PageClassRegistry.class); + application = new IsisWicketApplication() { + private static final long serialVersionUID = 1L; + + @Override + public PageClassRegistry getPageClassRegistry() { + return mockPageClassRegistry; + } + }; + context.checking(new Expectations() { + { + one(mockPageClassRegistry).getPageClass(pageType); + will(returnValue(expectedPageClass)); + } + }); + final Class<? extends Page> pageClass = application.getSignInPageClass(); + assertThat(expectedPageClass.isAssignableFrom(pageClass), is(true)); + } + +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicket_providers.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicket_providers.java b/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicket_providers.java new file mode 100644 index 0000000..2dda4ef --- /dev/null +++ b/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/IsisWicket_providers.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.isis.viewer.wicket.viewer; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; + +import com.google.inject.Guice; +import com.google.inject.Injector; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import org.apache.isis.core.commons.config.IsisConfigurationBuilder; +import org.apache.isis.core.runtime.system.DeploymentType; +import org.apache.isis.core.runtime.system.IsisSystem; + +public class IsisWicket_providers { + + private IsisWicketModule isisWicketModule; + private Injector injector; + + @Before + public void setUp() throws Exception { + isisWicketModule = new IsisWicketModule(); + injector = Guice.createInjector(isisWicketModule); + } + + @Ignore // REVIEW: DKH + @Test + public void deploymentType() { + final DeploymentType instance = injector.getInstance(DeploymentType.class); + assertThat(instance, is(notNullValue())); + } + + @Ignore // REVIEW: DKH + @Test + public void configurationBuilder() { + final IsisConfigurationBuilder instance = injector.getInstance(IsisConfigurationBuilder.class); + assertThat(instance, is(notNullValue())); + } + + @Ignore + // need to handle config + @Test + public void isisSystem() { + final IsisSystem instance = injector.getInstance(IsisSystem.class); + assertThat(instance, is(notNullValue())); + } + +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/WicketObjectModule_bindingsStandard.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/WicketObjectModule_bindingsStandard.java b/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/WicketObjectModule_bindingsStandard.java new file mode 100644 index 0000000..6121101 --- /dev/null +++ b/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/WicketObjectModule_bindingsStandard.java @@ -0,0 +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.isis.viewer.wicket.viewer; + +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.Collection; + +import com.google.inject.Guice; +import com.google.inject.Injector; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistrar; +import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistry; +import org.apache.isis.viewer.wicket.ui.pages.PageClassList; +import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry; +import org.apache.isis.viewer.wicket.viewer.registries.components.ComponentFactoryRegistrarDefault; +import org.apache.isis.viewer.wicket.viewer.registries.components.ComponentFactoryRegistryDefault; +import org.apache.isis.viewer.wicket.viewer.registries.pages.PageClassListDefault; +import org.apache.isis.viewer.wicket.viewer.registries.pages.PageClassRegistryDefault; + +@RunWith(Parameterized.class) +public class WicketObjectModule_bindingsStandard { + + private IsisWicketModule wicketObjectsModule; + private Injector injector; + private final Class<?> from; + private final Class<?> to; + + @Parameters + public static Collection<Object[]> params() { + return Arrays.asList(new Object[][] { { ComponentFactoryRegistrar.class, ComponentFactoryRegistrarDefault.class }, { ComponentFactoryRegistry.class, ComponentFactoryRegistryDefault.class }, { PageClassList.class, PageClassListDefault.class }, + { PageClassRegistry.class, PageClassRegistryDefault.class }, }); + } + + public WicketObjectModule_bindingsStandard(final Class<?> from, final Class<?> to) { + this.from = from; + this.to = to; + } + + @Before + public void setUp() throws Exception { + wicketObjectsModule = new IsisWicketModule(); + injector = Guice.createInjector(wicketObjectsModule); + } + + @Test + public void binding() { + final Object instance = injector.getInstance(from); + assertThat(instance, is(instanceOf(to))); + } + +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_Authenticate.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_Authenticate.java b/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_Authenticate.java new file mode 100644 index 0000000..2ecd81c --- /dev/null +++ b/core/viewer-wicket/impl/src/test/java/org/apache/isis/viewer/wicket/viewer/app/wicket/AuthenticatedWebSessionForIsis_Authenticate.java @@ -0,0 +1,109 @@ +/* + * 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.isis.viewer.wicket.viewer.app.wicket; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; + +import java.util.Locale; + +import org.apache.wicket.request.Request; +import org.jmock.Expectations; +import org.jmock.auto.Mock; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import org.apache.isis.core.runtime.authentication.AuthenticationManager; +import org.apache.isis.core.runtime.authentication.AuthenticationRequest; +import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2; +import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode; +import org.apache.isis.viewer.wicket.viewer.integration.wicket.AuthenticatedWebSessionForIsis; + +public class AuthenticatedWebSessionForIsis_Authenticate { + + @Rule + public final JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES); + + private AuthenticatedWebSessionForIsis webSession; + @Mock + private Request stubRequest; + @Mock + private AuthenticationManager mockAuthMgr; + + @Before + public void setUp() throws Exception { + context.checking(new Expectations() { + { + // must provide explicit expectation, since Locale is final. + allowing(stubRequest).getLocale(); + will(returnValue(Locale.getDefault())); + + // stub everything else out + ignoring(stubRequest); + } + }); + + } + + @Test + public void delegatesToAuthenticationManagerAndCachesAuthSessionIfOk() { + + context.checking(new Expectations() { + { + one(mockAuthMgr).authenticate(with(any(AuthenticationRequest.class))); + } + }); + + webSession = new AuthenticatedWebSessionForIsis(stubRequest) { + private static final long serialVersionUID = 1L; + + @Override + protected AuthenticationManager getAuthenticationManager() { + return mockAuthMgr; + } + }; + assertThat(webSession.authenticate("jsmith", "secret"), is(true)); + assertThat(webSession.getAuthenticationSession(), is(not(nullValue()))); + } + + @Test + public void delegatesToAuthenticationManagerAndHandlesIfNotAuthenticated() { + context.checking(new Expectations() { + { + one(mockAuthMgr).authenticate(with(any(AuthenticationRequest.class))); + will(returnValue(null)); + } + }); + webSession = new AuthenticatedWebSessionForIsis(stubRequest) { + private static final long serialVersionUID = 1L; + + @Override + protected AuthenticationManager getAuthenticationManager() { + return mockAuthMgr; + } + }; + assertThat(webSession.authenticate("jsmith", "secret"), is(false)); + assertThat(webSession.getAuthenticationSession(), is(nullValue())); + } + +}