Package org.openiaml.model.tests

Source Code of org.openiaml.model.tests.ModelInferenceTestCase

/**
*
*/
package org.openiaml.model.tests;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import junit.framework.AssertionFailedError;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.jaxen.JaxenException;
import org.openiaml.model.ModelLoader.ModelLoadException;
import org.openiaml.model.codegen.php.CheckModelInstance;
import org.openiaml.model.drools.CreateMissingElementsWithDrools;
import org.openiaml.model.drools.ICreateElementsFactory;
import org.openiaml.model.model.Action;
import org.openiaml.model.model.ActionEdgeSource;
import org.openiaml.model.model.ComplexTerm;
import org.openiaml.model.model.ECARule;
import org.openiaml.model.model.Function;
import org.openiaml.model.model.GeneratedElement;
import org.openiaml.model.model.InternetApplication;
import org.openiaml.model.model.ModelFactory;
import org.openiaml.model.model.ModelPackage;
import org.openiaml.model.model.NamedElement;
import org.openiaml.model.model.Parameter;
import org.openiaml.model.model.Wire;
import org.openiaml.model.model.WireDestination;
import org.openiaml.model.model.WireSource;
import org.openiaml.model.model.domain.DomainPackage;
import org.openiaml.model.model.scopes.ScopesPackage;
import org.openiaml.model.model.users.RequiresEdgeDestination;
import org.openiaml.model.model.users.RequiresEdgesSource;
import org.openiaml.model.model.visual.VisualPackage;
import org.openiaml.model.model.wires.ConditionEdgeDestination;
import org.openiaml.model.model.wires.ExtendsEdge;
import org.openiaml.model.model.wires.ExtendsEdgeDestination;
import org.openiaml.model.model.wires.ExtendsEdgesSource;
import org.openiaml.model.model.wires.ParameterEdgeDestination;
import org.openiaml.model.model.wires.ParameterEdgesSource;
import org.openiaml.model.model.wires.RequiresEdge;
import org.openiaml.model.tests.CachedModelLoader.IModelReloader;

import ca.ecliptical.emf.xpath.EMFXPath;

/**
* Assorted methods to assist with loading and inferring models.
*
* @see ModelTestCaseWithProperties
* @see #loadAndInfer(Class)
* @author jmwright
*/
public abstract class ModelInferenceTestCase extends ModelTestCase implements IProvidesInferenceEngine {
 
  /**
   * Should inference rule sources be logged by default?
   */
  public static final boolean DEFAULT_LOG_RULE_SOURCES = false;

  protected InternetApplication root;
 
  /**
   * Forcibly clear the entire inference cache.
   */
  public void resetInferenceCache() {
    inferer.getCache().clear();
  }
 
  /**
   * Remove the given class from the inference cache. Returns the
   * original result for the given key, or <code>null</code> if the
   * key was not present.
   *
   * @param cls the class to remove from the cache
   * @return the original result for the given key, or <code>null</code> if the key was not in the cache
   */
  public File removeClassFromInferenceCache(Class<?> cls) {
    return inferer.getCache().remove(cls);
  }

  /**
   * Load a model file and perform inference on it.
   */
  protected InternetApplication loadAndInfer(final String modelFile) throws Exception {
    return inferer.loadAndInfer(this, modelFile);
  }

  /**
   * Automagically load the model file (.iaml) for this given
   * test class, and do inference.
   *
   * @see ModelSourceResolver#getModelFileForClass(Class)
   * @see #loadAndCodegen(String)
   * @see #DEFAULT_LOG_RULE_SOURCES
   * @param class1 The test class to load a model for.
   * @return the loaded and inferred InternetApplication
   */
  protected InternetApplication loadAndInfer(
      Class<?> class1) throws Exception {
    return loadAndInfer(class1, DEFAULT_LOG_RULE_SOURCES);
  }
 
  /**
   * Load the model file (.iaml) for this given
   * test class, and do inference.
   *
   * @see #loadAndCodegen(String)
   * @param class1 The test class to load a model for.
   * @param logRuleSource Log the rule source of inserted elements.
   * @return the loaded and inferred InternetApplication
   */
  protected InternetApplication loadAndInfer(
      final String filename, boolean logRuleSource) throws Exception {
    return inferer.loadAndInfer(this, filename, logRuleSource);
  }

