package com.openMap1.mapper.mapping; import com.openMap1.mapper.core.ClassSet; import com.openMap1.mapper.core.MapperException; import com.openMap1.mapper.util.ModelUtil; import com.openMap1.mapper.util.messageChannel; import com.openMap1.mapper.util.GenUtil; import com.openMap1.mapper.ModelAssocFilter; import java.util.Iterator; import java.util.Vector; /** * represents one association inclusion filter in an object mapping; * the object must be associated by the association in order to be represented in the XML * * This class is a wrapper around the model class ModelAssocFilter * * @author Robert Worden * @version 1.0 */ public class filterAssoc extends filter { private ClassSet cSet1,cSet2; // names of the two classes involved in the condition private String assocName; // name of the association private int otherEnd = 0; // the end of the association for the non-dependent object; = 1 or 2. private String otherRole; // the role name for the non-dependent object private String otherCName,otherSubset; String[] filterAtts = {"assocName","otherClass","otherSubset","otherEnd","otherRole"}; private boolean failToInclude; /** * @return true if the object should NOT have the association in order to be included */ public boolean failToInclude() {return failToInclude;} /** name of the association */ public String assocName() {return assocName;} /** (class,subset) at end 1 of the association */ public ClassSet cSet1() {return cSet1;} /** (class,subet) at end 2 of the association */ public ClassSet cSet2() {return cSet2;} /** the end of the association for the non-dependent object; = 1 or 2. */ public int otherEnd() {return otherEnd;} /** role name at the end of the association for the non-dependent object; = 1 or 2. */ public String otherRole() {return otherRole;} // called with an me:filterAssoc element as argument /** * called with an me:filterAssoc element as argument * @param md MDLBase * @param el Element an me:filterAssoc element * @param thisCSet ClassSet * @throws MDLReadException */ public filterAssoc(messageChannel mc, ModelAssocFilter maf, ClassSet thisCSet) throws MapperException { super(mc,thisCSet); otherCName = ModelUtil.getQualifiedClassName(GenUtil.gaplessForm(maf.getOtherClassName()), maf.getOtherPackageName()); otherSubset = GenUtil.gaplessForm(maf.getOtherSubset()); ClassSet otherCSet = new ClassSet(otherCName,otherSubset); setDepCSet(otherCSet); assocName = GenUtil.gaplessForm(maf.getAssocName()); otherRole = maf.getOtherRoleName(); // FIXME; we should not really use the description field to denote 'fail to include' associations failToInclude = ((maf.getDescription() != null)&& (maf.getDescription().startsWith("NOT"))); otherEnd = maf.getOtherEnd(); if (otherEnd == 1) { cSet1 = otherCSet; cSet2 = thisCSet; } else if (otherEnd == 2) { cSet2 = otherCSet; cSet1 = thisCSet; } else {throw new MapperException("Filter association end should be 1 or 2 but is '" + otherEnd + "'"); } } /** make a filter from a required association mapping where otherEnd (= 1 or 2) is not the end required to have that association. Beware - thisEnd is in the (0,1) convention .... */ public filterAssoc(messageChannel mc, AssociationMapping am, int thisEnd) throws MapperException { super(mc,am.assocEnd(thisEnd).cSet()); otherEnd = 2 - thisEnd; // 1 or 2 otherRole = am.assocEnd(otherEnd-1).roleName(); setDepCSet(am.assocEnd(otherEnd-1).cSet()); cSet1 = am.assocEnd(0).cSet(); cSet2 = am.assocEnd(1).cSet(); assocName = am.assocName(); } /** * described in the user manual as the constructor to use in an objectCapability. * thisEnd is in 1,2 convention. */ /* convert this constructor later public filterAssoc(MDLBase md, String thisClass, String assName, int thisEnd, String otherClass, String othRole) { super(md,new ClassSet(thisClass,"")); otherEnd = 3 - thisEnd; // 1 or 2 otherRole = othRole; ClassSet cThis = new ClassSet(thisClass,""); ClassSet cThat = new ClassSet(otherClass,""); setDepCSet(cThat); if (thisEnd == 1) {cSet1 = cThis; cSet2 = cThat;} else if (thisEnd == 2) {cSet2 = cThis; cSet1 = cThat;} assocName = assName; } */ /** * equality test * @param fa filterAssoc * @return boolean */ public boolean sameFilter(filterAssoc fa) { return ((cSet1().className().equals(fa.cSet1().className())) && (cSet2().className().equals(fa.cSet2().className())) && (assocName().equals(fa.assocName()))); } /** true if this filter is in a vector of filters */ public boolean inFilters(Vector<filter> filters) { int i; filter f; filterAssoc fa; boolean res = false; for (i = 0; i < filters.size(); i++) { f = (filter)filters.elementAt(i); if (f instanceof filterAssoc) { fa = (filterAssoc)f; if (sameFilter(fa)) res = true; } } return res; } /** write a readable form of the inclusion filter */ public void write() { String classSet = "null"; if (onCSet() != null) classSet = onCSet().stringForm(); String sign = ""; if (failToInclude()) sign = "NOT "; mChan().message("Class " + classSet + " requires " + sign + stringForm()); } /** string form of the association */ public String stringForm() { return ("[" + cSet1.stringForm() + "]" + assocName + "[" + cSet2.stringForm() + "]"); } public static Vector<filterAssoc> vCopy(Vector<filterAssoc> v) { Vector<filterAssoc> res = new Vector<filterAssoc>(); for (Iterator<filterAssoc> it = v.iterator();it.hasNext();) res.add(it.next()); return res; } }