All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nakedobjects.plugins.remoting.shared.ServerFacadeLogger Maven / Gradle / Ivy

package org.nakedobjects.plugins.remoting.shared;

import java.util.Properties;
import java.util.Vector;

import org.nakedobjects.metamodel.adapter.oid.Oid;
import org.nakedobjects.metamodel.adapter.version.Version;
import org.nakedobjects.metamodel.authentication.AuthenticationSession;
import org.nakedobjects.metamodel.commons.logging.Logger;
import org.nakedobjects.metamodel.spec.NakedObjectSpecification;
import org.nakedobjects.metamodel.spec.feature.NakedObjectAssociation;
import org.nakedobjects.plugins.remoting.shared.data.ClientActionResultData;
import org.nakedobjects.plugins.remoting.shared.data.CollectionData;
import org.nakedobjects.plugins.remoting.shared.data.CriteriaData;
import org.nakedobjects.plugins.remoting.shared.data.Data;
import org.nakedobjects.plugins.remoting.shared.data.EncodeableObjectData;
import org.nakedobjects.plugins.remoting.shared.data.IdentityData;
import org.nakedobjects.plugins.remoting.shared.data.NullData;
import org.nakedobjects.plugins.remoting.shared.data.ObjectData;
import org.nakedobjects.plugins.remoting.shared.data.ReferenceData;
import org.nakedobjects.plugins.remoting.shared.data.ServerActionResultData;
import org.nakedobjects.plugins.remoting.shared.transaction.ClientTransactionEvent;
import org.nakedobjects.runtime.context.NakedObjectsContext;


/**
 * previously called DistributionLogger.
 */
public class ServerFacadeLogger extends Logger implements ServerFacade {
    
    private static String PADDING = "      ";
    
    private final ObjectEncoder encoder;
    private final ServerFacade decorated;

    public ServerFacadeLogger(final ObjectEncoder encoder, final ServerFacade decorated, final String fileName) {
        super(fileName, false);
        this.encoder = encoder;
        this.decorated = decorated;
    }

    public ServerFacadeLogger(final ObjectEncoder encoder, final ServerFacade decorated) {
        this(encoder, decorated, null);
    }

    

    @Override
    protected Class getDecoratedClass() {
        return decorated.getClass();
    }

    //////////////////////////////////////////////////////////////////
    // init, shutdown
    //////////////////////////////////////////////////////////////////

    public void init() {
        decorated.init();
    }

    public void shutdown() {
        decorated.shutdown();
    }
    

    
    //////////////////////////////////////////////////////////////////
    // authentication, authorization
    //////////////////////////////////////////////////////////////////
    
    public AuthenticationSession authenticate(final String data) {
        log("authenticate");
        return decorated.authenticate(data);
    }

    public boolean authoriseUsability(final AuthenticationSession session, final String data) {
        log("authoriseUsability");
        return decorated.authoriseUsability(session, data);
    }

    public boolean authoriseVisibility(final AuthenticationSession session, final String data) {
        log("authoriseVisibility");
        return decorated.authoriseVisibility(session, data);
    }

    //////////////////////////////////////////////////////////////////
    // session
    //////////////////////////////////////////////////////////////////

    public void closeSession(final AuthenticationSession session) {
        log("close session " + session);
        decorated.closeSession(session);
    }


    //////////////////////////////////////////////////////////////////
    // setAssociation, setValue, clearAssociation, clearValue
    //////////////////////////////////////////////////////////////////

    public ObjectData[] setAssociation(
            final AuthenticationSession session,
            final String fieldIdentifier,
            final IdentityData target,
            final IdentityData associate) {
        log("set association " + fieldIdentifier + indentedNewLine() + "target: " + dump(target) + indentedNewLine()
                + "associate: " + dump(associate));
        final ObjectData[] changes = decorated.setAssociation(session, fieldIdentifier, target, associate);
        log("  <-- changes: " + dump(changes));
        return changes;
    }

    public ObjectData[] setValue(
            final AuthenticationSession session,
            final String fieldIdentifier,
            final IdentityData target,
            final EncodeableObjectData value) {
        log("set value " + fieldIdentifier + indentedNewLine() + "target: " + dump(target) + indentedNewLine() + "value: "
                + value);
        final ObjectData[] changes = decorated.setValue(session, fieldIdentifier, target, value);
        log("  <-- changes: " + dump(changes));
        return changes;
    }

    public ObjectData[] clearAssociation(
            final AuthenticationSession session,
            final String fieldIdentifier,
            final IdentityData target,
            final IdentityData associate) {
        log("clear association " + fieldIdentifier + indentedNewLine() + "target: " + dump(target) + indentedNewLine()
                + "associate: " + dump(associate));
        final ObjectData[] changes = decorated.clearAssociation(session, fieldIdentifier, target, associate);
        log("  <-- changes: " + dump(changes));
        return changes;
    }