  /**
   * Automagically load the model file (.iaml) for this given
   * test class, but don't do inference.
   *
   * @see #loadAndInfer(Class)
   * @param class1 The test class to load a model for.
   * @return the loaded and inferred InternetApplication
   */
  protected InternetApplication loadDirectly(
      Class<?> class1) throws Exception {
    return loader.loadDirectly(class1, false);
  }

  /**
   * Load a model file directly.
   * Assumes that it will only contain one element (and tests this with JUnit).
   * @throws ModelLoadException
   */
  public EObject loadModelDirectly(String filename) throws ModelLoadException {
    return loader.loadModelDirectly(filename);
  }
 
  /**
   * Load a model file directly.
   * Assumes that it will only contain one element (and tests this with JUnit).
   * @throws ModelLoadException
   */
  public EObject loadModelDirectly(IFile f) throws ModelLoadException {
    return loader.loadModelDirectly(f);
  }
 
  private static ModelSourceResolver resolver = ModelSourceResolver.getInstance();
  private static CachedModelLoader loader = CachedModelLoader.getInstance();
 
  /**
   * Automatically find the model file (.iaml) for the given class.
   *
   * @param class1
   * @return
   */
  protected String getModelFileForClass(Class<?> class1) {
    return resolver.getModelFileForClass(class1);
  }
 
  /**
   * Automagically load the model file (.iaml) for this given
   * test class, but don't do inference.
   *
   * @see #getModelFileForClass(Class)
   * @see #loadModelDirectly(Class)
   * @param class1 The test class to load a model for.
   * @param logRuleSource Log the rule source of inserted elements.
   * @return the loaded and inferred InternetApplication
   */
  protected InternetApplication loadDirectly(
      Class<?> class1, boolean logRuleSource) throws Exception {
    return loader.loadDirectly(class1, logRuleSource);
  }

  /**
   * Perform inference on a loaded model.
   *
   * @see CreateMissingElementsWithDrools#create(EObject, boolean)
   * @param logRuleSource Log the rule source of inserted elements.
   * @return
   * @throws Exception
   */
  protected InternetApplication infer(InternetApplication root, boolean logRuleSource, IModelReloader reloader) throws Exception {
    return inferer.infer(this, root, logRuleSource, reloader);
  }
 
  /**
   * <p>Create a new instance of the inference engine.</p>
   *
   * @return
   */
  public CreateMissingElementsWithDrools getInferenceEngine(ICreateElementsFactory handler, boolean trackInsertions, final IModelReloader reloader) {
    return new CreateMissingElementsWithDrools(handler, trackInsertions);
  }
 
  private static final CachedModelInferer inferer = CachedModelInferer.getInstance();

  /**
   * Load a model file and perform inference on it.
   * This method also sees if we have got a cached model; if
   * not, it loads and infers it, then saves the inferred model
   * location to the cache.
   *
   * @see CreateMissingElementsWithDrools#create(EObject, boolean)
   * @param logRuleSource Log the rule source of inserted elements.
   * @return
   * @throws Exception
   */
  protected InternetApplication loadAndInfer(final Class<?> loadClass, final boolean logRuleSource) throws Exception {
    return inferer.loadAndInfer(this, loadClass, logRuleSource);
  }

  /**
   * Load a model file and perform inference on it.
   * This method also sees if we have got a cached model; if
   * not, it loads and infers it, then saves the inferred model
   * location to the cache.
   *
   * @see CreateMissingElementsWithDrools#create(EObject, boolean)
   * @param logRuleSource Log the rule source of inserted elements.
   * @return
   * @throws Exception
   */
  protected InternetApplication loadAndInfer(final Class<?> loadClass, final boolean logRuleSource, IProgressMonitor monitor) throws Exception {
    return inferer.loadAndInfer(this, loadClass, logRuleSource, monitor);
  }

  /**
   * Perform an XPath-like query on an EMF object
   *
   * @deprecated XPath queries should not be used; the metamodel should
   *     be used instead
   * @param root
   * @param query
   * @return
   * @throws JaxenException
   */
  public static List<?> query(final EObject root, String query) throws JaxenException {
    EMFXPath xpath = new EMFXPath(query);
    xpath.addNamespace("iaml", ModelPackage.eNS_URI);
    xpath.addNamespace("iaml.domain", DomainPackage.eNS_URI);
    xpath.addNamespace("iaml.scopes", ScopesPackage.eNS_URI);
    xpath.addNamespace("iaml.visual", VisualPackage.eNS_URI);
    xpath.addNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
    return xpath.selectNodes(root);
  }

