Package org.apache.isis.viewer.wicket.ui.components.appactions.cssmenu

Source Code of org.apache.isis.viewer.wicket.ui.components.appactions.cssmenu.AppActionsCssMenuFactory$LogicalServiceAction

/*
*  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.appactions.cssmenu;

import java.util.List;
import java.util.Map;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.wicket.Component;
import org.apache.wicket.model.IModel;
import org.apache.isis.applib.filter.Filters;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacet;
import org.apache.isis.core.metamodel.facets.all.named.NamedFacet;
import org.apache.isis.core.metamodel.spec.ActionType;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.Contributed;
import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
import org.apache.isis.core.metamodel.facets.actions.notinservicemenu.NotInServiceMenuFacet;
import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
import org.apache.isis.viewer.wicket.model.models.ApplicationActionsModel;
import org.apache.isis.viewer.wicket.ui.ComponentFactory;
import org.apache.isis.viewer.wicket.ui.ComponentFactoryAbstract;
import org.apache.isis.viewer.wicket.ui.ComponentType;
import org.apache.isis.viewer.wicket.ui.components.widgets.cssmenu.ActionLinkFactory;
import org.apache.isis.viewer.wicket.ui.components.widgets.cssmenu.ApplicationActionsPanel;
import org.apache.isis.viewer.wicket.ui.components.widgets.cssmenu.CssMenuBuilder;
import org.apache.isis.viewer.wicket.ui.components.widgets.cssmenu.CssMenuItem;
import org.apache.isis.viewer.wicket.ui.components.widgets.cssmenu.CssMenuItem.Builder;
import org.apache.isis.viewer.wicket.ui.components.widgets.cssmenu.CssMenuPanel;

/**
* {@link ComponentFactory} for a {@link CssMenuPanel} to represent the
* {@link ApplicationActionsModel application action}s.
*/
public class AppActionsCssMenuFactory extends ComponentFactoryAbstract {

    private final static long serialVersionUID = 1L;

   
    static class LogicalServiceAction {
        private final String serviceName;
        private final ObjectAdapter serviceAdapter;
        private final ObjectAdapterMemento serviceAdapterMemento;
        private final ObjectAction objectAction;
       
        LogicalServiceAction(final String serviceName, final ObjectAdapter serviceAdapter, final ObjectAction objectAction) {
            this.serviceName = serviceName;
            this.serviceAdapter = serviceAdapter;
            this.serviceAdapterMemento = ObjectAdapterMemento.createOrNull(serviceAdapter);
            this.objectAction = objectAction;
        }
        @Override
        public String toString() {
            return serviceName + " ~ " + objectAction.getIdentifier().toFullIdentityString();
        }
    }

    private final static ActionLinkFactory cssMenuLinkFactory = new AppActionsCssMenuLinkFactory();

    public AppActionsCssMenuFactory() {
        super(ComponentType.APPLICATION_ACTIONS, CssMenuPanel.class);
    }

    /**
     * Generic, so applies to all models.
     */
    @Override
    protected ApplicationAdvice appliesTo(final IModel<?> model) {
        return appliesIf(model instanceof ApplicationActionsModel);
    }

    @Override
    public Component createComponent(final String id, final IModel<?> model) {
        final ApplicationActionsModel applicationActionsModel = (ApplicationActionsModel) model;
        return new ApplicationActionsPanel(id, buildMenu(applicationActionsModel));
    }

    private List<CssMenuItem> buildMenu(final ApplicationActionsModel appActionsModel) {

        final List<ObjectAdapter> serviceAdapters = appActionsModel.getObject();

        final List<LogicalServiceAction> serviceActions = Lists.newArrayList();
        for (final ObjectAdapter serviceAdapter : serviceAdapters) {
            collateServiceActions(serviceAdapter, ActionType.USER, serviceActions);
            collateServiceActions(serviceAdapter, ActionType.PROTOTYPE, serviceActions);
        }
       
        final List<String> serviceNamesInOrder = serviceNamesInOrder(serviceAdapters, serviceActions);
        final Map<String, List<LogicalServiceAction>> serviceActionsByName = groupByServiceName(serviceActions);
       
        // prune any service names that have no service actions
        serviceNamesInOrder.retainAll(serviceActionsByName.keySet());
       
        return buildMenuItems(serviceNamesInOrder, serviceActionsByName, new CssMenuBuilder.CssMenuContext(cssMenuLinkFactory, appActionsModel.getActionPromptProvider()));
    }

