Package org.openetcs.pror.tracing.provider

Source Code of org.openetcs.pror.tracing.provider.CreateTraceCommand

/**
* Copyright 2014 Formal Mind GmbH.
*
* Licensed under the European Union Public Licence (EUPL), Version 1.1 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*       http://joinup.ec.europa.eu/software/page/eupl/licence-eupl
*
* 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.
*
* Contributors:
*     Michael Jastram - initial API and implementation
*/
package org.openetcs.pror.tracing.provider;

import java.util.Set;

import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.command.AbstractOverrideableCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.rmf.reqif10.AttributeDefinitionString;
import org.eclipse.rmf.reqif10.AttributeValue;
import org.eclipse.rmf.reqif10.AttributeValueString;
import org.eclipse.rmf.reqif10.ReqIF;
import org.eclipse.rmf.reqif10.ReqIF10Factory;
import org.eclipse.rmf.reqif10.ReqIF10Package;
import org.eclipse.rmf.reqif10.SpecObject;
import org.eclipse.rmf.reqif10.SpecRelation;
import org.eclipse.rmf.reqif10.SpecRelationType;
import org.eclipse.rmf.reqif10.common.util.ReqIF10Util;
import org.eclipse.rmf.reqif10.pror.util.ProrUtil;
import org.openetcs.pror.tracing.TracingConfiguration;
import org.openetcs.pror.tracing.util.TracingUtil;

/**
* <p>
* This command is used for creating traces from Papyrus via drag and drop.
* During the drag operation (and before drop), many instances of the command
* are created. To keep performance high, {@link #prepare()} does nothing, while
* all the "work" is done in {@link #doExecute()}, which is only called after
* the drop.
* </p>
*
* <p>
* The format of the value of the Proxy Element is described in
* {@link TracingConfigurationItemProvider}.
* </p>
*
* @author jastram
*
*/
public class CreateTraceCommand extends AbstractOverrideableCommand {

  private Set<EObject> elements;
  private SpecObject target;
  private TracingConfigurationItemProvider itemProvider;

  public CreateTraceCommand(Set<EObject> elements, SpecObject target, int operation, EditingDomain domain, TracingConfigurationItemProvider itemProvider) {
    super(domain, "Dropped " + elements.size() + " Papyrus element(s)");
    if (itemProvider == null) throw new NullPointerException();
    this.itemProvider = itemProvider;
    this.elements = elements;
    this.target = target;
  }

  private TracingConfiguration getTracingConfig() {
    return (TracingConfiguration) itemProvider.getTarget();
  }
 
  /**
   * We always return true.  The default implementation would call the prepare method, which creates
   * proxy elements as a side effect.
   */
  @Override
  public boolean doCanExecute() {
    return true;
  }

  /**
   * Builds a CompoundCommand that is then set to
   * {@link AbstractOverrideableCommand#setOverride(org.eclipse.emf.common.command.Command)}
   * .
   */
  @Override
  public void doExecute() {
    CompoundCommand cmd = new CompoundCommand(getLabel());
    for (EObject element : elements) {
      createCreateLinkCommand(cmd, element);
    }
    setOverride(cmd);
    if (cmd.canExecute())
      cmd.execute();
  }

  /**
   * Adds to the provided compound command to create a link from a proxy for
   * element to the drop target. If a proxy already exists, it is reused. If a
   * link of the correct type already exists, it is reused as well.
   */
  void createCreateLinkCommand(CompoundCommand cmd, EObject element) {
    SpecObject proxy = getProxy(element, cmd);
    SpecRelation specRelation = getLink(proxy, cmd);
    TracingUtil.notifyProxyListeners(target, specRelation, element);
  }

  /**
   * Returns the proxy for the given element.  If the proxy does not exist yet,
   * it is created, thereby appending to cmd.
   */
  private SpecObject getProxy(EObject element, CompoundCommand cmd) {
    SpecObject proxy = findProxyFor(element);
    if (proxy == null)
      proxy = createProxy(cmd, element);
    return proxy;
  }

