Package org.apache.isis.core.metamodel.util

Source Code of org.apache.isis.core.metamodel.util.Dump

/*
*  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.core.metamodel.util;

import java.util.List;

import org.apache.isis.core.commons.authentication.AuthenticationSession;
import org.apache.isis.core.commons.debug.DebugBuilder;
import org.apache.isis.core.commons.debug.DebugString;
import org.apache.isis.core.commons.debug.DebugUtils;
import org.apache.isis.core.commons.debug.DebuggableWithTitle;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.facetapi.Facet;
import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacetUtils;
import org.apache.isis.core.metamodel.facets.object.bounded.BoundedFacetUtils;
import org.apache.isis.core.metamodel.facets.object.cached.CachedFacetUtils;
import org.apache.isis.core.metamodel.facets.object.immutable.ImmutableFacetUtils;
import org.apache.isis.core.metamodel.spec.ActionType;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationFilters;

import com.google.common.collect.Lists;

public final class Dump {

    private static DebugBuilder debugBuilder;

    private Dump() {
    }

    // /////////////////////////////////////////////////////////////////////
    // specification
    // /////////////////////////////////////////////////////////////////////

    /**
     * @see #specification(ObjectAdapter, DebugBuilder)
     * @see #specification(ObjectSpecification, DebugBuilder)
     */
    public static String specification(final ObjectAdapter adapter) {
        final DebugBuilder debugBuilder = new DebugString();
        specification(adapter, debugBuilder);
        return debugBuilder.toString();
    }

    /**
     * Convenience overload of {@link #specification(ObjectSpecification, DebugBuilder)} that takes the
     * {@link ObjectSpecification} ( {@link ObjectAdapter#getSpecification()}) of the provided {@link ObjectAdapter}
     *
     * @see #specification(ObjectAdapter)
     * @see #specification(ObjectSpecification, DebugBuilder)
     */
    public static void specification(final ObjectAdapter adapter, final DebugBuilder debugBuilder) {
        final ObjectSpecification specification = adapter.getSpecification();
        specification(specification, debugBuilder);
    }

    public static void specification(final ObjectSpecification specification, final DebugBuilder debugBuilder) {
        try {
            debugBuilder.appendTitle(specification.getClass().getName());
            debugBuilder.appendAsHexln("Hash code", specification.hashCode());
            debugBuilder.appendln("ID", specification.getIdentifier());
            debugBuilder.appendln("Full Name", specification.getFullIdentifier());
            debugBuilder.appendln("Short Name", specification.getShortIdentifier());
            debugBuilder.appendln("Singular Name", specification.getSingularName());
            debugBuilder.appendln("Plural Name", specification.getPluralName());
            debugBuilder.appendln("Description", specification.getDescription());
            debugBuilder.blankLine();
            debugBuilder.appendln("Features", featureList(specification));
            debugBuilder.appendln("Type", specification.isCollection() ? "Collection" : "Object");
            if (specification.superclass() != null) {
                debugBuilder.appendln("Superclass", specification.superclass().getFullIdentifier());
            }
            debugBuilder.appendln("Interfaces", specificationNames(specification.interfaces()));
            debugBuilder.appendln("Subclasses", specificationNames(specification.subclasses()));
            debugBuilder.blankLine();
            debugBuilder.appendln("Service", specification.isService());
            debugBuilder.appendln("Encodable", specification.isEncodeable());
            debugBuilder.appendln("Parseable", specification.isParseable());
            debugBuilder.appendln("Aggregated", specification.isValueOrIsAggregated());
        } catch (final RuntimeException e) {
            debugBuilder.appendException(e);
        }

        if (specification instanceof DebuggableWithTitle) {
            ((DebuggableWithTitle) specification).debugData(debugBuilder);
        }

        debugBuilder.blankLine();

        debugBuilder.appendln("Facets");
        final Class<? extends Facet>[] facetTypes = specification.getFacetTypes();
        debugBuilder.indent();
        if (facetTypes.length == 0) {
            debugBuilder.appendln("none");
        } else {
            for (final Class<? extends Facet> type : facetTypes) {
                final Facet facet = specification.getFacet(type);
                debugBuilder.appendln(facet.toString());
            }
        }
        debugBuilder.unindent();
        debugBuilder.blankLine();

        debugBuilder.appendln("Fields");
        debugBuilder.indent();
        specificationFields(specification, debugBuilder);
        debugBuilder.unindent();

        debugBuilder.appendln("Object Actions");
        debugBuilder.indent();
        specificationActionMethods(specification, debugBuilder);
        debugBuilder.unindent();

        debugBuilder.appendln("Related Service Actions");
        debugBuilder.indent();
        specificationServiceMethods(specification, debugBuilder);
        debugBuilder.unindent();
    }

    private static String[] specificationNames(final List<ObjectSpecification> specifications) {
        final String[] names = new String[specifications.size()];
        for (int i = 0; i < names.length; i++) {
            names[i] = specifications.get(i).getFullIdentifier();
        }
        return names;
    }

    private static void specificationActionMethods(final ObjectSpecification specification,
        final DebugBuilder debugBuilder) {
        try {
            final List<ObjectAction> userActions = specification.getObjectActions(ActionType.USER);
            final List<ObjectAction> explActions = specification.getObjectActions(ActionType.EXPLORATION);
            final List<ObjectAction> prototypeActions = specification.getObjectActions(ActionType.PROTOTYPE);
            final List<ObjectAction> debActions = specification.getObjectActions(ActionType.DEBUG);
            specificationMethods(userActions, explActions, prototypeActions, debActions, debugBuilder);
        } catch (final RuntimeException e) {
            debugBuilder.appendException(e);
        }
    }

    private static void specificationServiceMethods(final ObjectSpecification specification,
        final DebugBuilder debugBuilder) {
        try {
            final List<ObjectAction> userActions = specification.getServiceActionsReturning(ActionType.USER);
            final List<ObjectAction> explActions = specification.getServiceActionsReturning(ActionType.EXPLORATION);
            final List<ObjectAction> prototypeActions = specification.getServiceActionsReturning(ActionType.PROTOTYPE);
            final List<ObjectAction> debActions = specification.getServiceActionsReturning(ActionType.DEBUG);
            specificationMethods(userActions, explActions, prototypeActions, debActions, debugBuilder);
        } catch (final RuntimeException e) {
            debugBuilder.appendException(e);
        }
    }

    private static void specificationFields(final ObjectSpecification specification, final DebugBuilder debugBuilder) {
        final List<ObjectAssociation> fields = specification.getAssociations();
        debugBuilder.appendln("All");
        debugBuilder.indent();
        for (int i = 0; i < fields.size(); i++) {
            debugBuilder.appendln((i + 1) + "." + fields.get(i).getId());
        }
        debugBuilder.unindent();

        final List<ObjectAssociation> fields2 =
            specification.getAssociations(ObjectAssociationFilters.STATICALLY_VISIBLE_ASSOCIATIONS);
        debugBuilder.appendln("Static");
        debugBuilder.indent();
        for (int i = 0; i < fields2.size(); i++) {
            debugBuilder.appendln((i + 1) + "." + fields2.get(i).getId());
        }
        debugBuilder.unindent();
        debugBuilder.appendln();

        try {
            if (fields.size() == 0) {
                debugBuilder.appendln("none");
            } else {
                for (int i = 0; i < fields.size(); i++) {

                    final ObjectAssociation field = fields.get(i);
                    debugBuilder.appendln((i + 1) + "." + field.getId() + "  (" + field.getClass().getName() + ")");

                    debugBuilder.indent();
                    final String description = field.getDescription();
                    if (description != null && !description.equals("")) {
                        debugBuilder.appendln("Description", description);
                    }
                    final String help = field.getHelp();
                    if (help != null && !help.equals("")) {
                        debugBuilder.appendln("Help", help.substring(0, Math.min(30, help.length()))
                            + (help.length() > 30 ? "..." : ""));
                    }

                    debugBuilder.appendln("ID", field.getIdentifier());
                    debugBuilder.appendln("Short ID", field.getId());
                    debugBuilder.appendln("Name", field.getName());
                    final String type =
                        field.isOneToManyAssociation() ? "Collection" : field.isOneToOneAssociation() ? "Object"
                            : "Unknown";
                    debugBuilder.appendln("Type", type);
                    debugBuilder.appendln("Has identity", !field.getSpecification().isCollectionOrIsAggregated());
                    debugBuilder.appendln("Spec", field.getSpecification().getFullIdentifier());

                    debugBuilder
                        .appendln("Flags", (field.isAlwaysHidden() ? "" : "Visible ")
                            + (field.isNotPersisted() ? "Not Persisted " : " ")
                            + (field.isMandatory() ? "Mandatory " : ""));

                    final Class<? extends Facet>[] facets = field.getFacetTypes();
                    if (facets.length > 0) {
                        debugBuilder.appendln("Facets");
                        debugBuilder.indent();
                        boolean none = true;
                        for (final Class<? extends Facet> facet : facets) {
                            debugBuilder.appendln(field.getFacet(facet).toString());
                            none = false;
                        }
                        if (none) {
                            debugBuilder.appendln("none");
                        }
                        debugBuilder.unindent();
                    }

                    debugBuilder.appendln(field.debugData());

                    debugBuilder.unindent();
                }
            }
        } catch (final RuntimeException e) {
            debugBuilder.appendException(e);
        }

    }

    private static void specificationMethods(final List<ObjectAction> userActions,
        final List<ObjectAction> explActions, final List<ObjectAction> prototypeActions,
        final List<ObjectAction> debugActions, final DebugBuilder debugBuilder) {
        if (userActions.size() == 0 && explActions.size() == 0 && prototypeActions.size() == 0
            && debugActions.size() == 0) {
            debugBuilder.appendln("no actions...");
        } else {
            appendActionDetails(debugBuilder, "User actions", userActions);
            appendActionDetails(debugBuilder, "Exploration actions", explActions);
            appendActionDetails(debugBuilder, "Prototype actions", prototypeActions);
            appendActionDetails(debugBuilder, "Debug actions", debugActions);
        }
    }

    private static void appendActionDetails(final DebugBuilder debug, final String desc,
        final List<ObjectAction> actions) {
        debug.appendln(desc);
        debug.indent();
        for (int i = 0; i < actions.size(); i++) {
            actionDetails(actions.get(i), 8, i, debug);
        }
        debug.unindent();
    }

    private static void actionDetails(final ObjectAction objectAction, final int indent, final int count,
        final DebugBuilder debugBuilder) {
        debugBuilder
            .appendln((count + 1) + "." + objectAction.getId() + " (" + objectAction.getClass().getName() + ")");
        debugBuilder.indent();
        final int newIndent = indent + 4;
        try {
            final List<ObjectAction> debActions = objectAction.getActions();
            if (debActions.size() > 0) {
                for (int i = 0; i < debActions.size(); i++) {
                    actionDetails(debActions.get(i), newIndent, i, debugBuilder);
                }

            } else {
                if (objectAction.getDescription() != null && !objectAction.getDescription().equals("")) {
                    debugBuilder.appendln("Description", objectAction.getDescription());
                }
                debugBuilder.appendln("ID", objectAction.getId());
                // debug.appendln(12, "Returns", f.getReturnType() == null ? "Nothing" :
                // f.getReturnType().getFullName());

                debugBuilder.appendln(objectAction.debugData());
                debugBuilder.appendln("Target", objectAction.getTarget());
                debugBuilder.appendln("On type", objectAction.getOnType());

                final Class<? extends Facet>[] facets = objectAction.getFacetTypes();
                if (facets.length > 0) {
                    debugBuilder.appendln("Facets");
                    debugBuilder.indent();
                    for (final Class<? extends Facet> facet : facets) {
                        debugBuilder.appendln(objectAction.getFacet(facet).toString());
                    }
                    debugBuilder.unindent();
                }

                final ObjectSpecification returnType = objectAction.getReturnType();
                debugBuilder.appendln("Returns", returnType == null ? "VOID" : returnType.toString());

                final List<ObjectActionParameter> parameters = objectAction.getParameters();
                if (parameters.size() == 0) {
                    debugBuilder.appendln("Parameters", "none");
                } else {
                    debugBuilder.appendln("Parameters");
                    debugBuilder.indent();
                    final List<ObjectActionParameter> p = objectAction.getParameters();
                    for (int j = 0; j < parameters.size(); j++) {
                        debugBuilder.append(p.get(j).getName());
                        debugBuilder.append(" (");
                        debugBuilder.append(parameters.get(j).getSpecification().getFullIdentifier());
                        debugBuilder.appendln(")");
                        debugBuilder.indent();
                        final Class<? extends Facet>[] parameterFacets = p.get(j).getFacetTypes();
                        for (final Class<? extends Facet> parameterFacet : parameterFacets) {
                            debugBuilder.appendln(p.get(j).getFacet(parameterFacet).toString());
                        }
                        debugBuilder.unindent();
                    }
                    debugBuilder.unindent();
                }
            }
        } catch (final RuntimeException e) {
            debugBuilder.appendException(e);
        }

        debugBuilder.unindent();
    }

    private static String featureList(final ObjectSpecification specification) {
        final StringBuilder str = new StringBuilder();
        if (specification.isAbstract()) {
            str.append("Abstract ");
        }
        if (BoundedFacetUtils.isBoundedSet(specification)) {
            str.append("Bounded ");
        }
        if (CachedFacetUtils.isCached(specification)) {
            str.append("Cached ");
        }
        if (ImmutableFacetUtils.isAlwaysImmutable(specification)) {
            str.append("Immutable (always) ");
        }
        if (ImmutableFacetUtils.isImmutableOncePersisted(specification)) {
            str.append("Immutable (once persisted) ");
        }
        if (specification.isService()) {
            str.append("Service ");
        }
        return str.toString();
    }

    // /////////////////////////////////////////////////////////////////////
    // adapter
    // /////////////////////////////////////////////////////////////////////

    /**
     * @see #adapter(ObjectAdapter, DebugBuilder)
     */
    public static String adapter(final ObjectAdapter adapter) {
        final DebugBuilder debugBuilder = new DebugString();
        adapter(adapter, debugBuilder);
        return debugBuilder.toString();
    }

    /**
     * @see #adapter(ObjectAdapter)
     */
    public static void adapter(final ObjectAdapter adapter, final DebugBuilder builder) {
        try {
            builder.appendln("Adapter", adapter.getClass().getName());
            builder.appendln("Class", adapter.getObject() == null ? "none" : adapter.getObject().getClass().getName());
            builder.appendAsHexln("Hash", adapter.hashCode());
            builder.appendln("Object", adapter.getObject());
            builder.appendln("Title", adapter.titleString());
            builder.appendln("Specification", adapter.getSpecification().getFullIdentifier());

            builder.appendln();

            builder.appendln("Icon", adapter.getIconName());
            builder.appendln("OID", adapter.getOid());
            builder.appendln("State", adapter.getResolveState());
            builder.appendln("Version", adapter.getVersion());

        } catch (final RuntimeException e) {
            builder.appendException(e);
        }

    }

    // /////////////////////////////////////////////////////////////////////
    // graph
    // /////////////////////////////////////////////////////////////////////

    /**
     * Creates an ascii object graph diagram for the specified object, up to three levels deep.
     *
     * @see #graph(ObjectAdapter, AuthenticationSession, DebugBuilder)
     */
    public static String graph(final ObjectAdapter adapter, final AuthenticationSession authenticationSession) {
        debugBuilder = new DebugString();
        graph(adapter, authenticationSession, debugBuilder);
        return debugBuilder.toString();
    }

    /**
     * As {@link #graph(ObjectAdapter, AuthenticationSession)}, but appending to the provided {@link DebugBuilder}.
     *
     * @see #graph(ObjectAdapter, AuthenticationSession)
     */
    public static void graph(final ObjectAdapter object, final AuthenticationSession authenticationSession,
        final DebugBuilder debugBuilder) {
        simpleObject(object, debugBuilder);
        debugBuilder.appendln();
        debugBuilder.append(object);
        graph(object, 0, Lists.<ObjectAdapter> newArrayList(), authenticationSession, debugBuilder);
    }

    private static void simpleObject(final ObjectAdapter collectionAdapter, final DebugBuilder debugBuilder) {
        debugBuilder.appendln(collectionAdapter.titleString());
        final ObjectSpecification objectSpec = collectionAdapter.getSpecification();
        if (objectSpec.isCollection()) {
            final CollectionFacet facet = CollectionFacetUtils.getCollectionFacetFromSpec(collectionAdapter);
            int i = 1;
            for (final ObjectAdapter element : facet.collection(collectionAdapter)) {
                debugBuilder.appendln(i++ + " " + element.titleString());
            }
        } else {
            // object is a regular Object
            try {
                final List<ObjectAssociation> fields = objectSpec.getAssociations();
                for (int i = 0; i < fields.size(); i++) {
                    final ObjectAssociation field = fields.get(i);
                    final ObjectAdapter obj = field.get(collectionAdapter);

                    final String name = field.getId();
                    if (obj == null) {
                        debugBuilder.appendln(name, "null");
                    } else {
                        debugBuilder.appendln(name, obj.titleString());
                    }
                }
            } catch (final RuntimeException e) {
                debugBuilder.appendException(e);
            }
        }
    }

    private static void collectionGraph(final ObjectAdapter collectionAdapter, final int level,
        final List<ObjectAdapter> ignoreAdapters, final AuthenticationSession authenticationSession,
        final DebugBuilder debugBuilder) {

        if (ignoreAdapters.contains(collectionAdapter)) {
            debugBuilder.append("*\n");
        } else {
            ignoreAdapters.add(collectionAdapter);
            final CollectionFacet facet = CollectionFacetUtils.getCollectionFacetFromSpec(collectionAdapter);
            for (final ObjectAdapter element : facet.collection(collectionAdapter)) {
                graphIndent(level, debugBuilder);
                debugBuilder.append(element);
                if (ignoreAdapters.contains(element)) {
                    debugBuilder.append("*\n");
                } else {
                    graph(element, level + 1, ignoreAdapters, authenticationSession, debugBuilder);
                }
            }
        }
    }

    private static void graph(final ObjectAdapter adapter, final int level, final List<ObjectAdapter> ignoreAdapters,
        final AuthenticationSession authenticationSession, final DebugBuilder debugBuilder) {
        if (level > 3) {
            debugBuilder.appendln("..."); // only go 3 levels?
        } else {
            debugBuilder.append("\n");
            if (adapter.getSpecification().isCollection()) {
                collectionGraph(adapter, level, ignoreAdapters, authenticationSession, debugBuilder);
            } else if (adapter.getSpecification().isNotCollection()) {
                objectGraph(adapter, level, ignoreAdapters, debugBuilder, authenticationSession);
            } else {
                debugBuilder.append("??? " + adapter);
            }
        }
    }

    private static void graphIndent(final int level, final DebugBuilder debugBuilder) {
        for (int indent = 0; indent < level; indent++) {
            debugBuilder.append(DebugUtils.indentString(4) + "|");
        }
        debugBuilder.append(DebugUtils.indentString(4) + "+--");
    }

    private static void objectGraph(final ObjectAdapter adapter, final int level,
        final List<ObjectAdapter> ignoreAdapters, final DebugBuilder s,
        final AuthenticationSession authenticationSession) {
        ignoreAdapters.add(adapter);

        try {
            // work through all its fields
            final List<ObjectAssociation> fields = adapter.getSpecification().getAssociations();
            for (int i = 0; i < fields.size(); i++) {
                final ObjectAssociation field = fields.get(i);
                final ObjectAdapter obj = field.get(adapter);
                final String name = field.getId();
                graphIndent(level, s);

                if (field.isVisible(authenticationSession, adapter).isVetoed()) {
                    s.append(name + ": (not visible)");
                    s.append("\n");
                } else {
                    if (obj == null) {
                        s.append(name + ": null\n");
                        /*
                         * } else if (obj.getSpecification().isParseable()) { s.append(name + ": " + obj.titleString());
                         * s.append("\n");
                         */} else {
                        if (ignoreAdapters.contains(obj)) {
                            s.append(name + ": " + obj + "*\n");
                        } else {
                            s.append(name + ": " + obj);
                            graph(obj, level + 1, ignoreAdapters, authenticationSession, s);

                        }
                    }
                }
            }
        } catch (final RuntimeException e) {
            s.appendException(e);
        }
    }

}
TOP

Related Classes of org.apache.isis.core.metamodel.util.Dump

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.