/** * 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.components.widgets.breadcrumbs; import java.io.Serializable; import java.util.Collections; import java.util.List; import java.util.Map; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager; import org.apache.isis.core.metamodel.adapter.oid.OidMarshaller; import org.apache.isis.core.metamodel.adapter.oid.RootOid; import org.apache.isis.viewer.wicket.model.mementos.PageParameterNames; import org.apache.isis.viewer.wicket.model.models.EntityModel; public class BreadcrumbModel implements Serializable { private static final long serialVersionUID = 1L; private static final int MAX_SIZE = 5; private static final OidMarshaller OID_MARSHALLER = OidMarshaller.INSTANCE; private final Map<String, EntityModel> entityModelByOidStr = Maps.newHashMap(); private final Map<EntityModel, String> oidStrByEntityModel = Maps.newHashMap(); private final List<EntityModel> list = Lists.newArrayList(); public List<EntityModel> getList() { return Collections.unmodifiableList(list); } public void visited(final EntityModel entityModel) { // ignore view models if(entityModel.getTypeOfSpecification().isViewModel()) { return; } final String oidStr = oidStrFrom(entityModel); remove(oidStr); addToStart(oidStr, entityModel); trimTo(MAX_SIZE); } private String oidStrFrom(final EntityModel entityModel) { final PageParameters pageParameters = entityModel.getPageParametersWithoutUiHints(); return oidStrFrom(pageParameters); } private String oidStrFrom(final PageParameters pageParameters) { String oidStr = PageParameterNames.OBJECT_OID.getStringFrom(pageParameters); if(oidStr == null) { return null; } try { final RootOid unmarshal = OID_MARSHALLER.unmarshal(oidStr, RootOid.class); return unmarshal.enStringNoVersion(); } catch(Exception ex) { return null; } } private void addToStart(final String oidStr, final EntityModel entityModel) { entityModelByOidStr.put(oidStr, entityModel); oidStrByEntityModel.put(entityModel, oidStr); list.add(0, entityModel); } private void trimTo(final int size) { if(list.size() <= size) { return; } final List<EntityModel> modelsToRemove = list.subList(size, list.size()); for (final EntityModel model : modelsToRemove) { final String oidStr = oidStrByEntityModel.get(model); remove(oidStr, model); } } public String titleFor(final EntityModel model) { return model.getObjectAdapterMemento().getObjectAdapter(AdapterManager.ConcurrencyChecking.NO_CHECK, model.getPersistenceSession(), model.getSpecificationLoader()).titleString(null); } public EntityModel lookup(final String oidStr) { if(oidStr == null) { return null; } return entityModelByOidStr.get(oidStr); } public void detach() { for (EntityModel entityModel : list) { entityModel.detach(); } } public RootOid getId(final EntityModel choice) { try { final PageParameters pageParameters = choice.getPageParameters(); final String oidStr = PageParameterNames.OBJECT_OID.getStringFrom(pageParameters); return RootOid.deString(oidStr); } catch (Exception ex) { remove(choice); return null; } } void remove(final String rootOid) { final EntityModel existingModel = entityModelByOidStr.get(rootOid); if(existingModel != null) { remove(rootOid, existingModel); } } public void remove(final EntityModel entityModel) { final String oidStr = oidStrByEntityModel.get(entityModel); if(oidStr != null) { remove(oidStr, entityModel); } } private void remove(final String rootOid, final EntityModel model) { entityModelByOidStr.remove(rootOid); oidStrByEntityModel.remove(model); list.remove(model); } }