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

org.fabric3.spi.model.instance.CopyUtil Maven / Gradle / Ivy

There is a newer version: 2.0.1
Show newest version
/*
* Fabric3
* Copyright (c) 2009-2011 Metaform Systems
*
* Fabric3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version, with the
* following exception:
*
* Linking this software statically or dynamically with other
* modules is making a combined work based on this software.
* Thus, the terms and conditions of the GNU General Public
* License cover the whole combination.
*
* As a special exception, the copyright holders of this software
* give you permission to link this software with independent
* modules to produce an executable, regardless of the license
* terms of these independent modules, and to copy and distribute
* the resulting executable under terms of your choice, provided
* that you also meet, for each linked independent module, the
* terms and conditions of the license of that module. An
* independent module is a module which is not derived from or
* based on this software. If you modify this software, you may
* extend this exception to your version of the software, but
* you are not obligated to do so. If you do not wish to do so,
* delete this exception statement from your version.
*
* Fabric3 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the
* GNU General Public License along with Fabric3.
* If not, see .
*/
package org.fabric3.spi.model.instance;

import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.namespace.QName;

import org.fabric3.model.type.component.ComponentDefinition;
import org.fabric3.model.type.component.CompositeImplementation;
import org.fabric3.model.type.component.ResourceReferenceDefinition;

/**
 * Copies a logical model graph.
 *
 * @version $Rev: 9763 $ $Date: 2011-01-03 00:48:06 +0000 (Mon, 03 Jan 2011) $
 */
public class CopyUtil {

    private CopyUtil() {
    }

    /**
     * Makes a replica of the composite, including preservation of parent-child relationships.
     *
     * @param composite the composite to copy
     * @return the copy
     */
    public static LogicalCompositeComponent copy(LogicalCompositeComponent composite) {
        return copy(composite, composite.getParent());
    }

    /**
     * Performs the copy using depth-first traversal.
     *
     * @param composite the composite to copy
     * @param parent    the parent of the copy
     * @return the copy
     */
    private static LogicalCompositeComponent copy(LogicalCompositeComponent composite, LogicalCompositeComponent parent) {
        // Create maps to de-reference pointers to components, reference and services. Since the copy is performed depth-first, the maps
        // will always be populated before a component, reference, or service needs to be de-referenced.
        Map> components = new HashMap>();
        Map references = new HashMap();
        Map services = new HashMap();
        LogicalCompositeComponent replica = copy(composite, parent, components, services, references);

        // Wires must be copied last since they may contain forward references to services provided by components not yet copied. This
        // guarantees that all components and services will have been copied before wires are copied.
        copyWires(composite, components, services);
        return replica;
    }

    private static LogicalCompositeComponent copy(LogicalCompositeComponent composite,
                                                  LogicalCompositeComponent parent,
                                                  Map> components,
                                                  Map services,
                                                  Map references) {

        URI uri = composite.getUri();
        ComponentDefinition definition = composite.getDefinition();
        LogicalCompositeComponent copy = new LogicalCompositeComponent(uri, definition, parent);
        components.put(uri, copy);
        copy.setAutowire(composite.getAutowire());
        copy.setState(composite.getState());
        copy.setZone(composite.getZone());
        copy.setDeployable(composite.getDeployable());
        copy.addIntents(composite.getIntents());
        copy.addPolicySets(composite.getPolicySets());
        for (LogicalProperty property : composite.getAllProperties().values()) {
            copy.setProperties(property);
        }
        for (LogicalComponent component : composite.getComponents()) {
            copy(component, copy, components, services, references);
        }
        for (LogicalReference reference : composite.getReferences()) {
            copy(reference, copy, references);
        }
        for (LogicalResourceReference resourceReference : composite.getResourceReferences()) {
            copy(resourceReference, copy);
        }
        for (LogicalService service : composite.getServices()) {
            copy(service, copy, components, services);
        }
        for (LogicalChannel channel : composite.getChannels()) {
            copy(channel, copy);
        }
        for (LogicalConsumer consumer : composite.getConsumers()) {
            copy(consumer, copy);
        }
        for (LogicalProducer producer : composite.getProducers()) {
            copy(producer, copy);
        }
        for (LogicalResource resource : composite.getResources()) {
            copy(resource, copy);
        }
        return copy;
    }

