| /******************************************************************************* |
| * Copyright (c) 2004-2008 Andras Schmidt, Andras Balogh, Istvan Rath and Daniel Varro |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Andras Schmidt, Andras Balogh, Istvan Rath - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.viatra2.imports; |
| |
| import java.io.InputStream; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| import java.util.Properties; |
| import java.util.Set; |
| import java.util.TreeMap; |
| import java.util.TreeSet; |
| |
| import javax.xml.parsers.SAXParser; |
| import javax.xml.parsers.SAXParserFactory; |
| |
| import org.eclipse.viatra2.core.EMultiplicityKind; |
| import org.eclipse.viatra2.core.IEntity; |
| import org.eclipse.viatra2.core.IModelElement; |
| import org.eclipse.viatra2.core.IModelManager; |
| import org.eclipse.viatra2.core.IModelSpace; |
| import org.eclipse.viatra2.core.IRelation; |
| import org.eclipse.viatra2.errors.VPMCoreException; |
| import org.eclipse.viatra2.errors.VPMRuntimeException; |
| import org.eclipse.viatra2.framework.properties.VPMProperties; |
| import org.xml.sax.Attributes; |
| import org.xml.sax.SAXException; |
| import org.xml.sax.SAXParseException; |
| import org.xml.sax.helpers.DefaultHandler; |
| |
| /** |
| * VPM model loader implementation. |
| * |
| * The loader first reads the whole file. The file is read by a SAX parser, so |
| * the loader builds the data read from the file as SAX events. |
| * |
| * Then builds the containment tree of all elements Then creates all elements |
| * Then sets the target of all relations Then creates the type relations |
| * |
| * @author Andras Schmidt |
| * |
| */ |
| public class VPMImporterSaxImpl extends DefaultHandler { |
| /** |
| * The string collected from text contents of xml file |
| */ |
| private StringBuffer collectedString = new StringBuffer(); |
| |
| /** |
| * Commands the parser to collect the text contents read from xml into the |
| * <code>collectedString</code> buffer |
| */ |
| private boolean collectString = false; |
| |
| /**
|
| *
|
| */ |
| private int stateField = 0; |
| |
| private int stateCollection = 0; |
| |
| private int stateElement = 0; |
| |
| private int stateModel = 0; |
| |
| private int stateParent = 0; |
| |
| private int stateModelElement = 0; |
| |
| // / Enumeratinos of states of the parser
|
| private static final int STATE_MODELELEMENT_OFF = 0; |
| |
| private static final int STATE_MODELELEMENT_ON = 1; |
| |
| private static final int STATE_PARENT_OFF = 0; |
| |
| private static final int STATE_PARENT_ENTITY = 1; |
| |
| private static final int STATE_FIELD_OFF = 0; |
| |
| private static final int STATE_FIELD_VALUE = 1; |
| |
| private static final int STATE_FIELD_NAME = 2; |
| |
| private static final int STATE_FIELD_PARENT = 3; |
| |
| private static final int STATE_FIELD_TYPE = 4; |
| |
| private static final int STATE_FIELD_TO = 7; |
| |
| private static final int STATE_FIELD_SUPERTYPE = 5; |
| |
| private static final int STATE_FIELD_FROM = 6; |
| |
| private static final int STATE_FIELD_VIEW_INFO = 8; |
| |
| private static final int STATE_FIELD_MULTIPLICITY = 9; |
| |
| private static final int STATE_FIELD_ISAGGREGATION = 10; |
| |
| private static final int STATE_FIELD_INVERSE = 11; |
| |
| private static final int STATE_FIELD_ISFINALTYPE = 12; |
| |
| private static final int STATE_COLLECTION_OFF = 0; |
| |
| private static final int STATE_COLLECTION_RELATION = 1; |
| |
| private static final int STATE_COLLECTION_FUNCTION = 2; |
| |
| private static final int STATE_COLLECTION_ENTITY = 3; |
| |
| private static final int STATE_ELEMENT_OFF = 0; |
| |
| private static final int STATE_ELEMENT_ON = 1; |
| |
| private static final int STATE_MODEL_OUT = 0; |
| |
| private static final int STATE_MODEL_VPM = 1; |
| |
| private static final int STATE_MODEL_MODEL = 2; |
| |
| private static final String sVPM = "VPM"; |
| |
| private static final String sPROPERTIES = "PROPERTIES"; |
| |
| private static final String sPROPERTY = "PROPERTY"; |
| |
| private static final String sPROPERTY_NAME = "name"; |
| |
| private static final String sPROPERTY_VALUE = "value"; |
| |
| private static final String sMODEL = "MODEL"; |
| |
| private static final String sENTITIES = "ENTITIES"; |
| |
| private static final String sENTITY = "ENTITY"; |
| |
| private static final String sRELATIONS = "RELATIONS"; |
| |
| private static final String sRELATION = "RELATION"; |
| |
| private static final String sFUNCTIONS = "FUNCTIONS"; |
| |
| private static final String sFUNCTION = "FUNCTION"; |
| |
| private static final String sMODELELEMENT = "MODELELEMENT"; |
| |
| private static final String sISFINALTYPE = "ISFINALTYPE"; |
| |
| private static final String saID = "id"; |
| |
| private static final String saAnyFrom = "isAnyFrom"; |
| |
| private static final String saAnyTo = "isAnyTo"; |
| |
| private static final String saIDREF = "idref"; |
| |
| private static final String sPARENT = "PARENT"; |
| |
| private static final String sNAME = "NAME"; |
| |
| private static final String sVALUE = "VALUE"; |
| |
| private static final String sTYPE = "TYPE"; |
| |
| private static final String sFROM = "FROM"; |
| |
| private static final String sTO = "TO"; |
| |
| private static final String sVIEW_INFO = "VIEWINFO"; |
| |
| private static final String sMULTIPLICITY = "MULTIPLICITY"; |
| |
| private static final String sINVERSE = "INVERSE"; |
| |
| private static final String sISAGGREGATION = "ISAGGREGATION"; |
| |
| private static final String sSUPERTYPE = "SUPERTYPE"; |
| |
| private static final String sROOTENTITY = "ROOTENTITY"; |
| |
| /** |
| * The model element currently being read from vpml file |
| */ |
| private ModelElement modelElement = null; |
| |
| /** |
| * The id of the root model element |
| */ |
| private String rootID = null; |
| |
| /** |
| * Mapping from ID (in vpml file) to <code>ModelElement</code> structure |
| */ |
| private Map<String, ModelElement> id2modelElement = new TreeMap<String, ModelElement>(); |
| |
| /** |
| * Mapping from ID (in vpml file) to <code>ModelElement</code> structure |
| * (just entities) |
| */ |
| private Map<String, ModelElement> id2entity = new TreeMap<String, ModelElement>(); |
| |
| /** |
| * Structure that contains all data of a model element stored in a vpml |
| * file. This structure is filled with concrete values when a model element |
| * is loaded. The VPM model is built when all data of all elements is |
| * collected. |
| * |
| * @author Andras Schmidt |
| * |
| */ |
| private class ModelElement implements Comparable { |
| public static final int ENTITY = 0; |
| |
| public static final int RELATION = 1; |
| |
| public static final int FUNCTION = 2; |
| |
| private String id = null; |
| |
| private String multiplicity = null; |
| |
| private String isAggregation = null; |
| |
| private String Inverse = null; |
| |
| private String isfinaltype = null; |
| |
| private String name = ""; |
| |
| private String parent = null; |
| |
| private String value = ""; |
| |
| private String viewInfo = null; |
| |
| private String from = null; |
| |
| private String to = null; |
| |
| private int type; |
| |
| private boolean isAnyFrom = false; |
| |
| private boolean isAnyTo = false; |
| |
| private List<String> types = new ArrayList<String>(); |
| |
| private List<String> superTypes = new ArrayList<String>(); |
| |
| private Set<String> containment = null; |
| |
| private IModelElement me = null; |
| |
| void setModelElement(IModelElement me) { |
| this.me = me; |
| } |
| |
| IModelElement getModelElement() { |
| return me; |
| } |
| |
| String getID() { |
| return id; |
| } |
| |
| int getType() { |
| return type; |
| } |
| |
| String getName() { |
| return name; |
| } |
| |
| void setName(String name) { |
| this.name = name; |
| } |
| |
| String getValue() { |
| return value; |
| } |
| |
| void setValue(String value) { |
| this.value = value; |
| } |
| |
| String getViewInfo() { |
| return viewInfo; |
| } |
| |
| void setViewInfo(String viewInfo) { |
| this.viewInfo = viewInfo; |
| } |
| |
| void setMultiplicity(String multiplicity) { |
| this.multiplicity = multiplicity; |
| } |
| |
| String getMultiplicity() { |
| return multiplicity; |
| } |
| |
| void setIsAggregation(String isa) { |
| this.isAggregation = isa; |
| } |
| |
| String getIsAggregation() { |
| return isAggregation; |
| } |
| |
| void setInverse(String inv) { |
| this.Inverse = inv; |
| } |
| |
| String getInverse() { |
| return Inverse; |
| } |
| |
| void setIsFinalType(String isft) { |
| this.isfinaltype = isft; |
| } |
| |
| String getIsFinalType() { |
| return this.isfinaltype; |
| } |
| |
| String getFrom() { |
| return from; |
| } |
| |
| void setFrom(String from) { |
| this.from = from; |
| } |
| |
| String getTo() { |
| return to; |
| } |
| |
| void setTo(String to) { |
| this.to = to; |
| } |
| |
| List getTypes() { |
| return types; |
| } |
| |
| void addType(String type) { |
| types.add(type); |
| } |
| |
| List getSuperTypes() { |
| return superTypes; |
| } |
| |
| void addSupertype(String supertype) { |
| superTypes.add(supertype); |
| } |
| |
| String getParent() { |
| return parent; |
| } |
| |
| void setParent(String parent) { |
| this.parent = parent; |
| } |
| |
| void addChild(String id) { |
| if (containment == null) { |
| containment = new TreeSet<String>(); |
| } |
| containment.add(id); |
| } |
| |
| public ModelElement(String id, int type) { |
| this.id = id; |
| this.type = type; |
| } |
| |
| public int compareTo(Object arg0) { |
| return id.compareTo(((ModelElement) arg0).id); |
| } |
| |
| public boolean isAnyFrom() { |
| return isAnyFrom; |
| } |
| |
| public void setAnyFrom(boolean isAnyFrom) { |
| this.isAnyFrom = isAnyFrom; |
| } |
| |
| public boolean isAnyTo() { |
| return isAnyTo; |
| } |
| |
| public void setAnyTo(boolean isAnyTo) { |
| this.isAnyTo = isAnyTo; |
| } |
| } |
| |
| /** |
| * Check the element loaded from vpml file to have all required paramters |
| * filled |
| * |
| */ |
| private void checkElement() { |
| if (modelElement.getID() == null) { |
| throw new RuntimeException("no id for element:" + modelElement.name); |
| } |
| // if(modelElement.)
|
| } |
| |
| /* |
| * private String ListToString(List<String> l) { StringBuffer ret=new |
| * StringBuffer(); for(int i=0;i<l.size();++i) { |
| * ret.append((String)l.get(i)); ret.append(","); } return ret.toString(); } |
| */ |
| private boolean debug = false; |
| |
| /** |
| * When all data is read from the vpml file the currently edited model |
| * element is put into the mapping that map ID's to elements |
| */ |
| private void closeAndSaveElement() { |
| if (modelElement.getType() == ModelElement.ENTITY) { |
| id2entity.put(modelElement.getID(), modelElement); |
| } |
| id2modelElement.put(modelElement.getID(), modelElement); |
| if (debug) { |
| String[] names = { "entity", "relation", "function" }; |
| |
| debugMsg("-- new element: " + names[modelElement.getType()]); |
| debugMsg("name: " + modelElement.getName()); |
| debugMsg("id: " + modelElement.getID()); |
| debugMsg("value: " + modelElement.getValue()); |
| debugMsg("parent: " + modelElement.getParent()); |
| debugMsg("from: " + modelElement.getFrom()); |
| debugMsg("to: " + modelElement.getTo()); |
| debugMsg("types: " + ListToString(modelElement.getTypes())); |
| debugMsg("SUPERtypes: " |
| + ListToString(modelElement.getSuperTypes())); |
| } |
| modelElement = null; |
| } |
| |
| private String ListToString(List types) { |
| // TODO Auto-generated method stub
|
| return null; |
| } |
| |
| private void debugMsg(String string) { |
| // TODO Auto-generated method stub
|
| |
| } |
| |
| /** |
| * The data of an entity is being read so create a <code>ModelElement</code> |
| * object that represents an entity |
| * |
| * @param id |
| */ |
| private void newEntity(String id) { |
| modelElement = new ModelElement(id, ModelElement.ENTITY); |
| } |
| |
| /** |
| * The data of a relation is being read so create a |
| * <code>ModelElement</code> object that represents a relation |
| * |
| * @param id |
| */ |
| private void newRelation(String id, boolean isAnyFrom, boolean isAnyTo) { |
| modelElement = new ModelElement(id, ModelElement.RELATION); |
| modelElement.setAnyFrom(isAnyFrom); |
| modelElement.setAnyTo(isAnyTo); |
| } |
| |
| /** |
| * The data of a relation is being read so create a |
| * <code>ModelElement</code> object that represents a relation. For |
| * compatibility we load old-style function relations too |
| * |
| * @param id |
| */ |
| private void newFunction(String id, boolean isAnyFrom, boolean isAnyTo) { |
| modelElement = new ModelElement(id, ModelElement.FUNCTION); |
| modelElement.setMultiplicity("0,-1,0,1"); |
| modelElement.setAnyFrom(isAnyFrom); |
| modelElement.setAnyTo(isAnyTo); |
| } |
| |
| private void _debugMsg(String str) { |
| if (debug) |
| System.out.println(str); |
| } |
| |
| public VPMImporterSaxImpl() { |
| super(); |
| } |
| |
| public String getName() { |
| return "VPML Importer with SAX technology. Ver 0.1b. Schmidt Andras"; |
| } |
| |
| public void startDocument() { |
| debugMsg("Start document"); |
| } |
| |
| public void endDocument() { |
| debugMsg("End document"); |
| } |
| |
| private final void startElementInModel(String qName, Attributes atts) { |
| if (stateCollection == STATE_COLLECTION_OFF) { |
| if (qName.equals(sENTITIES)) { |
| stateCollection = STATE_COLLECTION_ENTITY; |
| } else if (qName.equals(sRELATIONS)) { |
| stateCollection = STATE_COLLECTION_RELATION; |
| } else if (qName.equals(sFUNCTIONS)) { |
| stateCollection = STATE_COLLECTION_FUNCTION; |
| } else if (qName.equals(sROOTENTITY)) { |
| rootID = atts.getValue(saID); |
| } |
| } else { |
| if (stateElement == STATE_ELEMENT_OFF) { |
| switch (stateCollection) { |
| case STATE_COLLECTION_ENTITY: |
| if (qName.equals(sENTITY)) { |
| newEntity(atts.getValue(saID)); |
| stateElement = STATE_ELEMENT_ON; |
| } |
| break; |
| case STATE_COLLECTION_FUNCTION: |
| if (qName.equals(sFUNCTION)) { |
| newFunction(atts.getValue(saID), Boolean |
| .parseBoolean(atts.getValue(saAnyFrom)), |
| Boolean.parseBoolean(atts.getValue(saAnyTo))); |
| stateElement = STATE_ELEMENT_ON; |
| } |
| break; |
| case STATE_COLLECTION_RELATION: |
| if (qName.equals(sRELATION)) { |
| newRelation(atts.getValue(saID), Boolean |
| .parseBoolean(atts.getValue(saAnyFrom)), |
| Boolean.parseBoolean(atts.getValue(saAnyTo))); |
| stateElement = STATE_ELEMENT_ON; |
| } |
| break; |
| } |
| } else { |
| switch (stateField) { |
| case STATE_FIELD_OFF: { |
| if (qName.equals(sTYPE)) { |
| stateField = STATE_FIELD_TYPE; |
| } else if (qName.equals(sSUPERTYPE)) { |
| stateField = STATE_FIELD_SUPERTYPE; |
| } else if (qName.equals(sPARENT)) { |
| stateField = STATE_FIELD_PARENT; |
| } else if (qName.equals(sNAME)) { |
| startCollection(); |
| stateField = STATE_FIELD_NAME; |
| } else if (qName.equals(sVALUE)) { |
| startCollection(); |
| stateField = STATE_FIELD_VALUE; |
| } else if (qName.equals(sVIEW_INFO)) { |
| startCollection(); |
| stateField = STATE_FIELD_VIEW_INFO; |
| } else if (qName.equals(sMULTIPLICITY)) { |
| startCollection(); |
| stateField = STATE_FIELD_MULTIPLICITY; |
| } else if (qName.equals(sINVERSE)) { |
| // startCollection();
|
| stateField = STATE_FIELD_INVERSE; |
| } else if (qName.equals(sISAGGREGATION)) { |
| startCollection(); |
| stateField = STATE_FIELD_ISAGGREGATION; |
| } else if (qName.equals(sISFINALTYPE)) { |
| startCollection(); |
| stateField = STATE_FIELD_ISFINALTYPE; |
| } else if (qName.equals(sFROM)) { |
| stateField = STATE_FIELD_FROM; |
| } else if (qName.equals(sTO)) { |
| stateField = STATE_FIELD_TO; |
| } |
| break; |
| } |
| case STATE_FIELD_PARENT: { |
| if (qName.equals(sENTITY)) { |
| modelElement.setParent(atts.getValue(saIDREF)); |
| stateParent = STATE_PARENT_ENTITY; |
| } |
| break; |
| } |
| case STATE_FIELD_FROM: { |
| if (qName.equals(sENTITY)) { |
| modelElement.setFrom(atts.getValue(saIDREF)); |
| stateParent = STATE_PARENT_ENTITY; |
| } |
| break; |
| } |
| case STATE_FIELD_TO: { |
| if (qName.equals(sENTITY)) { |
| modelElement.setTo(atts.getValue(saIDREF)); |
| stateParent = STATE_PARENT_ENTITY; |
| } |
| break; |
| } |
| case STATE_FIELD_INVERSE: { |
| if (qName.equals(sRELATION)) { |
| modelElement.setInverse(atts.getValue(saIDREF)); |
| stateParent = STATE_PARENT_ENTITY; // FIXME ez nem jo!
|
| } |
| break; |
| } |
| case STATE_FIELD_TYPE: { |
| if (qName.equals(sMODELELEMENT)) { |
| modelElement.addType(atts.getValue(saIDREF)); |
| stateModelElement = STATE_MODELELEMENT_ON; |
| } else |
| stateError(); |
| break; |
| } |
| case STATE_FIELD_SUPERTYPE: { |
| if (qName.equals(sMODELELEMENT)) { |
| modelElement.addSupertype(atts.getValue(saIDREF)); |
| stateModelElement = STATE_MODELELEMENT_ON; |
| } else |
| stateError(); |
| break; |
| } |
| } |
| |
| } |
| } |
| } |
| |
| private void addProperty(Attributes atts) { |
| String name = atts.getValue(sPROPERTY_NAME); |
| String value = atts.getValue(sPROPERTY_VALUE); |
| props.put(name, value); |
| // System.out.println(name+":\""+value+"\"");
|
| } |
| |
| public void startElement(String uri, String name, String qName, |
| Attributes atts) { |
| if (stateModel == STATE_MODEL_MODEL) { |
| startElementInModel(qName, atts); |
| } else { |
| switch (stateModel) { |
| case STATE_MODEL_OUT: { |
| if (qName.equals(sVPM)) |
| stateModel = STATE_MODEL_VPM; |
| break; |
| } |
| case STATE_MODEL_VPM: { |
| if (qName.equals(sMODEL)) |
| stateModel = STATE_MODEL_MODEL; |
| if (qName.equals(sPROPERTY)) |
| addProperty(atts); |
| break; |
| } |
| } |
| } |
| } |
| |
| private void closeCollection() { |
| collectString = false; |
| collectedString.delete(0, collectedString.length()); |
| } |
| |
| private void startCollection() { |
| collectString = true; |
| } |
| |
| /* |
| * private String getCollectedString() { return collectedString.toString(); |
| * } |
| */ |
| private String getCollectedStringAndClose() { |
| String ret = collectedString.toString(); |
| closeCollection(); |
| return ret; |
| } |
| |
| public void endElement(String uri, String name, String qName) { |
| if (stateField != STATE_FIELD_OFF) { |
| if (stateParent != STATE_PARENT_OFF) { |
| if (qName.equals(sENTITY) || qName.equals(sRELATION)) { |
| stateParent = STATE_PARENT_OFF; |
| } else |
| stateError(); |
| } else if (stateModelElement != STATE_MODELELEMENT_OFF) { |
| if (qName.equals(sMODELELEMENT)) { |
| stateModelElement = STATE_MODELELEMENT_OFF; |
| } else |
| stateError(); |
| } else { |
| switch (stateField) { |
| case STATE_FIELD_NAME: |
| if (qName.equals(sNAME)) |
| modelElement.setName(getCollectedStringAndClose()); |
| else |
| stateError(); |
| break; |
| case STATE_FIELD_VALUE: |
| if (qName.equals(sVALUE)) |
| modelElement.setValue(getCollectedStringAndClose()); |
| else |
| stateError(); |
| break; |
| case STATE_FIELD_VIEW_INFO: |
| if (qName.equals(sVIEW_INFO)) |
| modelElement.setViewInfo(getCollectedStringAndClose()); |
| else |
| stateError(); |
| break; |
| case STATE_FIELD_MULTIPLICITY: |
| if (qName.equals(sMULTIPLICITY)) |
| modelElement |
| .setMultiplicity(getCollectedStringAndClose()); |
| else |
| stateError(); |
| break; |
| case STATE_FIELD_ISAGGREGATION: |
| if (qName.equals(sISAGGREGATION)) |
| modelElement |
| .setIsAggregation(getCollectedStringAndClose()); |
| else |
| stateError(); |
| break; |
| case STATE_FIELD_ISFINALTYPE: |
| if (qName.equals(sISFINALTYPE)) |
| modelElement |
| .setIsFinalType(getCollectedStringAndClose()); |
| else |
| stateError(); |
| break; |
| case STATE_FIELD_INVERSE: |
| if (!qName.equals(sINVERSE)) |
| stateError(); |
| break; |
| case STATE_FIELD_TYPE: |
| if (!qName.equals(sTYPE)) |
| stateError(); |
| break; |
| case STATE_FIELD_SUPERTYPE: |
| if (!qName.equals(sSUPERTYPE)) |
| stateError(); |
| break; |
| case STATE_FIELD_PARENT: |
| if (!qName.equals(sPARENT)) |
| stateError(); |
| break; |
| case STATE_FIELD_FROM: |
| if (!qName.equals(sFROM)) |
| stateError(); |
| break; |
| case STATE_FIELD_TO: |
| if (!qName.equals(sTO)) |
| stateError(); |
| break; |
| } |
| stateField = STATE_FIELD_OFF; |
| } |
| } else { |
| // We are inside an element's attributes
|
| if (stateElement == STATE_ELEMENT_ON) { |
| switch (stateCollection) { |
| case STATE_COLLECTION_ENTITY: |
| if (qName.equals(sENTITY)) { |
| checkElement(); |
| closeAndSaveElement(); |
| } |
| stateElement = STATE_ELEMENT_OFF; |
| break; |
| case STATE_COLLECTION_RELATION: |
| if (qName.equals(sRELATION)) { |
| checkElement(); |
| closeAndSaveElement(); |
| } |
| stateElement = STATE_ELEMENT_OFF; |
| break; |
| case STATE_COLLECTION_FUNCTION: |
| if (qName.equals(sFUNCTION)) { |
| checkElement(); |
| closeAndSaveElement(); |
| } |
| stateElement = STATE_ELEMENT_OFF; |
| break; |
| } |
| } |
| // We are not inside an element's attribute
|
| else { |
| if (qName.equals(sENTITIES) || qName.equals(sRELATIONS) |
| || qName.equals(sFUNCTIONS)) |
| stateCollection = STATE_COLLECTION_OFF; |
| if (qName.equals(sMODEL)) |
| stateModel = STATE_MODEL_VPM; |
| if (qName.equals(sVPM)) |
| stateModel = STATE_MODEL_OUT; |
| } |
| } |
| /* |
| * if ("".equals(uri)) System.out.println("Start element: " + qName + |
| * " " + name); else System.out.println("Start element: {" + uri + "}" + |
| * name); |
| * |
| * if ("".equals(uri)) System.out.println("End element: " + qName); else |
| * System.out.println("End element: {" + uri + "}" + name); |
| */ |
| } |
| |
| private void stateError() { |
| throw new RuntimeException("file format is corrupt"); |
| // System.out.println("state error!");
|
| // TODO
|
| } |
| |
| public void characters(char ch[], int start, int length) { |
| if (collectString) { |
| collectedString.append(ch, start, length); |
| } |
| } |
| |
| public void warning(SAXParseException e) throws SAXException { |
| throw new SAXException(e.getMessage()); |
| } |
| |
| public void error(SAXParseException e) throws SAXException { |
| throw new SAXException(e.getMessage()); |
| } |
| |
| public void fatalError(SAXParseException e) throws SAXException { |
| throw new SAXException(e.getMessage()); |
| } |
| |
| // class VPMImporterSaxEcxeption extends SAXException
|
| /** |
| * When all data is read from the file build the VPM model |
| */ |
| private void generateModelSpace() throws VPMImporterException { |
| if (rootID == null) |
| throw new VPMImporterException("modelspace must contain root"); |
| { |
| // The vpml file does not contain the root entity of the VPM model
|
| // So it must be created in the raw VPM model
|
| ModelElement rootMeta = new ModelElement(rootID, |
| ModelElement.ENTITY); |
| rootMeta.setName("root"); |
| rootMeta.setModelElement(mManager.getRoot()); |
| id2entity.put(rootID, rootMeta); |
| id2modelElement.put(rootID, rootMeta); |
| } |
| _debugMsg("building containment tree"); |
| // build containment tree
|
| Iterator<Entry<String, ModelElement>> it = id2entity.entrySet().iterator(); |
| while (it.hasNext()) { |
| ModelElement me = it.next().getValue(); |
| String pID = me.getParent(); |
| if (pID == null) { |
| if (!me.getID().equals(rootID)) { |
| throw new VPMImporterException( |
| "element must have a parent:" + me.getName() |
| + " with id:" + me.getID()); |
| } |
| } else { |
| ModelElement parent = id2entity.get(pID); |
| if (parent == null) { |
| _debugMsg(pID); |
| // TODO error
|
| } |
| parent.addChild(me.getID()); |
| } |
| } |
| // start building modelspace
|
| try { |
| // creating entitites in containment hierarchy
|
| _debugMsg("creating entities"); |
| createEntityWithChildren(rootID, null); |
| // creating all relations and functions
|
| _debugMsg("creating relations"); |
| it = id2modelElement.entrySet().iterator(); |
| IEntity root = mManager.getRoot(); |
| while (it.hasNext()) { |
| ModelElement me = it.next().getValue(); |
| int type = me.getType(); |
| if (type != ModelElement.ENTITY) { |
| IRelation newRel = null; |
| if (type == ModelElement.RELATION) |
| newRel = mManager.newRelation(root, root); |
| else |
| newRel = mManager.newRelation(root, root); |
| mManager.setViewInfo(newRel, me.getViewInfo()); |
| // added by Istvan Rath
|
| mManager.setIsFinalType(newRel, "true".equalsIgnoreCase(me |
| .getIsFinalType())); |
| me.setModelElement(newRel); |
| } |
| } |
| _debugMsg("setting function, and relation from and to places"); |
| it = id2modelElement.entrySet().iterator(); |
| while (it.hasNext()) { |
| ModelElement me = it.next().getValue(); |
| int type = me.getType(); |
| if (type != ModelElement.ENTITY) { |
| IRelation newRel = (IRelation) me.getModelElement(); |
| IModelElement from = id2modelElement |
| .get(me.getFrom()).getModelElement(); |
| IModelElement to = id2modelElement |
| .get(me.getTo()).getModelElement(); |
| mManager.setRelationFrom(newRel, from); |
| mManager.setRelationTo(newRel, to); |
| mManager.setIsAnyFrom(newRel, me.isAnyFrom); |
| mManager.setIsAnyTo(newRel, me.isAnyTo); |
| mManager.setName(newRel, me.getName()); |
| if (me.getMultiplicity() != null) { |
| /* |
| * StringTokenizer tok=new |
| * StringTokenizer(me.getMultiplicity(),","); int |
| * fromMin=Integer.parseInt(tok.nextToken()); int |
| * fromMax=Integer.parseInt(tok.nextToken()); int |
| * toMin=Integer.parseInt(tok.nextToken()); int |
| * toMax=Integer.parseInt(tok.nextToken()); |
| */ |
| if (me.getMultiplicity().equals( |
| EMultiplicityKind.MANY_TO_MANY.toString())) { |
| mManager.setRelationMultiplicity(newRel, |
| EMultiplicityKind.MANY_TO_MANY); |
| } else if (me.getMultiplicity().equals( |
| EMultiplicityKind.ONE_TO_MANY.toString())) { |
| mManager.setRelationMultiplicity(newRel, |
| EMultiplicityKind.ONE_TO_MANY); |
| } else if (me.getMultiplicity().equals( |
| EMultiplicityKind.MANY_TO_ONE.toString())) { |
| mManager.setRelationMultiplicity(newRel, |
| EMultiplicityKind.MANY_TO_ONE); |
| } else if (me.getMultiplicity().equals( |
| EMultiplicityKind.ONE_TO_ONE.toString())) { |
| mManager.setRelationMultiplicity(newRel, |
| EMultiplicityKind.ONE_TO_ONE); |
| } |
| } |
| if (me.getIsAggregation() != null |
| && me.getIsAggregation().equalsIgnoreCase("true")) |
| mManager.setRelationIsAggregation(newRel, true); |
| if (me.getInverse() != null) { |
| ModelElement m = id2modelElement.get(me.getInverse()); |
| if (m != null) { |
| IRelation inv = (IRelation) m.getModelElement(); |
| mManager.setRelationInverse(newRel, inv); |
| } |
| } |
| if (!newRel.getName().equals(me.getName())) { |
| // Name clash with uniquenames already in modelspace.
|
| IModelElement par = newRel.getNamespace(); |
| IModelElement clasher = par |
| .getElementInNamespaceByName(me.getName()); |
| mManager.setName(clasher, clasher.getName() + "!"); |
| mManager.setName(newRel, me.getName()); |
| } |
| } |
| } |
| _debugMsg("creating type relations between elements, setting names of relations"); |
| // Go through entities, relations and functions again. Now all |
| // elements exist in modelspace
|
| // so we can mark instanceof and supertypeof relations between them.
|
| it = id2modelElement.entrySet().iterator(); |
| while (it.hasNext()) { |
| ModelElement modE = it.next().getValue(); |
| IModelElement me = modE.getModelElement(); |
| List list = null; |
| for (int j = 0; j < 2; ++j) { |
| if (j == 0) |
| list = modE.getTypes(); |
| else |
| list = modE.getSuperTypes(); |
| for (int i = 0; i < list.size(); ++i) { |
| String parID = (String) list.get(i); |
| IModelElement type = id2modelElement |
| .get(parID).getModelElement(); |
| String msg = null; |
| if (j == 0) |
| try { |
| mManager.newInstanceOfEditor(type, me); |
| } catch (VPMCoreException e) { |
| mManager.newInstanceOfMachine(type, me); |
| msg = e.getMessage(); |
| } |
| else |
| try { |
| mManager.newSupertypeOfEditor(type, me); |
| } catch (VPMCoreException e) { |
| mManager.newSupertypeOfMachine(type, me); |
| msg = e.getMessage(); |
| } |
| if (msg != null) { |
| _debugMsg(msg); |
| } |
| } |
| } |
| } |
| } catch (VPMCoreException e) { |
| e.printStackTrace(); |
| // TODO
|
| } |
| } |
| |
| private void createEntityWithChildren(String id, IEntity parent) |
| throws VPMCoreException { |
| ModelElement me = id2entity.get(id); |
| IEntity newEnt = null; |
| if (!id.equals(rootID)) { |
| newEnt = mManager.newEntity(me.getName(), me.getValue(), parent); |
| } else { |
| newEnt = mManager.getRoot(); |
| } |
| mManager.setViewInfo(newEnt, me.getViewInfo()); |
| // added by Istvan Rath
|
| mManager.setIsFinalType(newEnt, "true".equalsIgnoreCase(me |
| .getIsFinalType())); |
| me.setModelElement(newEnt); |
| if (me.containment != null) { |
| Iterator<String> it = me.containment.iterator(); |
| while (it.hasNext()) { |
| String idChild = it.next(); |
| createEntityWithChildren(idChild, newEnt); |
| } |
| } |
| } |
| |
| class VPMImporterException extends VPMRuntimeException { |
| private static final long serialVersionUID = 1L; |
| |
| public VPMImporterException(String msg) { |
| super(msg); |
| } |
| } |
| |
| IModelManager mManager; |
| |
| IModelSpace modelSpace; |
| |
| VPMProperties vprops; |
| |
| Properties props; |
| |
| private long timeInMillis; |
| |
| public IModelSpace process(InputStream f, IModelSpace ms, |
| VPMProperties props) throws VPMRuntimeException { |
| _debugMsg("Loading modelspace starts at:" |
| + (timeInMillis = System.currentTimeMillis())); |
| modelSpace = ms; |
| this.vprops = props; |
| this.props = new Properties(); |
| mManager = ms.getModelManager(); |
| try { |
| SAXParser sp = SAXParserFactory.newInstance().newSAXParser(); |
| // Build raw model of the VPM model
|
| sp.parse(f, this); |
| // Build the VPM model
|
| generateModelSpace(); |
| // propagate properties to the given VPM properties object
|
| vprops.loadFromJavaProperties(this.props); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| throw new VPMRuntimeException("Error loading model", e); |
| } |
| long endTime = System.currentTimeMillis(); |
| _debugMsg("Loading modelspace ended at:" + endTime + " finished in: " |
| + (endTime - timeInMillis) + " millis"); |
| return modelSpace; |
| } |
| } |