    public ObjectData[] clearValue(final AuthenticationSession session, final String fieldIdentifier, final IdentityData target) {
        log("clear value " + fieldIdentifier + indentedNewLine() + "target: " + dump(target));
        final ObjectData[] changes = decorated.clearValue(session, fieldIdentifier, target);
        log("  <-- changes: " + dump(changes));
        return changes;
    }

    //////////////////////////////////////////////////////////////////
    // executeClientAction, executeServerAction 
    //////////////////////////////////////////////////////////////////

    public ServerActionResultData executeServerAction(
            final AuthenticationSession session,
            final String actionType,
            final String actionIdentifier,
            final ReferenceData target,
            final Data[] parameters) {
        log("execute action " + actionIdentifier + "/" + actionType + indentedNewLine() + "target: " + dump(target)
                + indentedNewLine() + "parameters: " + dump(parameters));
        ServerActionResultData result;
        try {
            result = decorated.executeServerAction(session, actionType, actionIdentifier, target, parameters);
            log("  <-- returns: " + dump(result.getReturn()));
            log("  <-- persisted target: " + dump(result.getPersistedTarget()));
            log("  <-- persisted parameters: " + dump(result.getPersistedParameters()));
            log("  <-- updates: " + dump(result.getUpdates()));
            log("  <-- disposed: " + dump(result.getDisposed()));
        } catch (final RuntimeException e) {
            log("  <-- exception: " + e.getClass().getName() + " " + e.getMessage());
            throw e;
        }
        return result;
    }

    public ClientActionResultData executeClientAction(final AuthenticationSession session, final ReferenceData[] data, final int[] types) {
        Vector complete = new Vector();
        StringBuffer str = new StringBuffer();
        for (int i = 0; i < data.length; i++) {
            str.append(indentedNewLine());
            str.append("[");
            str.append(i + 1);
            str.append("] ");
            switch (types[i]) {
            case ClientTransactionEvent.ADD:
                str.append("persisted: ");
                break;
            case ClientTransactionEvent.CHANGE:
                str.append("changed: ");
                break;
            case ClientTransactionEvent.DELETE:
                str.append("deleted: ");
                break;
            }
            dump(str, data[i], 3, complete);
        }
        log("execute client action " + str);

        /*
         * + indentedNewLine() + "changed: " + dump(changed, complete) + indentedNewLine() + "deleted: " +
         * dump(deleted, complete));
         */
        final ClientActionResultData results = decorated.executeClientAction(session, data, types);

        complete = new Vector();
        str = new StringBuffer();
        final ReferenceData[] persistedUpdates = results.getPersisted();
        final Version[] changedVersions = results.getChanged();
        for (int i = 0; i < persistedUpdates.length; i++) {
            str.append(indentedNewLine());
            str.append("[");
            str.append(i + 1);
            str.append("] ");
            switch (types[i]) {
            case ClientTransactionEvent.ADD:
                str.append("persisted: ");
                dump(str, persistedUpdates[i], 3, complete);
                break;
            case ClientTransactionEvent.CHANGE:
                str.append("changed: ");
                str.append(changedVersions[i]);
                break;
            }
        }
        log(" <--- execute client action results" + str);
        /*
         * log(" <-- persisted: " + dump(results.getPersisted())); log(" <-- changed: " +
         * dump(results.getChanged()));
         */
        return results;
    }

    
    //////////////////////////////////////////////////////////////////
    // getObject, resolveXxx 
    //////////////////////////////////////////////////////////////////

    public ObjectData getObject(final AuthenticationSession session, final Oid oid, final String specificationName) {
        log("get object " + oid);
        final ObjectData data = decorated.getObject(null, oid, specificationName);
        log(" <-- data: " + data);
        return data;
    }

    public Data resolveField(final AuthenticationSession session, final IdentityData data, final String name) {
        log("resolve field " + name + " - " + dump(data));
        final Data result = decorated.resolveField(session, data, name);
        log(" <-- data: " + dump(result));
        return result;
    }

    public ObjectData resolveImmediately(final AuthenticationSession session, final IdentityData target) {
        log("resolve immediately" + dump(target));
        final ObjectData result = decorated.resolveImmediately(session, target);
        log("  <-- data: " + dump(result));
        return result;

    }


    //////////////////////////////////////////////////////////////////
    // findInstances, hasInstances 
    //////////////////////////////////////////////////////////////////

    public ObjectData[] findInstances(final AuthenticationSession session, final CriteriaData criteria) {
        log("find instances " + criteria);
        final ObjectData[] instances = decorated.findInstances(session, criteria);
        log(" <-- instances: " + dump(instances));
        return instances;
    }

