|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.lib.jmi.xmi; import java.io.*; import java.util.*; import java.net.*; import org.xml.sax.*; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import org.netbeans.api.xmi.*; import javax.jmi.reflect.*; import javax.jmi.model.*; import org.netbeans.lib.jmi.util.Logger; import org.netbeans.lib.jmi.util.DebugException; public class XmiSAXReader extends DefaultHandler { private URL docURL = null; // currently processed element private XmiElement currentElement; // context private XmiContext context; // differences that have to be applayed on the content of read XMI private HashMap diffs = null; // indicates if elements of Content section are being currently read private boolean contentIsRead = false; // indicates if a predecessor of a read sub-element has been deleted by a diference private boolean elementIsDeleted = false; // timestamp of a difference that has been or is being applyed private int lastTimeStamp = 0; // stack used to to track information needed to applay differences private Stack stack = new Stack (); // document locator private Locator locator = null; // root element name ("XMI" in case of XMI 1.1, "ns:XMI" or "ns:ClassName" in case of XMI 2.0) private String rootElementName = null; // possible elemnet of the stack, represents a deleted XMI element private final Object DELETED = new Integer (0); // an empty element, pushed to the stack if no information is needed to store in a given step private final Object EMPTY = new Integer (1); private XMIInputConfig config; // init ..................................................................... public XmiSAXReader () { this (null, null); } public XmiSAXReader (XMIInputConfig config) { this (null, config); } public XmiSAXReader (XmiContext context, XMIInputConfig config) { this.context = context; if (config == null) this.config = new InputConfig (); else this.config = config; } // methods .................................................................. public Collection read (InputStream input, String uri, RefPackage[] extents, String encoding) throws IOException, SAXException, ParserConfigurationException { InputSource is = new InputSource (input); if (encoding != null) { is.setEncoding(encoding); } if (uri != null) { is.setSystemId(uri); try { docURL = new URI (uri).toURL (); } catch (URISyntaxException e) { } catch (MalformedURLException e) { } catch (IllegalArgumentException e) { } } return read (is, extents); } public Collection read (URL url, RefPackage[] extents, String encoding) throws IOException, SAXException, ParserConfigurationException { docURL = url; InputSource is = new InputSource (url.toString ()); if (encoding != null) is.setEncoding(encoding); return read (is, extents); } public Collection read (URL url, RefPackage[] extents, String encoding, HashMap diffs) throws IOException, SAXException, ParserConfigurationException { this.diffs = diffs; return read (url, extents, encoding); } public Collection read (InputSource input, RefPackage[] extents) throws IOException, SAXException, ParserConfigurationException { if (diffs == null) Logger.getDefault().log ("XMI reader started"); long time = System.currentTimeMillis (); if (docURL == null) { String systemId = input.getSystemId(); if (systemId != null) { try { docURL = new URL (systemId); } catch (MalformedURLException e) { } catch (IllegalArgumentException e) { } } } if (context == null) context = new XmiContext (extents, docURL, config); SAXParserFactory factory = SAXParserFactory.newInstance (); factory.setValidating (false); SAXParser saxParser = factory.newSAXParser (); saxParser.parse (input, this); time = System.currentTimeMillis () - time; if (diffs == null) Logger.getDefault().log ("finished, TIME: " + time/1000.0 + "[s]"); return context.getOutermostObjects (); } void initConsumer (RefPackage pkg) throws SAXException { context = new XmiContext (new RefPackage [] {pkg}, null, config); } public void startDocument () throws SAXException { rootElementName = null; } /* public void endDocument () throws SAXException { } */ public void startElement (String namespaceURI, String sName, String qName, Attributes attrs) throws SAXException { try { // Logger.getDefault().log ("s: " + qName); if (elementIsDeleted) { stack.push (EMPTY); return; } else if (rootElementName == null) { rootElementName = qName; currentElement = new XmiElement.Document (null, context, qName, attrs); return; } else if (currentElement == null) { throw new DebugException("Not an XMI document. Root element must be <"+XmiConstants.XMI_ROOT+">"); } else if (qName.equals (XmiConstants.XMI_CONTENT)) { stack.push (EMPTY); contentIsRead = true; } else if ((contentIsRead && qName.equals(XmiConstants.XMI_EXTENSION)) || (!contentIsRead && qName.equals(XmiConstants.XMI_EXTENSIONS))) { stack.push (DELETED); elementIsDeleted = true; return; } else if ((contentIsRead) && (diffs != null)) { // check if there are some differences to apply String xmiId = attrs.getValue (XmiConstants.XMI_ID); List list = null; if (xmiId != null) list = (List) diffs.get (xmiId); if (list != null) { String elementName = null; Iterator iter = list.iterator (); List modifs = new LinkedList (); while (iter.hasNext ()) { XmiElement.Difference.Diff diff = (XmiElement.Difference.Diff) iter.next (); if (diff.timeStamp <= lastTimeStamp) continue; switch (diff.kind) { case XmiElement.Difference.Diff.DELETE: stack.push (DELETED); elementIsDeleted = true; return; case XmiElement.Difference.Diff.ADD: modifs.add (diff); break; case XmiElement.Difference.Diff.REPLACE: XmiElement.Difference.Item item = (XmiElement.Difference.Item) diff.items.removeFirst (); qName = item.qName; attrs = item.attrs; elementName = qName; diff.items.removeLast (); modifs.add (diff); break; } // switch } // while stack.push (new StackElement (modifs, elementName)); } else { stack.push (EMPTY); } // if } // if currentElement = currentElement.startSubElement (qName, attrs); if (currentElement == null) // should not occur throw new DebugException ("XmiElement.startSubElement("+qName+", ..) returned null"); if (contentIsRead && (diffs != null)) applayDiffs (); } catch (Exception e) { e.printStackTrace (); Logger.getDefault().annotate(e, "Error parsing XMI" + getLineNumberErrorString()); throw (SAXException) Logger.getDefault().annotate(new SAXException("XMI parsing error" + getLineNumberErrorString() + ": " + (e.getMessage() != null ? e.getMessage() : e.toString()), e), e); } } public void endElement (String namespaceURI, String sName, String qName) throws SAXException { // Logger.getDefault().log ("e: " + qName); try { if (elementIsDeleted) { if (stack.pop () == DELETED) elementIsDeleted = false; return; } if (qName.equals (XmiConstants.XMI_CONTENT)) contentIsRead = false; else { if (contentIsRead && (diffs != null)) { Object obj = stack.pop (); if ((obj instanceof StackElement) && ((StackElement) obj).replacedName != null) qName = ((StackElement) obj).replacedName; } } // if currentElement = currentElement.endElement (qName); if ((currentElement == null) && !qName.equals (rootElementName)) // should not occur throw new DebugException ("XmiElement.endElement("+qName+") returned null"); if (contentIsRead && (diffs != null)) applayDiffs (); } catch (Exception e) { e.printStackTrace (); String message = "XMI parsing error" + getLineNumberErrorString() + ": " + (e.getMessage() != null ? e.getMessage() : e.toString()); Logger.getDefault().log(Logger.WARNING, message); SAXException ne = new SAXException(message, e); throw (SAXException) Logger.getDefault().annotate(ne, e); } } public void characters (char buf[], int offset, int len) throws SAXException { String s = new String (buf, offset, len); try { if (!elementIsDeleted) { if (currentElement != null) currentElement.characters (buf, offset, len); } } catch (Exception e) { e.printStackTrace (); SAXException ne = new SAXException("XMI parsing error" + getLineNumberErrorString() + ": " + (e.getMessage() != null ? e.getMessage() : e.toString()), e); Logger.getDefault().annotate(ne, e); throw (SAXException) Logger.getDefault().annotate(ne, "XMI parsing error" + getLineNumberErrorString()); } } public void setDocumentLocator (Locator locator) { this.locator = locator; } /** * Produces text like "at line: #" useful for error messages. Produces * the empty string, if no locator was set. */ private String getLineNumberErrorString() { if ( locator != null ) { return " at line: " + locator.getLineNumber(); } else { return ""; } } public InputSource resolveEntity (String publicID, String systemID) { Logger.getDefault().log ("resolving reference: " + publicID + ", " + systemID); return new InputSource (new StringReader ("")); } private void applayDiffs () throws SAXException { Object elem = stack.peek (); if (elem != EMPTY) { ((StackElement) elem).position++; Iterator iter = ((StackElement) elem).diffs.iterator (); while (iter.hasNext ()) { XmiElement.Difference.Diff diff = (XmiElement.Difference.Diff) iter.next (); if ((diff.position == ((StackElement) elem).position) && (diff.timeStamp > lastTimeStamp)) { int temp = lastTimeStamp; lastTimeStamp = diff.timeStamp; addContent (diff); lastTimeStamp = temp; } } // while } // if (item != null) } private void addContent (XmiElement.Difference.Diff diff) throws SAXException { Iterator iter = diff.items.iterator (); while (iter.hasNext ()) { Object obj = iter.next (); if (obj instanceof XmiElement.Difference.Item) { XmiElement.Difference.Item item = (XmiElement.Difference.Item) obj; if (item.isStart) { startElement (null, "", item.qName, item.attrs); } else { endElement (null, "", item.qName); } } else characters (((String) obj).toCharArray (), 0, ((String) obj).length ()); } // while } private static class StackElement { public int position = 0; public List diffs; public String replacedName; public StackElement (List diffs, String replacedName) { this.diffs = diffs; this.replacedName = replacedName; } } // StackElement } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.