/** * Retrieves the referenced element in the current XMIReader instance. * * <p>Note, null may be returned if it is a forward reference. If it is the case, it is added to * the forward reference. * * @param idRef the xmi id refers to an element which may be or may be not stored in XMIReader * instance * @param elementName the xmi element name * @return the referenced element in the current XMIReader instance, or null if it is a forward * reference * @throws SAXException if parent handler is null, or the parent element name or its associated * object is null */ private Object getReferenceElement(String idRef, String elementName) throws SAXException { // get the object from found elements Object obj = this.getCurrentXMIReader().getElement(idRef); // if it is not found, then add the forward reference if (obj == null) { XMIHandler handler = getParentHandler(); // the parent handler is required if (handler == null) { throw new SAXException( "The handler for the parent element of " + elementName + " is null."); } // the parent element name is required if (handler.getLastProperty() == null) { throw new SAXException("The parent element name of " + elementName + " is null."); } // the object for the parent element is required if (handler.getLastRefObject() == null) { throw new SAXException( "The associated object for element " + handler.getLastProperty() + " is null."); } // add the forward reference for the given xmi id this.getCurrentXMIReader() .putElementProperty(idRef, handler.getLastProperty(), handler.getLastRefObject()); } return obj; }
/** * This method is used to adjust the size of Diagram when the <UML:Diagram> element ended, * it will use the util method adjustGraphNodeSize in XMIConverterUtil class to adjust diagram * size. When the diagram doesn't contain any diagram element, the size should be configured empty * size, otherwise, the size will be calculated by the sub elements and the configured margin. * * @param uri the Namespace URI, or the empty string if the element has no Namespace URI or if * Namespace processing is not being performed * @param localName the local name (without prefix), or the empty string if Namespace processing * is not being performed * @param qName the qualified XML name (with prefix), or the empty string if qualified names are * not available * @param chain the next chain of the chains of converters * @param reader the XMIReader instance firing this callback * @param handler the XMIHandler instance this converter added to * @throws SAXException if any error occurs in this method */ public void endElement( String uri, String localName, String qName, XMIConverterChain chain, XMIReader reader, XMIHandler handler) throws SAXException { // Save the last ref object first, it maybe changed in later chain Object obj = handler.getLastRefObject(); chain.endElement(uri, localName, qName, reader, handler); String elementName = ((qName != null) && (qName.trim().length() > 0)) ? qName : localName; if (DIAGRAM_QNAME.equals(elementName)) { Diagram diagram = (Diagram) obj; XMIConvertersUtil.adjustGraphNodeSize(diagram, emptyWidth, emptyHeight, margin); } }
/** * This method implements the endElement(String,String,String) method in ContentHandler interface. * * <p>This component is a plugin of XMIReader component and this method is intended to be invoked * by XMIReader class. * * <p>This method receives notification of the end of an element. The diagram interchange related * elements will be processed by this method. * * @param uri the Namespace URI; * @param localName The local name (without prefix), or the empty string if Namespace processing * is not being performed. * @param qName The qualified XML 1.0 name (with prefix), or the empty string if qualified names * are not available * @throws SAXException Any SAX exception, possibly wrapping another exception, it may be caused * by reflection, etc. */ public void endElement(String uri, String localName, String qName) throws SAXException { String elementName = ((qName != null) && (qName.trim().length() != 0)) ? qName : localName; int dotIndex = elementName.indexOf("."); // if the element represents a uml model element and its parent element is a uml element // property, // then to set the property value for the parent uml element if (dotIndex < 0) { // get the object for the current element Object curElementObject = getLastRefObject(); // make the parent element name and object on the top of the stack // it is called before getParentHandler() method because the handler for the // element and the handler for parent element may be the same pop(); XMIHandler handler = getParentHandler(); if (handler != null) { String parentElementName = handler.getLastProperty(); // the parent element represents a uml model property if (parentElementName != null && parentElementName.indexOf(".") >= 0) { // update the uml model element property // for example: // <UML:GraphElement.semanticModel> // <UML:SimpleSemanticModelElement xmi.id = '......'/> // </UML:GraphElement.semanticModel> // The current element is "UML:SimpleSemanticModelElement", the parent element is // "UML:GraphElement.semanticModel". // Here, the semanticModel property of the corresponding GraphElement instance is set. setElementProperty(handler.getLastRefObject(), parentElementName, curElementObject); } } } else { // get the property name // for example, get "semanticModel" from "UML:GraphElement.semanticModel" String propName = elementName.substring(dotIndex + 1); // If a XMI.field element ends, validate it and add the value to XMI.field values if (XMI_FIELD.equals(elementName)) { // Only zero or two sub XMI.field elements are allowed for each XMI.field element int count = (Integer) getLastRefObject(); if (count != 0 && count != 2) { throw new SAXException( "One XMI.field element has " + count + " child XMI.field elements, instead of 0 or 2."); } // If the current XMI.field element is an inner XMI.field element // for example, <XMI.field><XMI.field>0.0</XMI.field></XMI.field> // The first XMI.field is an outer element while the inner XMI.field element is an // inner element if (xmiFieldValue != null) { this.xmiFieldValues.add(xmiFieldValue); this.xmiFieldValue = null; } } else if (DIMENSION_ELEMENTS.contains(propName) || POINT_ELEMENTS.contains(propName) || POINTS_ELEMENTS.contains(propName)) { // The elements that may have XMI.field sub-elements if (!this.xmiFieldValues.isEmpty()) { // Only two XMI.field sub-elements are allowed for the point or dimension elements if (!POINTS_ELEMENTS.contains(propName) && this.xmiFieldValues.size() != 2) { throw new SAXException( "The " + elementName + " element contains " + this.xmiFieldValues.size() + " XMI.field elements instead of two, only two is allowed."); } try { if (DIMENSION_ELEMENTS.contains(propName)) { // process the dimension element // for example // <UML:GraphNode.size> // <XMI.field>80.0776</XMI.field> // <XMI.field>15.0</XMI.field> // </UML:GraphNode.size> Dimension dimension = new Dimension(); dimension.setWidth(Double.valueOf(this.xmiFieldValues.get(0).toString())); dimension.setHeight(Double.valueOf(this.xmiFieldValues.get(1).toString())); this.setElementProperty(getLastRefObject(), elementName, dimension); } else if (POINT_ELEMENTS.contains(propName)) { // process the point element // <UML:GraphElement.position> // <XMI.field>2.0</XMI.field> // <XMI.field>2.0</XMI.field> // </UML:GraphElement.position> Point point = new Point(); point.setX(Double.valueOf(this.xmiFieldValues.get(0).toString())); point.setY(Double.valueOf(this.xmiFieldValues.get(1).toString())); this.setElementProperty(getLastRefObject(), elementName, point); } else { // process the point collect element // <UML:GraphEdge.waypoints> // <XMI.field> // <XMI.field>110.0</XMI.field> // <XMI.field>205.0</XMI.field> // </XMI.field> // <XMI.field> // <XMI.field>0.0</XMI.field> // <XMI.field>0.0</XMI.field> // </XMI.field> // ...... // </UML:GraphEdge.waypoints> int len = this.xmiFieldValues.size(); // Add all the points for (int i = 0; i < len / 2; i++) { Point point = new Point(); point.setX(Double.valueOf(this.xmiFieldValues.get(2 * i).toString())); point.setY(Double.valueOf(this.xmiFieldValues.get(2 * i + 1).toString())); this.setElementProperty(getLastRefObject(), elementName, point); } } } catch (NumberFormatException e) { throw new SAXException( "NumberFormatException occurs while converting string to double value.", e); } } } // make the parent element name and object because on the top of the stack // the name and object for the current element will be discarded pop(); } }