    @SuppressWarnings({"unchecked"})
    private static void copy(LogicalComponent component,
                             LogicalCompositeComponent newParent,
                             Map> components,
                             Map services,
                             Map references) {
        LogicalComponent copy;
        if (component instanceof LogicalCompositeComponent) {
            copy = copy((LogicalCompositeComponent) component, newParent, components, services, references);
        } else {
            URI uri = component.getUri();
            copy = new LogicalComponent(uri, component.getDefinition(), newParent);
            copy.setAutowire(component.getAutowire());
            copy.setState(component.getState());
            copy.setZone(component.getZone());
            copy.setDeployable(component.getDeployable());
            copy.addIntents(component.getIntents());
            copy.addPolicySets(component.getPolicySets());
            components.put(uri, copy);

            for (LogicalProperty property : component.getAllProperties().values()) {
                copy.setProperties(property);
            }
            for (LogicalReference reference : component.getReferences()) {
                copy(reference, copy, references);
            }
            for (LogicalResourceReference resourceReference : component.getResourceReferences()) {
                copy(resourceReference, copy);
            }
            for (LogicalService service : component.getServices()) {
                copy(service, copy, components, services);
            }
            for (LogicalConsumer consumer : component.getConsumers()) {
                copy(consumer, copy);
            }
            for (LogicalProducer producer : component.getProducers()) {
                copy(producer, copy);
            }
        }
        newParent.addComponent(copy);
    }

    private static void copy(LogicalReference reference, LogicalComponent parent, Map references) {
        URI referenceUri = reference.getUri();
        LogicalReference copy = new LogicalReference(referenceUri, reference.getDefinition(), parent);
        references.put(referenceUri, copy);
        for (URI uri : reference.getPromotedUris()) {
            copy.addPromotedUri(uri);
        }
        copy.setAutowire(reference.getAutowire());
        copy.setLeafReference(references.get(reference.getLeafReference().getUri()));
        copy.setResolved(reference.isResolved());
        copy.setServiceContract(reference.getServiceContract());
        for (URI uri : reference.getPromotedUris()) {
            copy.addPromotedUri(uri);
        }
        copy.addIntents(reference.getIntents());
        copy.addPolicySets(reference.getPolicySets());
        copy(reference, copy);
        parent.addReference(copy);
    }

    @SuppressWarnings({"unchecked"})
    private static void copy(LogicalResourceReference resourceReference, LogicalComponent parent) {
        URI uri = resourceReference.getUri();
        ResourceReferenceDefinition definition = resourceReference.getDefinition();
        LogicalResourceReference copy = new LogicalResourceReference(uri, definition, parent);
        copy.setTarget(resourceReference.getTarget());
        parent.addResource(copy);
    }


    private static void copy(LogicalService service,
                             LogicalComponent parent,
                             Map> components,
                             Map services) {
        URI uri = service.getUri();
        LogicalService copy = new LogicalService(uri, service.getDefinition(), parent);
        services.put(uri, copy);
        copy.setLeafComponent(components.get(service.getLeafComponent().getUri()));
        copy.setLeafService(services.get(service.getLeafService().getUri()));
        copy.setServiceContract(service.getServiceContract());
        copy.setPromotedUri(service.getPromotedUri());
        copy.addIntents(service.getIntents());
        copy.addPolicySets(service.getPolicySets());
        copy(service, copy);
        parent.addService(copy);
    }

    private static void copy(LogicalChannel channel, LogicalCompositeComponent parent) {
        URI uri = channel.getUri();
        LogicalChannel copy = new LogicalChannel(uri, channel.getDefinition(), parent);
        copy.setServiceContract(channel.getServiceContract());
        copy(channel, copy);
        copy.setDeployable(channel.getDeployable());
        copy.addIntents(channel.getIntents());
        copy.addPolicySets(channel.getPolicySets());
        copy.setState(channel.getState());
        copy.setZone(channel.getZone());
        parent.addChannel(copy);
    }

    private static void copy(LogicalProducer producer, LogicalComponent parent) {
        URI uri = producer.getUri();
        LogicalProducer copy = new LogicalProducer(uri, producer.getDefinition(), parent);
        copy.setServiceContract(producer.getServiceContract());
        copy.addTargets(producer.getTargets());
        copyInvocable(producer, copy);
        copy.addIntents(producer.getIntents());
        copy.addPolicySets(producer.getPolicySets());
        parent.addProducer(copy);
    }

    private static void copy(LogicalConsumer consumer, LogicalComponent parent) {
        URI uri = consumer.getUri();
        LogicalConsumer copy = new LogicalConsumer(uri, consumer.getDefinition(), parent);
        copy.setServiceContract(consumer.getServiceContract());
        copy.addSources(consumer.getSources());
        copyInvocable(consumer, copy);
        copy.addIntents(consumer.getIntents());
        copy.addPolicySets(consumer.getPolicySets());
        parent.addConsumer(copy);
    }