  /**
   * Helper method: print out a list of objects
   * @param obj
   */
  protected void dump(List<Object> obj) {
    for (Object o : obj)
      EMFXPath.dump(o, System.out);
    System.out.println("-");
  }

  /**
   * Helper method: print out an objects
   * @param obj
   */
  protected void dump(Object o) {
    EMFXPath.dump(o, System.out);
  }

  /**
   * Helper method: perform a query, but assert that there is only
   * one result returned, and it is of type EObject
   *
   * @deprecated use EMF methods instead
   * @param root
   * @param query
   * @return
   * @throws JaxenException
   */
  public static EObject queryOne(EObject root, String query) throws JaxenException {
    List<?> q = query(root, query);
    assertEquals("queryOne for '" + query + "' did not return one result", 1, q.size());
    return (EObject) q.get(0);
  }
 
  /**
   * Assert that there are no results for the given XPath query.
   *
   * @deprecated use EMF methods instead
   * @param root the node on which to execute the XPath query
   * @param query the query to execute
   * @throws JaxenException
   */
  public static void assertHasNone(EObject root, String query) throws JaxenException {
    List<?> q = query(root, query);
    assertEquals("Unexpected query result for '" + query + "' on '" + root + ": " + q, 0, q.size());
  }
 
  /**
   * Assert that there are no results for the given XPath query with
   * the given type.
   *
   * @deprecated use EMF methods instead
   * @param root the node on which to execute the XPath query
   * @param query the query to execute
   * @param type the type to check for in the results
   * @throws JaxenException
   */
  public static void assertHasNone(EObject root, String query, Class<?> type) throws JaxenException {
    List<?> q = query(root, query);
    for (Object o : q) {
      if (type.isInstance(o)) {
        fail("Unexpected type '" + type.getName() + "' result for '" + query + "' on '" + root + ": " + o);       
      }
    }

  }
 
  /**
   * Assert that the given list of elements contains a
   * NamedElement with the given name and given generated status.
   *
   * @param elements
   * @param name
   * @param isGenerated
   */
  public static void assertContainsNamedElement(List<? extends NamedElement> elements, String name, boolean isGenerated) {
    for (NamedElement e : elements) {
      if (e.getName().equals(name) && e.isIsGenerated() == isGenerated) {
        // ok
        return;
      }
    }
    fail("Did not find any NamedElement '" + name + "' [generated=" + isGenerated + "] in " + elements);
  }
 
  /**
   * Assert that the given elements are generated.
   *
   * @param e
   */
  public static void assertGenerated(GeneratedElement... elements) {
    for (GeneratedElement e : elements) {
      assertTrue("Element '" + e + "' should be generated", e.isIsGenerated());
    }
  }

  /**
   * Assert that the given elements are not generated.
   *
   * @param e
   */
  public static void assertNotGenerated(GeneratedElement... elements) {
    for (GeneratedElement e : elements) {
      assertFalse("Element '" + e + "' should not be generated", e.isIsGenerated());
    }
  }

  /**
   *
   * @param container TODO we don't need this parameter
   * @param from
   * @param wire
   * @return the wire found or null
   * @throws JaxenException
   */
  protected static Wire getWireFrom(EObject container, WireSource from,
      String wire) throws JaxenException {
    for (Wire w : from.getOutWires()) {
      if (w instanceof NamedElement && wire.equals(((NamedElement) w).getName())) {
        return w;
      }
    }
   
    fail("No wire found with name '" + wire + "'");
    return null;
  }
 
