package ever.workflowRepresentation; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Stack; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import ever.pipeline.XmlHandler; /** * This is the main class used to represent products. * @author Pol Schumacher, Wirtschaftsinformatik, Institut fuer Informatik, Goethe Universitaet Frankfurt * */ public class SimpleProduct extends Product { public static int notFoundCounter = 0; public static int foundCounter = 0; /** * The name of the product */ private String name; /** * This field was used for anaphora resolution. Its true when the product was detected as anaphora. * It has no use for most filters. */ private boolean isAna; // private final HashSet originalProdList = XmlHandler // .getProductList(); /** * All the facets related to the product */ private Stack facets; /** * Stores the task related facets. A task related facet is a facet of product that might depend on the task. * For example the amount of an ingredient can be a task related facet because it can change with the task */ private HashMap> taskRelatedFacets; private int taskId; /** * ThreadLocal items are used to replace the static items of the first class * version. This enables correct multithreading behavior */ private static ThreadLocal> allProducts = new ThreadLocal>() { protected synchronized ArrayList initialValue() { return new ArrayList(); } }; /** * ThreadLocal items are used to replace the static items of the first class * version. This enables correct multithreading behavior */ private static ThreadLocal lastId = new ThreadLocal() { protected synchronized Integer initialValue() { return new Integer(-1); } }; /** * Standard constructor for a simple product * @param name The name of the product * @param taskId The id of task which contains this product * @throws EmptyProductException Is thrown when the product is empty. * @throws NotAProductException Is thrown when detected that its not a product. */ public SimpleProduct(String name, int taskId) throws EmptyProductException, NotAProductException { super(); taskRelatedFacets = new HashMap>(); int ld = lastId.get(); ld++; lastId.set(ld); facets = new Stack(); this.taskId = taskId; setName(name); if (name.length() == 0) throw new NotAProductException(name); ArrayList all = SimpleProduct.allProducts.get(); all.add(this); SimpleProduct.allProducts.set(all); } public SimpleProduct() { super(); } /** * Returns the next facet of the product */ public Facet getNextFacet() { if (facets.size() != 0) return facets.pop(); else return null; } /** * If it was detected that this product is an anaphora it is set true; */ public void setAnaTrue() { isAna = true; } /** * Returns true if product is anaphora * @return */ public boolean isAnaphora() { return isAna; } // /** // * Get all products as Hashset // * @return // */ // public static HashSet getAllProducts() { // HashSet hs = new HashSet(); // ArrayList all = SimpleProduct.allProducts.get(); // for (Product p : all) // hs.add(p); // // return hs; // } // /** // * Clear products // */ // public static void clearProducts() { // ArrayList all = new ArrayList(); // SimpleProduct.allProducts.set(all); // HashMap used = new HashMap(); // SimpleProduct.used.set(used); // SimpleProduct.lastId.set(-1); // // } /** * Returns the name of the product */ public String getName() { return name; } /** * Sets name of the product */ public void setName(String name) throws EmptyProductException { name = name.trim(); this.name = name; if (name.equals("")) { throw new EmptyProductException(); } // HashSet fa = null; // NumericValueExtractor ne = new NumericValueExtractor(); // fa = ne.getSI(name); // for (String e : fa) { // String[] split = e.split(" "); // if (split.length > 1) { // addTaskRelatedFacet(new SimpleFacet(split[1], split[0]), taskId); // addTaskRelatedFacet( // new SimpleFacet("UnitSourceText", // ne.getUnitExtractionSource()), taskId); // } else { // addTaskRelatedFacet(new SimpleFacet("quantity", split[0]), // taskId); // addTaskRelatedFacet( // new SimpleFacet("UnitSourceText", // ne.getUnitExtractionSource()), taskId); // } // } // // this.name = ne.getName(); // this.name = cleanProductName(this.name); // if (this.name.equals("")) { // throw new EmptyProductException(); // } else { // matchProduct(); // } } // public int getId() { // return SimpleProduct.allProducts.get().indexOf(this); // } // Adds facet to the facet set of a product /** * Adds a facet to the product * * @param f * Facet to be added */ public void addFacet(Facet f) { facets.add(f); } // add facet to facet set with the context of the current task /** * Add a facet that is linked to a task, * * @param f * Facet to be added * @param id * id of the task that should be linked to the facet */ public void addTaskRelatedFacet(SimpleFacet f, int id) { if (taskRelatedFacets.containsKey(id)) { HashSet tmp = taskRelatedFacets.get(id); tmp.add(f); taskRelatedFacets.put(id, tmp); } else { HashSet tmp = new HashSet(); tmp.add(f); taskRelatedFacets.put(id, tmp); } } /** * Write the xml representation of an option to the XMLStreamWriter * @param writer * @throws XMLStreamException */ public void exportWf2Xml(XMLStreamWriter writer, int id) { try { // currently write no semantic informations out writer.writeStartElement("rwfl:DataRef"); writer.writeCharacters(getName()); // writer.writeComment("\n" + getName()); writer.writeEndElement(); if (taskRelatedFacets.containsKey(id)) { writer.writeStartElement("rwfl:DataRef"); writer.writeAttribute("refID", getId() + ""); writer.writeStartElement("rwfl:SemanticDescription"); writer.writeStartElement("cdol:Agg"); writer.writeAttribute("c", "DataRefSemantic"); for (Facet f : taskRelatedFacets.get(id)) { f.exportWf2Xml(writer); } writer.writeEndElement(); writer.writeEndElement(); writer.writeEndElement(); } else { writer.writeEmptyElement("rwfl:DataRef"); writer.writeAttribute("refID", getId() + ""); } writer.writeCharacters("\n"); } catch (XMLStreamException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // public void exportWf2XmlArt(XMLStreamWriter writer) { // try { // // writer.writeEmptyElement("rwfl:DataRef"); // writer.writeAttribute("refID", // SimpleProduct.used.get().get(Integer.parseInt(this.name)) // + ""); // writer.writeCharacters("\n"); // } catch (XMLStreamException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // } /** * Write a list of all products to xml * @param writer * @throws XMLStreamException */ public void exportProd2List(XMLStreamWriter writer) throws EmptyProductException { try { writer.writeStartElement("rwfl:DataflowWrapper"); writer.writeAttribute("refID", "" + getId()); writer.writeCharacters("\n"); writer.writeStartElement("rwfl:DataflowElement"); writer.writeStartElement("cdol:Agg"); writer.writeAttribute("c", "DataflowElement"); writer.writeEmptyElement("cdol", "AA", "http://cake.wi2.uni-trier.de/xml/cdol"); writer.writeAttribute("n", "name"); if (getName().length() == 0) { throw new EmptyProductException(); } else { writer.writeAttribute("v", getName()); } if (facets.size() > 0) { for (Facet f : facets) { f.exportWf2Xml(writer); } } writer.writeEndElement(); writer.writeCharacters("\n"); writer.writeEndElement(); writer.writeCharacters("\n"); // Changes made on the 27/07 for CCC // if (facets.size() > 0) { // writer.writeStartElement("rwfl:SemanticDescription"); // writer.writeStartElement("cdol:Agg"); // writer.writeAttribute("c", "SemanticDescription"); // // for (Facet f : facets) { // f.exportWf2Xml(writer); // } // writer.writeEndElement(); // writer.writeEndElement(); // } writer.writeEndElement(); writer.writeCharacters("\n"); } catch (XMLStreamException e) { e.printStackTrace(); } } // private void matchProduct() { // englishStemmer stemmer = new englishStemmer(); // // HashSet products = originalProdList; // NumericValueExtractor ne = new NumericValueExtractor(); // ne.getSI(this.name); // // String tmp = ne.getName(); // tmp = tmp.replaceAll("[^A-Za-z\\s]", ""); // String[] split = tmp.trim().toLowerCase().split(" "); // // HashSet currentProductTokenSet = new HashSet(); // for (String s : split) { // stemmer.setCurrent(s); // stemmer.stem(); // String stemmedString = stemmer.getCurrent(); // currentProductTokenSet.add(stemmedString); // } // // int maxMatchingTokenCounter = 0; // HashSet bun = new HashSet(); // String bestMatch = ""; // String bestSourceText = ""; // // for (String s : products) { // NumericValueExtractor nve = new NumericValueExtractor(); // HashSet un = nve.getSI(s); // String p = nve.getName(); // p = p.replace("_", " "); // p = p.replaceAll("[^A-Za-z\\s]", "").trim().toLowerCase(); // String[] sp = p.split(" "); // // int currentMatchingCounter = 0; // for (String s2 : sp) { // stemmer.setCurrent(s2); // stemmer.stem(); // String stemmedString = stemmer.getCurrent(); // if (currentProductTokenSet.contains(stemmedString)) { // currentMatchingCounter++; // } // // } // // if (maxMatchingTokenCounter < currentMatchingCounter) { // maxMatchingTokenCounter = currentMatchingCounter; // bestMatch = p; // bun = un; // bestSourceText = nve.getUnitExtractionSource(); // } // } // if (maxMatchingTokenCounter > 0) { // addFacet(new SimpleFacet("ProductListEntry", bestMatch)); // for (String s : bun) { // String[] sp = s.split(" "); // try { // addFacet(new SimpleFacet(sp[1], sp[0])); // addFacet(new SimpleFacet("UnitSourceText", bestSourceText)); // } catch (ArrayIndexOutOfBoundsException e) { // System.err.println(s); // } // } // foundCounter++; // } else { // notFoundCounter++; // } // // } // public static HashMap getUsedThreadLocal() { // return used.get(); // } // // public static void setUsedThreadLocal(HashMap used) { // SimpleProduct.used.set(used); // } public static Integer getLastIdThreadLocal() { return lastId.get(); } public static void setLastIdThreadLocal(Integer lastId) { SimpleProduct.lastId.set(lastId); } public static void setAllProductsThreadLocal(ArrayList allProducts) { SimpleProduct.allProducts.set(allProducts); } public static ArrayList getAllProductsThreadLocal() { return SimpleProduct.allProducts.get(); } public boolean isIngredient() { for (Facet f : facets) { SimpleFacet sf = (SimpleFacet) f; if (sf.getFacetDefinition().equals("Linked") & sf.getFacetValue().equals("ProductList")) return true; } return false; } @Override public int hashCode() { final int prime = 31; int result = 1+SimpleProduct.lastId.get(); result = prime * result + ((facets == null) ? 0 : facets.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; SimpleProduct other = (SimpleProduct) obj; if (facets == null) { if (other.facets != null) return false; } else if (!facets.equals(other.facets)) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } /** * Just that everything comiles no real use * @return */ public int getId() { return -1; } }