    @SuppressWarnings({"unchecked"})
    private static void copy(LogicalResource resource, LogicalCompositeComponent parent) {
        LogicalResource copy = new LogicalResource(resource.getDefinition(), parent);
        copy.setDeployable(resource.getDeployable());
        copy.setState(resource.getState());
        copy.setZone(resource.getZone());
        parent.addResource(copy);
    }


    @SuppressWarnings({"unchecked"})
    private static void copy(Bindable from, Bindable to) {
        for (LogicalBinding binding : from.getBindings()) {
            LogicalBinding copy = new LogicalBinding(binding.getDefinition(), to, binding.getDeployable());
            copy.setState(binding.getState());
            to.addBinding(copy);
            copy.setAssigned(binding.isAssigned());
            copy.addIntents(binding.getIntents());
            copy.addPolicySets(binding.getPolicySets());
        }
        for (LogicalBinding binding : from.getCallbackBindings()) {
            LogicalBinding copy = new LogicalBinding(binding.getDefinition(), to, binding.getDeployable());
            copy.setState(binding.getState());
            to.addCallbackBinding(copy);
            copy.setAssigned(binding.isAssigned());
            copy.addIntents(binding.getIntents());
            copy.addPolicySets(binding.getPolicySets());
        }
        copyInvocable(from, to);
    }

    @SuppressWarnings({"unchecked"})
    private static void copyInvocable(LogicalInvocable from, LogicalInvocable to) {
        List operations = new ArrayList();
        for (LogicalOperation operation : from.getOperations()) {
            LogicalOperation copy = new LogicalOperation(operation.getDefinition(), to);
            copy.addIntents(operation.getIntents());
            copy.addPolicySets(operation.getPolicySets());
            operations.add(copy);
        }
        to.overrideOperations(operations);
    }

    private static void copyWires(LogicalComponent fromComponent, Map> components, Map services) {
        LogicalComponent toComponent = components.get(fromComponent.getUri());
        if (fromComponent instanceof LogicalCompositeComponent) {
            LogicalCompositeComponent composite = (LogicalCompositeComponent) fromComponent;
            for (LogicalComponent component : composite.getComponents()) {
                copyWires(component, components, services);
            }
        }
        for (LogicalReference fromReference : fromComponent.getReferences()) {
            LogicalReference toReference = toComponent.getReference(fromReference.getUri().getFragment());
            LogicalCompositeComponent originalParent = fromComponent.getParent();
            LogicalCompositeComponent newParent = toComponent.getParent();
            copyWires(fromReference, toReference, originalParent, newParent, services);
        }
    }

    private static void copyWires(LogicalReference fromReference,
                                  LogicalReference toReference,
                                  LogicalCompositeComponent from,
                                  LogicalCompositeComponent to,
                                  Map services) {
        for (LogicalWire wire : from.getWires(fromReference)) {
            QName deployable = wire.getTargetDeployable();
            boolean replaceable = wire.isReplaceable();
            LogicalService fromTarget = wire.getTarget();
            LogicalService toTarget = services.get(fromTarget.getUri());
            LogicalWire wireCopy = new LogicalWire(to, toReference, toTarget, deployable, replaceable);
            wireCopy.setState(wire.getState());
            wireCopy.setReplaces(wire.isReplaces());

            LogicalBinding fromSourceBinding = wire.getSourceBinding();
            LogicalBinding toSourceBinding = null;
            if (fromSourceBinding != null) {
                for (LogicalBinding binding : toReference.getBindings()) {
                    if (fromSourceBinding.getDefinition().getName().equals(binding.getDefinition().getName())) {
                        toSourceBinding = binding;
                        break;
                    }
                }
            }
            wireCopy.setSourceBinding(toSourceBinding);

            LogicalBinding fromTargetBinding = wire.getTargetBinding();
            LogicalBinding toTargetBinding = null;
            if (fromTargetBinding != null) {
                if (!toTarget.getBindings().isEmpty()) {
                    for (LogicalBinding binding : toTarget.getBindings()) {
                        if (fromTargetBinding.getDefinition().getName().equals(binding.getDefinition().getName())) {
                            toTargetBinding = binding;
                            break;
                        }
                    }
                } else {
                    for (LogicalBinding binding : toTarget.getLeafService().getBindings()) {
                        if (fromTargetBinding.getDefinition().getName().equals(binding.getDefinition().getName())) {
                            toTargetBinding = binding;
                            break;
                        }
                    }
                }
            }
            wireCopy.setTargetBinding(toTargetBinding);
            to.addWire(toReference, wireCopy);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy