package com.openMap1.mapper.mapping; import com.openMap1.mapper.util.messageChannel; import com.openMap1.mapper.writer.XSLGenerator; import com.openMap1.mapper.core.MapperException; import com.openMap1.mapper.ModelAssocFilter; import com.openMap1.mapper.ModelFilter; import com.openMap1.mapper.ModelPropertyFilter; import com.openMap1.mapper.ObjMapping; import java.util.Vector; import java.util.Iterator; /** * An object mapping - defines how an object of some class is represented in XML * <p> * * This is a wrapper for the model class ObjMapping. * @author Robert Worden * @version 1.0 */ public class objectMapping extends MappingTwo { ObjMapping oMap() {return (ObjMapping)map();} // object mappings have no link conditions, as they only involve one node private Vector<filter> inclusionFilters = new Vector<filter>(); /** inclusion filters saying which objects in the class are represented by this node */ public Vector<filter> inclusionFilters(){return inclusionFilters;} private boolean isUnique = true; /** true if theXML represents each object uniquely, i.e. does not represent multiple copies of the same object */ public boolean isUnique() {return isUnique;} /** add an inclusion filter saying which objects in the class are represented by this node */ public void addInclusionFilter(filter f) {inclusionFilters.addElement(f);} /** set to true if theXML represents each object uniquely, i.e. does not represent multiple copies of the same object */ public void setIsUnique(boolean is) {isUnique = is;} private boolean isParameterMapping = false; // for mapping modules /** a parameter mapping of a mapping module */ public boolean isParameterMapping() {return isParameterMapping;} /** * make this a parameter mapping only if isParam = 'true' * * @param isParam String */ public void setIsParam(String isParam) {if (isParam.equals("true")) isParameterMapping = true;} /** * when generating XSLT with imported mapping sets in the input * @return full XPath from the root to this mapping - longer than the piece * within this mapping set */ public String getFullXPath() {return fullXPath;} private String fullXPath = ""; /** * when generating XSLT with imported mapping sets in the input * set the full XPath from the root to this mapping - longer than the piece * within this mapping set */ public void setFullXPath(String fullXPath) {this.fullXPath = fullXPath;} /** * @param om the ObjMapping in the EMF model * @param mc for writing out messages */ public objectMapping(ObjMapping om, messageChannel mc) throws MapperException { super(om, mc); mappingType = MappingTwo.OBJECT; if (oMap().getModelFilterSet() != null) for (Iterator<ModelFilter> it = oMap().getModelFilterSet().getModelFilters().iterator();it.hasNext();) { ModelFilter mf = it.next(); if (mf instanceof ModelPropertyFilter) {addInclusionFilter(new filterProp(mChan(),(ModelPropertyFilter)mf,oMap().getClassSet()));} else if (mf instanceof ModelAssocFilter) {addInclusionFilter(new filterAssoc(mChan(),(ModelAssocFilter)mf,oMap().getClassSet()));} } } /** write a text description of the object mapping */ public void write() { mChan().message(""); mChan().message("Object mapping of class " + cSet().stringForm() + " to node " + nodePath().stringForm()); writeConditions(); } /** vector of association filters (one type of inclusion filter) */ public Vector<filterAssoc> filterAssocs() { Vector<filterAssoc> res = new Vector<filterAssoc>(); int i; filter filt; for (i = 0; i < inclusionFilters.size(); i++) { filt = inclusionFilters.elementAt(i); if (filt instanceof filterAssoc) {res.addElement((filterAssoc)filt);} } return res; } /** vector of property filters (one type of inclusion filter) */ public Vector<filterProp> filterProps() { Vector<filterProp> res = new Vector<filterProp>(); int i; filter filt; for (i = 0; i < inclusionFilters.size(); i++) { filt = inclusionFilters.elementAt(i); if (filt instanceof filterProp) {res.addElement((filterProp)filt);} } return res; } /** true if the set of filters for this object mapping is mutually exclusive with the set of filters for some other object mapping - i.e if no object can satisfy both sets at once. Appropriate when the object mappings are for different subsets of the same class. */ public boolean exclusiveFilters(objectMapping om) { int i,j; filterProp f1,f2; boolean res = false; for (i = 0; i < filterProps().size(); i++) { f1 = filterProps().elementAt(i); for (j = 0; j < om.filterProps().size(); j++) { f2 = om.filterProps().elementAt(j); if (f1.mutuallyExclusive(f2)) res = true; } } return res; } /** short text description */ public String description() { return("mapping for class '" + className() + "'"); } /** * A vector of association inclusion filters that must be included in XSLT, * i.e excluding any that use the same association just navigated to get the object. * * @param inputAssoc associationMapping association just navigated to get the object, or null if none was navigated * @return Vector of all other association filters */ public Vector<filterAssoc> filterAssocsForXSLT(AssociationMapping inputAssoc) throws MapperException { Vector<filterAssoc> filters = new Vector<filterAssoc>(); for (int i = 0; i < filterAssocs().size(); i++) { boolean checkNeeded = true; filterAssoc fa = filterAssocs().elementAt(i); if (inputAssoc != null) // if this object was got by navigating an association... { // and if the navigated association is the same as the association filter... if ((fa.cSet1().className().equals(inputAssoc.assocEnd(0).className())) && (fa.cSet2().className().equals(inputAssoc.assocEnd(1).className())) && (fa.assocName().equals(inputAssoc.assocName()))) checkNeeded = false; // ...then it is not necessary to check the association filter } if (checkNeeded) { filters.addElement(fa); } } return filters; } /** this is called on an output XML mapping, looking at the input mappings * to construct the XPath expression for the output property inclusion filters in terms of input XPaths. * if the input property mapping has a default, check that against the required value. */ public String XPathPropertyInclusionFilter(XSLGenerator XX, objectMapping inputObject) throws MapperException { propertyMapping pm = null; String res = ""; if (filterProps().size() > 0) { res = "["; for (int i = 0; i < filterProps().size(); i++) { filterProp fp = filterProps().elementAt(i); // find input property mapping for the property used in the filter pm = XX.getInputPropertyMapping(inputObject.XSLCSet(),fp.property()); if (!(fp.test().equals("="))) { mChan().message("XSLT generation currently only supports '=' tests in inclusion filters."); } else { if (i > 0) res = res + " and "; String XPath = null; // for fixed property mappings, use the fixed value in stead of the XPath if (pm.fixed()) XPath = "'" + pm.value() + "'"; // non-fixed property mappings have a non-null object-to-property path else { XPath = XX.convertPathPrefixes(pm.objectToProperty().stringForm()); XPath = XPath + pm.XPathWhenTests(XX) + pm.XPathLinkTests(XX,true,null); } String cond = "(" + XPath + " = " + "'" + fp.value() + "')"; // if the property is not given in the input, and has the required default, let it pass if ((pm.hasDefault()) && (pm.defaultValue().equals(fp.value()))) {cond = "(" + cond + " or ((not (" + XPath + "))))";} res = res + cond; } } res = res + "]"; } return res; } /** to write this mapping out to an XML file (without its XPath) */ /* public Element objectMapEl(XMLFile xf) { Element objEl = xf.NSElement(MDLPrefix(),"object",MDLURI()); objEl.setAttribute("class",className()); if (!subset().equals("")) objEl.setAttribute("subset",subset()); addXMLConditions(objEl); // add when-conditions return objEl; } */ }