  /**
   * Returns the link for the given link.  If the link does not exist yet,
   * it is created, thereby appending to cmd.
   * @param element
   */
  private SpecRelation getLink(SpecObject proxy, CompoundCommand cmd) {
    SpecRelation link = findLinkFor(proxy);
    if (link == null)
      link = createLink(cmd, proxy);
    return link;
  }

  /**
   * Creates a properly configured SpecRelation object between proxy and target.
   */
  private SpecRelation createLink(CompoundCommand cmd, SpecObject proxy) {
    SpecRelation link;
    link= ReqIF10Factory.eINSTANCE.createSpecRelation();
    TracingConfiguration config = getTracingConfig();
    link.setSource(config.isLinkFromTarget() ? target : proxy);
    link.setTarget(config.isLinkFromTarget() ? proxy : target);
    cmd.append(ProrUtil.createAddTypedElementCommand(
        ReqIF10Util.getReqIF(config).getCoreContent(),
        ReqIF10Package.Literals.REQ_IF_CONTENT__SPEC_RELATIONS,
        link, ReqIF10Package.Literals.SPEC_RELATION__TYPE,
        config.getLinkType(), 0, 0, domain, itemProvider.getAdapterFactory()));
    return link;
  }

  /**
   * Attempts to find a SpecRelation that: (1) connects proxy and
   * target in the right direction; and (2) has the correct type.
   */
  private SpecRelation findLinkFor(SpecObject proxy) {
    TracingConfiguration config = getTracingConfig();
    SpecObject linkSource = config.isLinkFromTarget() ? target : proxy;
    SpecObject linkTarget = config.isLinkFromTarget() ? proxy : target;
    SpecRelationType type = config.getLinkType();
   
    for (SpecRelation relation : ReqIF10Util.getReqIF(config)
        .getCoreContent().getSpecRelations()) {
      //  It's okay to compare null and references.
      if (relation.getType() == type && linkSource == relation.getSource()
          && linkTarget == relation.getTarget()) {
        return relation;
      }
    }
    return null;
  }

  private SpecObject createProxy(CompoundCommand cmd, EObject element) {
    SpecObject proxy;
    proxy = ReqIF10Factory.eINSTANCE.createSpecObject();
    TracingConfiguration config = getTracingConfig();
    AttributeValueString value = ReqIF10Factory.eINSTANCE.createAttributeValueString();
    value.setDefinition(config.getProxyAttribute());
    value.setTheValue(itemProvider.buildProxyContent(element));
    proxy.getValues().add(value);
    cmd.append(ProrUtil.createAddTypedElementCommand(
        ReqIF10Util.getReqIF(config).getCoreContent(),
        ReqIF10Package.Literals.REQ_IF_CONTENT__SPEC_OBJECTS,
        proxy, ReqIF10Package.Literals.SPEC_OBJECT__TYPE,
        config.getProxyType(), 0, 0, domain, itemProvider.getAdapterFactory()));
    return proxy;
  }

  /**
   * Tries to find the proxy with the given URI.  Returns null if not found.
   */
  SpecObject findProxyFor(EObject element) {
    TracingConfiguration config = getTracingConfig();
    String uri = EcoreUtil.getURI(element).toString();
    ReqIF reqif = ReqIF10Util.getReqIF(config);
    AttributeDefinitionString ad = config.getProxyAttribute();

    // Iterate SpecObjects and search for existing proxy element
    for (SpecObject specObject : reqif.getCoreContent().getSpecObjects()) {
      AttributeValue value = ReqIF10Util
          .getAttributeValue(specObject, ad);
      if (value instanceof AttributeValueString) {
        String tmpUrl = TracingConfigurationItemProvider
            .getProxyUrlFromValue(((AttributeValueString) value)
                .getTheValue());
        if (uri.equals(tmpUrl)) {
          return specObject;
        }
      }
    }
    return null;
  }

  @Override
  public void doUndo() {
    throw new RuntimeException("Should never be called, due to overrideCommand");
  }

  @Override
  public void doRedo() {
    throw new RuntimeException("Should never be called, due to overrideCommand");
  }
 
 
}
TOP

Related Classes of org.openetcs.pror.tracing.provider.CreateTraceCommand

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.