    public boolean hasInstances(final AuthenticationSession session, final String fullName) {
        log("has instances " + fullName);
        final boolean hasInstances = decorated.hasInstances(session, fullName);
        log(" <-- instances: " + (hasInstances ? "yes" : "no"));
        return hasInstances;
    }

    //////////////////////////////////////////////////////////////////
    // getProperties 
    //////////////////////////////////////////////////////////////////

    public Properties getProperties() {
        log("get properties");
        final Properties properties = decorated.getProperties();
        log(" <-- data: " + properties);
        return properties;
    }

    //////////////////////////////////////////////////////////////////
    // services 
    //////////////////////////////////////////////////////////////////

    public IdentityData oidForService(final AuthenticationSession session, final String id) {
        log("oid for resource " + id);
        final IdentityData result = decorated.oidForService(session, id);
        log(" <-- data: " + dump(result));
        return result;
    }

    
    //////////////////////////////////////////////////////////////////
    // Helpers 
    //////////////////////////////////////////////////////////////////

    private String dump(final Data data) {
        final StringBuffer str = new StringBuffer();
        dump(str, data, 1, new Vector());
        return str.toString();
    }

    private String dump(final Data[] data) {
        final StringBuffer str = new StringBuffer();
        for (int i = 0; i < data.length; i++) {
            str.append("\n    [");
            str.append(i + 1);
            str.append("] ");
            dump(str, data[i], 3, new Vector());
        }
        return str.toString();
    }

    private void dump(final StringBuffer str, final Data data, final int indent, final Vector complete) {
        if (data == null) {
            str.append("null");
        } else if (data instanceof NullData) {
            str.append("NULL (NullData object)");
        } else if (data instanceof EncodeableObjectData) {
            final EncodeableObjectData encodeableObjectData = ((EncodeableObjectData) data);
            str.append("ValueData@" + Integer.toHexString(encodeableObjectData.hashCode()) + " " + encodeableObjectData.getType()
                    + ":" + encodeableObjectData.getEncodedObjectData());
        } else if (data instanceof IdentityData) {
            final IdentityData referenceData = (IdentityData) data;
            str.append("ReferenceData@" + Integer.toHexString(referenceData.hashCode()) + " " + referenceData.getType() + ":"
                    + referenceData.getOid() + ":" + referenceData.getVersion());
        } else if (data instanceof ObjectData) {
            dumpObjectData(str, data, indent, complete);
        } else if (data instanceof CollectionData) {
            dumpCollectionData(str, data, indent, complete);
        } else {
            str.append("Unknown: " + data);
        }
    }

    private void dumpCollectionData(final StringBuffer str, final Data data, final int indent, final Vector complete) {
        final CollectionData objectData = ((CollectionData) data);
        str.append("CollectionData@" + Integer.toHexString(objectData.hashCode()) + " " + objectData.getType() + ":"
                + objectData.getOid() + ":" + (objectData.hasAllElements() ? "A" : "-") + ":" + objectData.getVersion());
        final Object[] elements = objectData.getElements();
        for (int i = 0; elements != null && i < elements.length; i++) {
            str.append("\n");
            str.append(padding(indent));
            str.append(i + 1);
            str.append(") ");
            dump(str, (Data) elements[i], indent + 1, complete);
        }
    }

    private void dumpObjectData(final StringBuffer str, final Data data, final int indent, final Vector complete) {
        final ObjectData objectData = ((ObjectData) data);
        str.append("ObjectData@" + Integer.toHexString(objectData.hashCode()) + " " + objectData.getType() + ":"
                + objectData.getOid() + ":" + (objectData.hasCompleteData() ? "C" : "-") + ":" + objectData.getVersion());

        if (complete.contains(objectData)) {
            str.append(" (already detailed)");
            return;
        }

        complete.addElement(objectData);
        final NakedObjectSpecification spec = NakedObjectsContext.getSpecificationLoader().loadSpecification(data.getType());
        final NakedObjectAssociation[] fs = encoder.getFieldOrder(spec);
        final Object[] fields = objectData.getFieldContent();
        for (int i = 0; fields != null && i < fields.length; i++) {
            str.append("\n");
            str.append(padding(indent));
            str.append(i + 1);
            str.append(") ");
            str.append(fs[i].getId());
            str.append(": ");
            dump(str, (Data) fields[i], indent + 1, complete);
        }
    }

    private String indentedNewLine() {
        return "\n" + padding(2);
    }

    private String padding(final int indent) {
        final int length = indent * 3;
        while (length > PADDING.length()) {
            PADDING += PADDING;
        }
        return PADDING.substring(0, length);
    }


}
// Copyright (c) Naked Objects Group Ltd.




© 2015 - 2025 Weber Informatics LLC | Privacy Policy