    /**
     * Builds a hierarchy of {@link CssMenuItem}s, following the provided map of {@link LogicalServiceAction}s (keyed by their service Name).
     */
    private List<CssMenuItem> buildMenuItems(
            final List<String> serviceNamesInOrder,
            final Map<String, List<LogicalServiceAction>> serviceActionsByName,
            final CssMenuBuilder.CssMenuContext cssMenuContext) {
       
        final List<CssMenuItem> menuItems = Lists.newArrayList();
        for (String serviceName : serviceNamesInOrder) {
            final CssMenuItem serviceMenuItem = CssMenuItem.newMenuItem(serviceName).build();
            final List<LogicalServiceAction> serviceActionsForName = serviceActionsByName.get(serviceName);
            for (LogicalServiceAction logicalServiceAction : serviceActionsForName) {
                final ObjectAdapter serviceAdapter = logicalServiceAction.serviceAdapter;
                final ObjectSpecification serviceSpec = serviceAdapter.getSpecification();
                if (serviceSpec.isHidden()) {
                    continue;
                }
                final ObjectAdapterMemento serviceAdapterMemento = logicalServiceAction.serviceAdapterMemento;
                final ObjectAction objectAction = logicalServiceAction.objectAction;
                final Builder subMenuItemBuilder = serviceMenuItem.newSubMenuItem(serviceAdapterMemento, objectAction, cssMenuContext);
                if (subMenuItemBuilder == null) {
                    // not visible
                    continue;
                }
                subMenuItemBuilder.build();
            }
            if (serviceMenuItem.hasSubMenuItems()) {
                menuItems.add(serviceMenuItem);
            }
        }
        return menuItems;
    }


    // //////////////////////////////////////

    /**
     * Spin through all object actions of the service adapter, and add to the provided List of {@link LogicalServiceAction}s.
     */
    private static void collateServiceActions(final ObjectAdapter serviceAdapter, ActionType actionType, List<LogicalServiceAction> serviceActions) {
        final ObjectSpecification serviceSpec = serviceAdapter.getSpecification();
        for (final ObjectAction objectAction : serviceSpec.getObjectActions(
                actionType, Contributed.INCLUDED, Filters.<ObjectAction>any())) {
            // skip if annotated to not be included in repository menu
            if (objectAction.getFacet(NotInServiceMenuFacet.class) != null) {
                continue;
            }

            final MemberOrderFacet memberOrderFacet = objectAction.getFacet(MemberOrderFacet.class);
            String serviceName = memberOrderFacet != null? memberOrderFacet.name(): null;
            if(Strings.isNullOrEmpty(serviceName)){
                serviceName = serviceSpec.getFacet(NamedFacet.class).value();
            }
            serviceActions.add(new LogicalServiceAction(serviceName, serviceAdapter, objectAction));
        }
    }

    /**
     * The unique service names, as they appear in order of the provided List of {@link LogicalServiceAction}s.
     * @param serviceAdapters
     */
    private List<String> serviceNamesInOrder(
            final List<ObjectAdapter> serviceAdapters, final List<LogicalServiceAction> serviceActions) {
        final List<String> serviceNameOrder = Lists.newArrayList();

        // first, order as defined in isis.properties
        for (ObjectAdapter serviceAdapter : serviceAdapters) {
            final ObjectSpecification serviceSpec = serviceAdapter.getSpecification();
            String serviceName = serviceSpec.getFacet(NamedFacet.class).value();
            serviceNameOrder.add(serviceName);
        }
        // then, any other services (eg due to misspellings, at the end)
        for (LogicalServiceAction serviceAction : serviceActions) {
            if(!serviceNameOrder.contains(serviceAction.serviceName)) {
                serviceNameOrder.add(serviceAction.serviceName);
            }
        }
        return serviceNameOrder;
    }

    /**
     * Group the provided {@link LogicalServiceAction}s by their service name.
     */
    private static Map<String, List<LogicalServiceAction>> groupByServiceName(final List<LogicalServiceAction> serviceActions) {
        final Map<String, List<LogicalServiceAction>> serviceActionsByName = Maps.newTreeMap();
       
        // map available services
        for (LogicalServiceAction serviceAction : serviceActions) {
            List<LogicalServiceAction> serviceActionsForName = serviceActionsByName.get(serviceAction.serviceName);
            if(serviceActionsForName == null) {
                serviceActionsForName = Lists.newArrayList();
                serviceActionsByName.put(serviceAction.serviceName, serviceActionsForName);
            }
            serviceActionsForName.add(serviceAction);
        }
       
        return serviceActionsByName;
    }



}
TOP

Related Classes of org.apache.isis.viewer.wicket.ui.components.appactions.cssmenu.AppActionsCssMenuFactory$LogicalServiceAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.