package ever.workflowRepresentation; import java.util.ArrayList; import java.util.EmptyStackException; import java.util.HashMap; import java.util.HashSet; import java.util.Random; import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import net.sf.saxon.s9api.XdmNode; import ever.pipeline.Sentence; public class Task extends WorkflowElement { private String name; private ArrayList inProducts; private ArrayList outProducts; private ArrayList facets; /** * Is used to keep track if the dataflow was modified based on gsp algo. */ private boolean dataflowAgg = false; private static ThreadLocal> usedNames = new ThreadLocal>(){ protected synchronized HashMap initialValue() { return new HashMap(); } }; private int namePosition; public boolean wasMerged=false; /** * @param name * the name of the task */ public Task() { super(); outProducts = new ArrayList(); inProducts = new ArrayList(); facets = new ArrayList(); } /** * * @param parent element of task * @param s sentence of which the task was extracted * @param name name of the task */ public Task(WorkflowElement parent, Sentence s,String name) { this(parent,s); this.name = name.trim(); } public Task(WorkflowElement parent, Sentence s) { super(parent,s); outProducts = new ArrayList(); inProducts = new ArrayList(); facets = new ArrayList(); } /** * @return the name of the task */ public String getName() { return name; } /** * Checks if a task contains a product with a certain name * @param name * @return */ public boolean containsInProduct(String name) { boolean ret =false; for(Product p: inProducts) { if(p.getName().equals(name)) ret=true; } return ret; } /** * Checks if a task contains a product with a certain name * @param name * @return */ public boolean containsOutProduct(String name) { boolean ret =false; for(Product p: outProducts) { if(p.getName().equals(name)) ret=true; } return ret; } /** * Set the name of the task * @param name */ public void setName(String name) { // Necessary to get different HashCodes for the tasks with the same // values. String tmpname = name.trim(); tmpname = tmpname.toLowerCase(); if (usedNames.get().containsKey(tmpname)) { HashMap tmpMap=usedNames.get(); int tmpCount = tmpMap.get(tmpname); tmpCount++; tmpMap.put(tmpname, tmpCount); usedNames.set(tmpMap); namePosition = tmpCount; } else { namePosition = 0; HashMap tmpMap=usedNames.get(); tmpMap.put(tmpname, namePosition); usedNames.set(tmpMap); } this.name = tmpname; } /** * * @param p * a Product to add as new input product of the task */ public void addInProduct(Product p) { inProducts.add(p); } /** * * @return returns the next in product of the task */ public Product getNextInProduct() { if (inProducts.size() > 0) { Product p = inProducts.get(0); inProducts.remove(p); return p; } else return null; } /** * * @param prod * Removes the product from the list input-products. */ public void removeInProduct(Product prod) { inProducts.remove(prod); } /** * * @param prod * Removes the product from the list output-products. */ public void removeOutProduct(Product prod) { outProducts.remove(prod); } /** * * @param p * a Product to add as new output product of the task */ public void addOutProduct(Product p) { outProducts.add(p); } /** * * @return returns the next out product of the task */ public Product getNextOutProduct() { if (outProducts.size() > 0) { return outProducts.get(0); } else { return null; } } /** * Adds new facets to the task. A facet contains additional information * about the task. (e.g. until tender) * * @param f * facet to add */ public void addFacet(Facet fac) { facets.add(fac); } /** * Returns a facet of the task and deletes it. * * @return next facet of the task */ public Facet getNextFacet() { if (facets.size() != 0) return facets.get(0); else return null; } /** * Writes the task, its products and facet into the stream. It uses the * xml-format which was defined. * * @param writer * is the stream writer which is used to write */ public void exportWf2Xml(XMLStreamWriter writer) { try { writer.writeStartElement("rwfl:Task"); // writer.writeAttribute("refID", this.getId() + ""); // writer.writeAttribute("type", "WORKLISTTASK"); // writer.writeAttribute("status", "READY"); writer.writeStartElement("rwfl:SemanticDescription"); writer.writeStartElement("cdol:Agg"); writer.writeAttribute("c", "TaskSemantic"); writer.writeEmptyElement("cdol", "AA", "http://cake.wi2.uni-trier.de/xml/cdol"); writer.writeAttribute("n", "name"); if (this.name != null) writer.writeAttribute("v", this.name); else writer.writeAttribute("v", "unknownNameTask"); writer.writeCharacters("\n"); for (Facet fac : facets) { fac.exportWf2Xml(writer); } writer.writeEndElement(); writer.writeCharacters("\n"); writer.writeEndElement(); writer.writeCharacters("\n"); if (inProducts.size() > 0) { writer.writeStartElement("rwfl:input"); for (Product pro : inProducts) { pro.exportWf2Xml(writer, getId()); } writer.writeEndElement(); } writer.writeCharacters("\n"); if (outProducts.size() > 0) { writer.writeStartElement("rwfl:output"); for (Product pro : outProducts) { pro.exportWf2Xml(writer, this.getId()); } writer.writeEndElement(); } writer.writeEndElement(); writer.writeCharacters("\n"); } catch (XMLStreamException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // // Export fn for artificial workflow without complex Dataflow handling // /** // * Export method for random artificial workflow without complex Dataflow // * handling. // * // * @param writer // * is the stream writer which is used to write // */ // public void exportWf2XmlArti(XMLStreamWriter writer) { // try { // writer.writeStartElement("rwfl:Task"); // writer.writeAttribute("refID", this.getId() + ""); // writer.writeAttribute("type", "WORKLISTTASK"); // writer.writeAttribute("status", "READY"); // // writing in products // // if (inProducts.size() > 0) { // // writing facets // writer.writeStartElement("rwfl:SemanticDescription"); // writer.writeStartElement("cdol:Agg"); // writer.writeAttribute("c", "TaskSemantic"); // // writer.writeEmptyElement("cdol", "AA", // "http://cake.wi2.uni-trier.de/xml/cdol"); // writer.writeAttribute("n", "name"); // // if (this.name != null) // writer.writeAttribute("v", this.name); // else // writer.writeAttribute("v", "unknownNameTask"); // writer.writeCharacters("\n"); // // // // // for (Facet fac : facets) { // fac.exportWf2Xml(writer); // } // writer.writeEndElement(); // writer.writeCharacters("\n"); // writer.writeEndElement(); // writer.writeCharacters("\n"); // if (inProducts.size() > 0) { // writer.writeStartElement("rwfl:input"); // for (Product p : inProducts) { // SimpleProduct sp = (SimpleProduct) p; // sp.exportWf2XmlArt(writer); // } // writer.writeEndElement(); // } // // if (outProducts.size() > 0) { // writer.writeStartElement("rwfl:output"); // for (Product p : outProducts) { // SimpleProduct sp = (SimpleProduct) p; // sp.exportWf2XmlArt(writer); // } // writer.writeEndElement(); // } // // writer.writeEndElement(); // writer.writeCharacters("\n"); // // } catch (XMLStreamException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // } /** * Marks that this task aggreates products. */ public void setDataflowAggTrue() { dataflowAgg=true; } public boolean getDataflowAgg() { return dataflowAgg; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((facets == null) ? 0 : facets.hashCode()); result = prime * result + ((inProducts == null) ? 0 : inProducts.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + namePosition; result = prime * result + ((outProducts == null) ? 0 : outProducts.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; Task other = (Task) obj; if (facets == null) { if (other.facets != null) return false; } else if (!facets.equals(other.facets)) return false; if (inProducts == null) { if (other.inProducts != null) return false; } else if (!inProducts.equals(other.inProducts)) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (namePosition != other.namePosition) return false; if (outProducts == null) { if (other.outProducts != null) return false; } else if (!outProducts.equals(other.outProducts)) return false; return true; } /** * Merges two task. This is necessary if two tasks were created by two different filters which are potenitally the same task * but contain slightly different information * @param t1 first Task * @param t2 second Task * @return Merged Task */ public static Task merge(Task t1, Task t2) { Task mt = new Task(t1.getParentElement(), t1.relatedSentence,t1.getName()); mt.addFacet(new SimpleFacet("Test","Merge")); //First add into HashSet to remove duplicates Product p = t1.getNextInProduct(); HashSet tSet = new HashSet(); while (p != null) { tSet.add(p); p = t1.getNextInProduct(); } p = null; p = t2.getNextInProduct(); while (p != null) { tSet.add(p); p = t2.getNextInProduct(); } for(Product tp: tSet) { mt.addInProduct(tp); } tSet.clear(); p = null; p = t1.getNextOutProduct(); while (p != null) { tSet.add(p); p = t1.getNextOutProduct(); } p = null; p = t2.getNextOutProduct(); while (p != null) { tSet.add(p); p = t2.getNextOutProduct(); } for(Product tp: tSet) { mt.addOutProduct(tp); } HashSet tfSet=new HashSet(); for(Facet f : t1.getAllFacets()) { tfSet.add(f); f = t1.getNextFacet(); } for(Facet f : t2.getAllFacets()) { tfSet.add(f); f = t2.getNextFacet(); } for(Facet ft : tfSet) mt.addFacet(ft); return mt; } /** * Returns all input products * @return */ public ArrayList getAllInProducts() { return inProducts; } /** * Returns all facets * @return */ public ArrayList getAllFacets() { return facets; } /** * Replaces the ArrayList of input products by the parameter of the method * @param ip */ public void setAllInProducts(ArrayListip) { inProducts=ip; } /** * Replaces the ArrayList of output products by the parameter of the method * @param ip */ public void setAllOutProducts(ArrayListip) { outProducts=ip; } /** * Returns all output products * @return */ public ArrayList getAllOutProducts() { return outProducts; } /** * Creates a hard copy of the task * @return */ public Task copy() { Task t = new Task(this.getParentElement(),this.relatedSentence,this.getName()); for(Product p : inProducts) t.addInProduct(p); for(Product p : outProducts) t.addInProduct(p); for(Facet f : facets) t.addFacet(f); return t; } // // public static Task importTask(XdmNode node) // { // return null; // } }