package com.openMap1.mapper.reader; import com.openMap1.mapper.core.ClassSet; import com.openMap1.mapper.core.MDLReadException; import com.openMap1.mapper.core.MDLWriteException; import com.openMap1.mapper.core.MapperException; import com.openMap1.mapper.core.RunIssue; import com.openMap1.mapper.util.ModelUtil; import com.openMap1.mapper.util.Timer; import com.openMap1.mapper.util.XMLOutputFile; import com.openMap1.mapper.util.messageChannel; import com.openMap1.mapper.writer.XMLWriter; import com.openMap1.mapper.writer.objectGetter; import com.openMap1.mapper.MappedStructure; import org.eclipse.emf.ecore.EPackage; import org.w3c.dom.Element; import org.w3c.dom.Node; import java.util.Vector; import java.util.Hashtable; /** * This class can be subclassed to produce Java implementations * of XOReader (to read from XML into an object model) * and XMLWriter (to write from an object model to XML) * in cases where either the mappings have a regular structure * or you want to do something that mappings will not do. * * This class provides two constructors that can be inherited * (for the reader and writer implementations respectively) * and implementations of some of the more boring methods in the XOReader * interface. * * @author robert * */ abstract public class AbstractReaderWriter implements XOReader, objectGetter, XMLWriter{ protected Element XMLFileRoot; protected MappedStructure ms; protected EPackage classModel; protected messageChannel mChan; protected objectGetter oGet; protected boolean doRunTracing; protected XMLOutputFile xout; private Timer timer; public Timer timer() {return timer;} /** * Give this XOReader or XMLWriter a timer, so the times it takes for different operations * can be reported alongside other times. */ public void giveTimer(Timer newTimer, boolean addTimes) { if ((addTimes) && (timer != null)) newTimer.addTimes(timer); timer = newTimer; } //-------------------------------------------------------------------------------------------- // Constructors //-------------------------------------------------------------------------------------------- /** * Constructor for implementations of XOReader, objectGetter */ public AbstractReaderWriter(Element XMLFileRoot, MappedStructure ms, EPackage classModel, messageChannel mChan) throws MapperException { this.XMLFileRoot = XMLFileRoot; this.ms = ms; this.classModel = classModel; this.mChan = mChan; timer = new Timer("Reader"); } /** * Constructor for use as an XMLWriter * @param oGet * @param ms * @param classModel * @param mChan * @param doRunTracing * @throws MapperException */ public AbstractReaderWriter(objectGetter oGet, MappedStructure ms, EPackage classModel, messageChannel mChan, Boolean doRunTracing) throws MapperException { this.oGet = oGet; this.ms = ms; this.classModel = classModel; this.mChan = mChan; this.doRunTracing = doRunTracing.booleanValue(); timer = new Timer("Writer"); } //-------------------------------------------------------------------------------------------- // Data retrieval methods //-------------------------------------------------------------------------------------------- // the root of the Ecore class model which the document is mapped to public EPackage classModel() {return classModel;} /** * Vector of objectTokens for all nodes representing objects * in any subclasses of a given class, in all subsets of those subclasses. * * @param className - the name of the class * @exception MDLReadException - class not represented in the XML * - you ignored some exception on creating XOReader */ abstract public Vector<objectToken> getAllObjectTokens(String className) throws MapperException; /** * return a Vector of objectTokens for all objects in the class which you want written out * in an XML document by OXWriter. * These must represent each distinct object only once. * The implementation here assumes the Java class returns each distinct object only once */ public Vector<objectToken> getObjects(String className) throws MapperException {return getAllObjectTokens(className);} /** * For use by EMFInstanceFactory * @param className * @return * @throws MapperException */ public Vector<objectToken> getAllLocalObjectTokens(String className) throws MapperException {return getAllObjectTokens(className);} /** * String value of a property of some represented object * * @param oRep - the objectToken for the object * @param propertyName - the name of the property * * @exception MDLReadException - XML does not represent the property for this class * - XML does not represent the property for this instance * - XML represents multiple values for the property * - Java class or method for a property format conversion cannot be found * - An input value for a property format conversion is not represented */ abstract public String getPropertyValue(objectToken oTok, String propertyName) throws MapperException; /** * Vector of objectTokens representing objects related to the current object by some association. * * @param oRep - the input object at one end of the association * @param assocName - name of the association * @param otherClass - class or superclass of the objects to be retrieved * @param otherRole - the role played by the other-end object in the association * * @exception MDLReadException - any argument null * - the XML does not represent the association between the classes */ public Vector<objectToken> getAssociatedObjectTokens(objectToken oTok, String otherClass, String otherRole) throws MapperException { String assocName = ModelUtil.getAssociationName(oTok.className(), otherRole, otherClass,ms()); return getTheAssociatedObjectReps(oTok,assocName, otherClass, -1, otherRole); } /** * Vector of objectTokens representing objects related to the current object by some association. * * @param oRep - the input object at one end of the association * @param assocName - name of the association * @param otherClass - class or superclass of the objects to be retrieved * @param thisEnd - end of the association for the input object, = 1 or 2 * * @exception MDLReadException - any argument null * - the XML does not represent the association between the classes */ public Vector<objectToken> getAssociatedObjectTokens(objectToken oTok, String assocName, String otherClass, int thisEnd) throws MapperException { return getTheAssociatedObjectReps(oTok,assocName,otherClass, thisEnd, ""); } /** * return a Vector of objectTokens for objects related to this object by some association * Throw a notRepresentedException if the source does not represent the association or * the class at the other end. * If anything else goes wrong, throw an MDLReadException. * @param oneOrTwo: end of the association which we are starting from * This method is just a simple renaming of a method above, required for * the objectGetter interface. */ public Vector<objectToken> getAssociatedObjects(objectToken oTok, String relation, String otherClass, int oneOrTwo) throws MapperException { return getAssociatedObjectTokens(oTok, relation, otherClass,oneOrTwo); } /** * Main method for following associations through mappings; the other two methods in the XOReader * interface can be got by simple calls to this method, as shown in MDLXOReader. * * @param oTok object token for the start object * @param assocName association name, usually composed from the two end role names * @param otherClass qualified class name at the target end of the association * @param thisEnd end of the start object, if the role name is not specified; or -1 if it is * @param otherRole role name leading to the target end; or "" if not specified * @return object tokens for objects reached by the association * @throws MapperException */ abstract public Vector<objectToken> getTheAssociatedObjectReps(objectToken oTok, String assocName, String otherClass, int thisEnd, String otherRole) throws MapperException; public void setRoot(Node el) throws MapperException {XMLFileRoot = (Element)el;} abstract public String parameterClassName() throws MapperException; public MappedStructure ms() {return ms;} //-------------------------------------------------------------------------------------------- // metaData methods //-------------------------------------------------------------------------------------------- public boolean checkIsRepresented(String className) {return representsObject(className);} abstract public boolean representsObject(String className); abstract public boolean representsProperty(String className,String property); abstract public boolean representsProperty(objectRep oRep,String property); public boolean representsPropertyLocally(String className,String property) {return representsProperty(className, property);} abstract public boolean representsAssociationRole(String class1, String roleName, String class2); abstract public boolean representsAssociationRole(objectRep oRep, String roleName, String class2); public boolean representsAssociationRoleLocally(String class1, String roleName, String class2) {return representsAssociationRole(class1, roleName, class2);} abstract public boolean representsAssociation(String class1, String assocName, String class2); abstract public Hashtable<String,ClassSet> subsets(String className); abstract public Vector<String> getQualifiedClassNames(String bareClassName); //------------------------------------------------------------------------------------------- // For use by EMFInstanceFactory //------------------------------------------------------------------------------------------- /** * @return ClassSets of all object mappings in this mapping set (not imported) that * are not inside a containment relation to some other class * which also has an object mapping to the top mapping set * Key = string form of the [class,subset]. */ abstract public Vector<ClassSet> outerObjectClassSets(); //------------------------------------------------------------------------------------------- // XMLWriter interface //------------------------------------------------------------------------------------------- /** * write the object model information from the objectGetter (set in the constructor) * to an output XML * * @return the root Element of the created XML document * @exception MDLWriteException - any major problem detected in making the translation */ abstract public Element makeXMLDOM() throws MapperException; /** * Extend some Element of an output XML DOM (which represents some object * in the object model, or has an ancestor element which represents that object) * producing a subtree which represents the properties of that object, subordinate * objects related to it, and their properties. * * @param bareElement the Element to be extended * @param oTok objectToken for the parameter class object, which the Element * to be extended (or one of its ancestors) represents * @return the extended Element * @throws MapperException if there is any major problem */ abstract public Element extendXMLDOM(Element bareElement, objectToken oTok) throws MapperException; /** * All issues that were noted when running the translation * or generating XSLT. * outer key = string form of root path * Inner key = a unique identifier for the issue * @return */ abstract public Hashtable<String,Hashtable<String,RunIssue>> allRunIssues(); /** * set the XML Output file for the writer * @param xout */ public void setXMLOutputFile(XMLOutputFile xout) {this.xout = xout;} }