  /**
   *
   * @param from
   * @param name
   * @return the wire found or null
   * @throws JaxenException
   */
  protected static ECARule getECARuleFrom(ActionEdgeSource from, String name) throws JaxenException {
    for (ECARule w : from.getListeners()) {
      if (w instanceof NamedElement && name.equals(((NamedElement) w).getName())) {
        return w;
      }
    }
   
    fail("No action found with name '" + name + "'");
    return null;
 
 
  /**
   * Get <em>any</em> Wire connecting the given elements,
   * contained with the given container element or any of its children.
   *
   * <p>It's not possible to do something like //iaml:wire[iaml:from='id']
   * so we need to parse them manually.
   *
   * @param container
   * @param fromElement
   * @param toElement
   * @return the wire found
   * @throws JaxenException
   * @throws AssertionFailedError if no wire was found
   */
  protected static Wire getWireFromTo(EObject container, WireSource fromElement, WireDestination toElement) throws JaxenException {
    for (Wire w : fromElement.getOutWires()) {
      if (toElement.equals(w.getTo())) {
        return w;
      }
    }
   
    fail("No wire found from [" + fromElement + "] to [" + toElement + "]");
    return null;
  }

  /**
   * Get <em>any</em> ParameterWire connecting the given elements,
   * contained with the given container element or any of its children.
   * If many exist, this method fails.
   *
   * @return the found ParameterEdge
   * @throws JaxenException
   * @throws AssertionFailedError if no edge was found, or more than one was found
   */
  protected static Parameter getParameterFromTo(EObject container, ParameterEdgesSource from, ParameterEdgeDestination to) throws JaxenException {
    List<Parameter> edges = to.getInParameterEdges();
    Parameter result = null;
    int count = 0;
   
    for (Parameter e : edges) {
      if (from.equals(e.getParameterValue())) {
        count++;
        result = e;
      }
    }
   
    assertEquals("Expected 1 ParameterEdge from '" + from + "' to '" + to + "'", 1, count);
    return result;
  }

  /**
   * Get <em>all</em> ParameterEdge connecting the given elements,
   * contained with the given container element or any of its children.
   *
   * @return the found ParameterEdges
   * @throws JaxenException
   */
  protected static Set<Parameter> getParametersFromTo(EObject container, ParameterEdgesSource from, ParameterEdgeDestination to) throws JaxenException {
    Set<Parameter> result = new HashSet<Parameter>();
   
    for (Parameter w : from.getOutParameterEdges()) {
      if (to.equals(w.getParameterTerm())) {
        result.add(w);
      }
    }

    return result;
  }
 
  /**
   * Get <em>all</em> ParameterEdge connecting the given elements,
   * contained with the given container element or any of its children,
   * with the given name.
   *
   * @return the found ParameterEdges
   * @throws JaxenException
   */
  protected static Set<Parameter> getParametersFromTo(EObject container, ParameterEdgesSource from, ParameterEdgeDestination to, String name) throws JaxenException {
    Set<Parameter> result = new HashSet<Parameter>();
   
    for (Parameter w : from.getOutParameterEdges()) {
      if (name.equals(w.getName()) && to.equals(w.getParameterTerm())) {
        result.add(w);
      }
    }
   
    return result;
  }
 
  /**
   * Get <em>all</em> {@link ComplexTerm}s connecting the given elements,
   * contained with the given container element or any of its children.
   *
   * @return the found {@link ComplexTerm}s
   * @throws JaxenException
   */
  protected static Set<ComplexTerm> getComplexTermsFromTo(EObject container, Function from, ConditionEdgeDestination to) throws JaxenException {
    Set<ComplexTerm> result = new HashSet<ComplexTerm>();
   
    for (ComplexTerm w : from.getConditioned()) {
      if (to.equals(w.getConditioned())) {
        result.add(w);
      }
    }
   
    return result;
  }
 
  /**
   * Get <em>all</em> {@link ComplexTerm}s connecting the given elements,
   * contained with the given container element or any of its children,
   * with the given name.
   *
   * @param name the name to search for
   * @return the found {@link ComplexTerm}s
   * @throws JaxenException
   */
  protected static Set<ComplexTerm> getComplexTermsFromTo(EObject container, Function from, ConditionEdgeDestination to, String name) throws JaxenException {
    Set<ComplexTerm> result = new HashSet<ComplexTerm>();
   
    for (ComplexTerm w : from.getConditioned()) {
      if (to.equals(w.getConditioned())) {
        result.add(w);
      }
    }
   
    return result;
  }
 
  /**
   * Get <em>all</em> ExtendsEdge connecting the given elements,
   * contained with the given container element or any of its children.
   *
   * @return the found ExtendsEdges
   * @throws JaxenException
   */
  protected static Set<ExtendsEdge> getExtendsEdgesFromTo(EObject container, ExtendsEdgesSource from, ExtendsEdgeDestination to) throws JaxenException {
    Set<ExtendsEdge> result = new HashSet<ExtendsEdge>();

    for (ExtendsEdge w : from.getOutExtendsEdges()) {
      if (to.equals(w.getTo())) {
        result.add(w);
      }
    }
   
    return result;
  }

  /**
   * Get <em>all</em> RequiresEdges connecting the given elements,
   * contained with the given container element or any of its children.
   *
   * @return the found RequiresEdges
   * @throws JaxenException
   */
  protected static Set<RequiresEdge> getRequiresEdgesFromTo(EObject container, RequiresEdgesSource from, RequiresEdgeDestination to) throws JaxenException {
    Set<RequiresEdge> result = new HashSet<RequiresEdge>();
   
    for (RequiresEdge w : from.getOutRequiresEdges()) {
      if (to.equals(w.getTo())) {
        result.add(w);
      }
    }
   
    return result;
  }

  /**
   * Get all of the wires connecting the two elements together of any
   * class. Does not throw an error if there are no wires.
   *
   * @param container
   * @param fromElement
   * @param toElement
   * @return the wire found or throws an exception
   * @throws JaxenException
   * @see #getWiresFromTo(EObject, WireSource, WireDestination, Class)
   */
  protected static Set<Wire> getWiresFromTo(EObject container, WireSource fromElement, WireDestination toElement) throws JaxenException {
    return getWiresFromTo(container, fromElement, toElement, Wire.class);
  }
 
  /**
   * Get all of the wires connecting the two elements together of any
   * class. Does not throw an error if there are no wires.
   *
   * @param container
   * @param fromElement
   * @param toElement
   * @return the wire found or throws an exception
   * @throws JaxenException
   * @see #getWiresFromTo(EObject, WireSource, WireDestination, Class)
   */
  protected static Set<ECARule> getActionsFromTo(EObject container, ActionEdgeSource fromElement, Action toElement) throws JaxenException {
    return getECARulesFromTo(container, fromElement, toElement, ECARule.class);
  }
 
  /**
   * Get all of the wires connecting the two elements together of the
   * given class. Does not throw an error if there are no wires.
   *
   * @param container
   * @param fromElement
   * @param toElement
   * @return the wire found or throws an exception
   * @throws JaxenException
   */
  protected static Set<Wire> getWiresFromTo(EObject container, WireSource fromElement, WireDestination toElement, Class<? extends Wire> type) throws JaxenException {
    Set<Wire> results = new HashSet<Wire>();
    for (Wire w : fromElement.getOutWires()) {
      if (type.isInstance(w) && w.getTo().equals(toElement)) {
        results.add(w);
      }
    }

    return results;
  }
 
  /**
   * Get all of the ECARules connecting the two elements together of the
   * given class. Does not throw an error if there are none.
   *
   * @param container
   * @param fromElement
   * @param toElement
   * @return the wire found or throws an exception
   * @throws JaxenException
   */
  protected static Set<ECARule> getECARulesFromTo(EObject container, ActionEdgeSource fromElement, Action toElement, Class<? extends ECARule> type) throws JaxenException {
    Set<ECARule> results = new HashSet<ECARule>();
    for (ECARule w : fromElement.getListeners()) {
      if (type.isInstance(w) && w.getTarget().equals(toElement)) {
        results.add(w);
      }
    }

    return results;
  }

  /**
   * Assert that there are no wires (contained in <code>container//iaml:wires</code>)
   * that connect the two given elements together.
   *
   * @param container
   * @param fromElement
   * @param toElement
   * @throws JaxenException
   */
  public static void assertHasNoWiresFromTo(EObject container, WireSource fromElement, WireDestination toElement) throws JaxenException {

    for (Wire w : fromElement.getWires()) {
      if (toElement.equals(w.getTo()))
        fail("Unexpected wire found from '" + w.getFrom() + "' to '" + w.getTo() + "'");
    }
   
    // no wires found: pass
  }


  /**
   * Assert that there are no wires (contained in <code>container//iaml:wires</code>)
   * that connect the two given elements together with the given wire class.
   *
   * @param container
   * @param fromElement
   * @param toElement
   * @throws JaxenException
   */
  public static void assertHasNoWiresFromTo(EObject container, WireSource fromElement, WireDestination toElement, Class<? extends Wire> wireClass) throws JaxenException {
    for (Wire wire : getWiresFromTo(container, fromElement, toElement)) {
      if (wireClass.isInstance(wire)) {
        fail("Found wire '" + wire + "' (" + wireClass + ") from '" + fromElement + "' to '" + toElement + "'");
      }
    }
   
    // pass
  }

 
  /**
   * Assert that only the given number of wires exist between
   * the source and the target.
   *
   * @param count
   * @param container
   * @param fromElement
   * @param toElement
   * @return
   * @throws JaxenException
   * @return the found wires
   */
  public static Set<Wire> assertHasWiresFromTo(int count, EObject container,
      WireSource fromElement, WireDestination toElement) throws JaxenException {

    Set<Wire> wires = getWiresFromTo(container, fromElement, toElement);
    if (wires.size() != count) {
      for (Wire wire : wires) {
        System.err.println(wire);
      }
      assertEquals("Expected " + count + " wires between [" + fromElement + "] and [" + toElement + "], found: " + wires.size(), count, wires.size());
    }
    return wires;
   
  }
 
  /**
   * It's not possible to do something like //iaml:wire[iaml:from='id']
   * so we need to parse them manually.
   *
   * @param container
   * @param toElement
   * @return the wire found or null
   * @throws JaxenException
   */
  protected static List<Wire> getWiresTo(EObject container, WireDestination toElement) throws JaxenException {
    assertFalse("No wires found to [" + toElement + "]", toElement.getInWires().isEmpty());
   
    return toElement.getInWires();
  }
 
  /**
   * It's not possible to do something like //iaml:wire[iaml:from='id']
   * so we need to parse them manually.
   *
   * @param container
   * @param fromElement
   * @return the wire found or null
   * @throws JaxenException
   */
  protected static List<Wire> getWiresFrom(EObject container, WireSource fromElement) throws JaxenException {
    assertFalse("No wires found from [" + fromElement + "]", fromElement.getOutWires().isEmpty());
   
    return fromElement.getOutWires();   
  }

  protected static void assertNoWiresFrom(EObject container, WireSource fromElement, Class<? extends Wire> cls) throws JaxenException {
    for (Wire w : fromElement.getOutWires()) {
      if (cls.isInstance(w)) {
        fail("Unexpectedly found wire '" + w + "' of type '" + cls + "' from element '" + fromElement + "'");
      }
    }
  }

  protected static void assertNoECARulesFrom(EObject container, ActionEdgeSource fromElement, Class<? extends ECARule> cls) throws JaxenException {
    for (ECARule w : fromElement.getListeners()) {
      if (cls.isInstance(w)) {
        fail("Unexpectedly found action '" + w + "' of type '" + cls + "' from element '" + fromElement + "'");
      }
    }
  }
 
  /**
   * Get all wires to the given element of the given EObject type.
   *
   * @param container
   * @param toElement
   * @param type
   * @return
   * @throws JaxenException
   */
  protected static List<?> getWiresTo(EObject container, WireDestination toElement, Class<? extends Wire> type) throws JaxenException {
    return typeSelect(getWiresTo(container, toElement), type);
  }
 
  /**
   * Get all wires from the given element of the given EObject type.
   *
   * @param container
   * @param fromElement
   * @param type
   * @return
   * @throws JaxenException
   */
  protected static List<?> getWiresFrom(EObject container, WireSource fromElement, Class<? extends Wire> type) throws JaxenException {
    return typeSelect(getWiresFrom(container, fromElement), type);
  }
 
  /**
   * Get all elements of the set which are instances of the given
   * type.
   *
   * @param collection
   * @param type
   * @return
   */
  public static Set<Object> typeSelect(Set<? extends Object> collection, Class<? extends Object> type) {
    Set<Object> result = new HashSet<Object>();
    for (Object o : collection) {
      if (type.isInstance(o))
        result.add(o);
    }
    return result;
  }

  /**
   * For bidirectional wires.
   *
   * @param container
   * @param element1
   * @param element2
   * @return the wire found or null
   * @throws JaxenException
   */
  protected static Wire getWireBidirectional(EObject container, WireSource element1, WireSource element2) throws JaxenException {
    Set<Wire> wires = getWiresBidirectional(container, element1, element2);
    assertFalse("No wire found between [" + element1 + "] and [" + element2 + "]", wires.isEmpty());
    return wires.iterator().next();
  }
 
  /**
   * For bidirectional wires, get all wires connecting the
   * two elements.
   *
   * @see #getWiresBidirectional(EObject, WireSource, WireDestination, Class)
   * @param container
   * @param element1
   * @param element2
   * @throws JaxenException
   */
  protected static Set<Wire> getWiresBidirectional(EObject container, WireSource element1, WireSource element2) throws JaxenException {
    return getWiresBidirectional(container, element1, element2, Wire.class);
  }

  /**
   * For bidirectional wires, get all wires connecting the
   * two elements, with the given type.
   */
  protected static Set<Wire> getWiresBidirectional(EObject container, WireSource element1, WireSource element2, Class<? extends Wire> type) throws JaxenException {
    Set<Wire> edges = new HashSet<Wire>();
    for (Wire w : element1.getOutWires()) {
      if (type.isInstance(w)) {
        if (w.getFrom().equals(element1) && w.getTo().equals(element2))
          edges.add(w);
        if (w.getFrom().equals(element2) && w.getTo().equals(element1))
          edges.add(w);
      }
    }
    for (Wire w : element2.getOutWires()) {
      if (type.isInstance(w)) {
        if (w.getFrom().equals(element1) && w.getTo().equals(element2))
          edges.add(w);
        if (w.getFrom().equals(element2) && w.getTo().equals(element1))
          edges.add(w);
      }
    }

    return edges;
  }

  /**
   * Assert that a given number of bidirectional wires
   * occur between the two elements.
   *
   * @see #assertHasWiresFromTo(int, EObject, WireSource, WireSource)
   * @see #getWiresBidirectional(EObject, WireSource, WireSource)
   * @see #assertHasWiresBidirectional(int, EObject, WireSource, WireSource, Class)
   * @param container
   * @param element1
   * @param element2
   * @return the wires found
   * @throws JaxenException
   */
  public static Set<Wire> assertHasWiresBidirectional(int count, EObject container, WireSource element1, WireSource element2) throws JaxenException {
    return assertHasWiresBidirectional(count, container, element1, element2, Wire.class);
  }
 
  /**
   * Assert that a given number of bidirectional wires
   * occur between the two elements, with the given type.
   *
   * @return the wires found
   */
  public static Set<Wire> assertHasWiresBidirectional(int count, EObject container, WireSource element1, WireSource element2, Class<? extends Wire> type) throws JaxenException {
   
    Set<Wire> wires = getWiresBidirectional(container, element1, element2, type);
    if (wires.size() != count) {
      for (Wire wire : wires) {
        System.err.println(wire);
      }
      assertEquals("Expected " + count + " wires of type '" + type.getName() + "' connecting [" + element1 + "] and [" + element2 + "], found: " + wires.size(), count, wires.size());
    }
    return wires;
   
  }

  /**
   * Assert that no given bidirectional wire exists.
   *
   * @see #getWireBidirectional(EObject, WireSource, WireSource)
   * @param container
   * @param element1
   * @param element2
   * @throws JaxenException
   */
  public static void assertNoWireBidirectional(EObject container, WireSource element1, WireSource element2) throws JaxenException {
    Set<Wire> wires = getWiresBidirectional(container, element1, element2);
    assertEquals(0, wires.size());
  }
 
  /**
   * <p>When we infer a model, we could assert that it is valid
   * according to the checks. Generally, this is already called when
   * generating code from the inferred model.</p>
   *
   * <p>We are especially strict; we assert that there are no
   * errors <em>or warnings</em> in the result.</p>
   *
   * @throws Exception
   */
  public void checkModelIsValid(EObject root) throws Exception {
   
    IFile target = getProject().getFile( getInferredModel().getName() );
    assertFalse("File '" + target + "' should not exist", target.exists());
    copyFileIntoWorkspace(getInferredModel(), target);
    assertTrue("File '" + target + "' should now exist", target.exists());
   
    CheckModelInstance check = new CheckModelInstance();
    IStatus result = check.checkModel(root, getProject().getProject(), new NullProgressMonitor());
   
    ModelInferenceTestCase.assertStatusIsOK(result);
   
  }

  /**
   * Assert that the IStatus is ok.
   *
   * @param status the status to check
   * @see #assertStatusIsNotOK(IStatus)
   * @throws Exception if there was a Throwable in the IStatus
   */
  public static void assertStatusIsOK(IStatus status) throws Exception {
    if (!status.isOK()) {
      if (status.getException() != null) {
        // rethrow
        throw new RuntimeException(status.getMessage(), status.getException());
      }
     
      if (status.isMultiStatus()) {
        // build up the message to alert the developer
        MultiStatus ms = (MultiStatus) status;
        StringBuffer msg = new StringBuffer();
        msg.append("Status was not OK: [" + status.getPlugin() + "] " + status.getMessage());
        for (IStatus s : ms.getChildren()) {
          msg.append("\n").append(s.getMessage());
        }
        fail(msg.toString());
      }
     
      // default fail
      fail("Status was not OK: [" + status.getPlugin() + "] " + status.getMessage());
    }
  }
 
  /**
   * Assert that the IStatus is <em>not</em> ok.
   *
   * @param status the status to check
   * @see #assertStatusIsOK(IStatus)
   */
  public static void assertStatusIsNotOK(IStatus status) {
    if (status.isOK()) {
      // default fail
      fail("Status was unexpectedly OK: [" + status.getPlugin() + "] " + status.getMessage());
    }
  }
 
  /**
   * Get the "safe name" of the given element.
   *
   * TODO add a test case that makes sure this method is synchronised
   * with the one in the codegen extensions. OR add the safeName()
   * method to all elements in the model.
   *
   * @param e
   * @return
   */
  public String safeName(GeneratedElement e) {
    return e.getId().replaceAll("[^A-Za-z0-9]", "_");
  }

  /**
   * Get the file representing the saved post-inference model.
   *
   * @return
   */
  public File getInferredModel() {
    return inferer.getInferredModel();
  }

  @Override
  protected void tearDown() throws Exception {
    root = null;
   
    super.tearDown();
  }

  /**
   * Create a new InternetApplication in the given file.
   *
   * @param file
   */
  public InternetApplication createNewInternetApplication(File file) {

    ResourceSet resourceSet = new ResourceSetImpl();
    URI uri = URI.createFileURI(file.getAbsolutePath());
    Resource resource = resourceSet.createResource(uri);
    assertNotNull(resource);
    assertEquals("The new model should be empty.", 0, resource.getContents().size());

    // create a new object
    InternetApplication a = ModelFactory.eINSTANCE.createInternetApplication();
    resource.getContents().add(a);
   
    // return
    return a;
  }
 
  /**
   * Save the changed, inferred model to a file for later reference.
   *
   * @throws FileNotFoundException
   * @throws IOException
   * @returns the generated model file
   */
  public File saveInferredModel(Resource resource) throws FileNotFoundException, IOException {
    // check that the inference folder exists
    File folder = new File("infer-output/");
    if (!(folder.exists() && folder.isDirectory())) {
      // make it
      boolean successful = folder.mkdir();
      if (!successful)
        throw new IOException("Could not make folder '" + folder + "'");
    }
   
    // it should now exist
    if (!folder.exists()) {
      throw new RuntimeException("Folder '" + folder + "' did not exist.");
    }
    if (!folder.isDirectory()) {
      throw new RuntimeException("Folder '" + folder + "' was not a directory.");
    }
   
    File tempJavaFile = new File("infer-output/" + this.getClass().getSimpleName() + ".iaml");
    Map<?,?> options = resource.getResourceSet().getLoadOptions();
    resource.save(new FileOutputStream(tempJavaFile), options);
    System.out.println("inferred model saved to: " + tempJavaFile.getAbsolutePath());
    return tempJavaFile;
  }
 
  /**
   * Save the model stored in the given resource to the given file.
   *
   * @param resource
   * @param file
   * @throws IOException
   * @throws FileNotFoundException
   */
  public void saveModel(Resource resource, File file) throws FileNotFoundException, IOException {
   
    // save the model   
    Map<?,?> options = resource.getResourceSet().getLoadOptions();
    resource.save(new FileOutputStream(file), options);
    System.out.println("inferred model saved to: " + file.getAbsolutePath());
  }
 
}
TOP

Related Classes of org.openiaml.model.tests.ModelInferenceTestCase

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.