/* * 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.ui.pages.entity; import org.apache.wicket.Application; import org.apache.wicket.RestartResponseException; import org.apache.wicket.authroles.authorization.strategies.role.annotations.AuthorizeInstantiation; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.link.BookmarkablePageLink; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.util.string.Strings; import org.apache.isis.applib.layout.component.Grid; import org.apache.isis.core.metamodel.adapter.ObjectAdapter; import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException; import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy; import org.apache.isis.core.metamodel.deployment.DeploymentCategory; import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacet; import org.apache.isis.core.metamodel.facets.object.grid.GridFacet; import org.apache.isis.core.metamodel.spec.ObjectSpecification; import org.apache.isis.core.metamodel.spec.feature.ObjectMember; import org.apache.isis.viewer.wicket.model.common.PageParametersUtils; import org.apache.isis.viewer.wicket.model.hints.UiHintContainer; import org.apache.isis.viewer.wicket.model.models.EntityModel; import org.apache.isis.viewer.wicket.ui.ComponentType; import org.apache.isis.viewer.wicket.ui.components.widgets.breadcrumbs.BreadcrumbModel; import org.apache.isis.viewer.wicket.ui.components.widgets.breadcrumbs.BreadcrumbModelProvider; import org.apache.isis.viewer.wicket.ui.pages.PageAbstract; import org.apache.isis.viewer.wicket.ui.util.CssClassAppender; /** * Web page representing an entity. */ @AuthorizeInstantiation("org.apache.isis.viewer.wicket.roles.USER") public class EntityPage extends PageAbstract { private static final long serialVersionUID = 1L; private final EntityModel model; private final String titleString; /** * Called reflectively, in support of * {@link BookmarkablePageLink bookmarkable} links. */ public EntityPage(final PageParameters pageParameters) { this(pageParameters, createEntityModel(pageParameters)); } /** * Creates an EntityModel from the given page parameters. * Redirects to the application home page if there is no OID in the parameters. * * @param parameters The page parameters with the OID * @return An EntityModel for the requested OID */ private static EntityModel createEntityModel(final PageParameters parameters) { String oid = EntityModel.oidStr(parameters); if (Strings.isEmpty(oid)) { throw new RestartResponseException(Application.get().getHomePage()); } return new EntityModel(parameters); } private EntityPage(final PageParameters pageParameters, final EntityModel entityModel) { this(pageParameters, entityModel, null); } public EntityPage(final ObjectAdapter adapter) { this(adapter, null); } /** * Ensure that any {@link ConcurrencyException} that might have occurred already * (eg from an action invocation) is show. */ public EntityPage(final ObjectAdapter adapter, final ConcurrencyException exIfAny) { this(PageParametersUtils.newPageParameters(), newEntityModel(adapter, exIfAny)); } private static EntityModel newEntityModel( final ObjectAdapter adapter, final ConcurrencyException exIfAny) { final EntityModel model = new EntityModel(adapter); model.setException(exIfAny); return model; } private EntityPage( final PageParameters pageParameters, final EntityModel entityModel, final String titleString) { super(pageParameters, titleString, ComponentType.ENTITY); this.model = entityModel; this.titleString = titleString; buildPage(); } private void addBreadcrumb(final EntityModel entityModel) { final BreadcrumbModelProvider session = (BreadcrumbModelProvider) getSession(); final BreadcrumbModel breadcrumbModel = session.getBreadcrumbModel(); breadcrumbModel.visited(entityModel); } private void removeAnyBreadcrumb(final EntityModel entityModel) { final BreadcrumbModelProvider session = (BreadcrumbModelProvider) getSession(); final BreadcrumbModel breadcrumbModel = session.getBreadcrumbModel(); breadcrumbModel.remove(entityModel); } @Override public UiHintContainer getUiHintContainerIfAny() { return model; } private void buildPage() { final ObjectAdapter objectAdapter; try { // check object still exists objectAdapter = model.getObject(); } catch(final RuntimeException ex) { removeAnyBookmark(model); removeAnyBreadcrumb(model); // we throw an authorization exception here to avoid leaking out information as to whether the object exists or not. throw new ObjectMember.AuthorizationException(ex); } // check that the entity overall can be viewed. if(!ObjectAdapter.Util.isVisible(objectAdapter, InteractionInitiatedBy.USER)) { throw new ObjectMember.AuthorizationException(); } final ObjectSpecification objectSpec = model.getTypeOfSpecification(); final GridFacet gridFacet = objectSpec.getFacet(GridFacet.class); if(gridFacet != null) { // the facet should always exist, in fact // just enough to ask for the metadata. // This will cause the current ObjectSpec to be updated as a side effect. final Grid unused = gridFacet.getGrid(); } if(titleString == null) { final String titleStr = objectAdapter.titleString(null); setTitle(titleStr); } WebMarkupContainer entityPageContainer = new WebMarkupContainer("entityPageContainer"); CssClassAppender.appendCssClassTo(entityPageContainer, objectSpec.getFullIdentifier().replace('.','-')); CssClassAppender.appendCssClassTo(entityPageContainer, objectSpec.getCorrespondingClass().getSimpleName()); CssClassFacet cssClassFacet = objectSpec.getFacet(CssClassFacet.class); if(cssClassFacet != null) { final String cssClass = cssClassFacet.cssClass(objectAdapter); CssClassAppender.appendCssClassTo(entityPageContainer, cssClass); } themeDiv.addOrReplace(entityPageContainer); addChildComponents(entityPageContainer, model); // bookmarks and breadcrumbs bookmarkPage(model); addBreadcrumb(model); addBookmarkedPages(entityPageContainer); } protected DeploymentCategory getDeploymentCategory() { return getIsisSessionFactory().getDeploymentCategory(); } }