|
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.util.*; import java.net.*; import java.io.*; 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 org.netbeans.lib.jmi.util.DebugException; import javax.jmi.reflect.*; import javax.jmi.model.*; import javax.jmi.xmi.MalformedXMIException; import javax.jmi.primitivetypes.PrimitiveTypesPackage; import org.netbeans.lib.jmi.util.Logger; public class XmiContext implements XMIReferenceResolver { private static final String ANNOTATION = ""; //"Created by XMI SAX Reader to substitute Corba types."; private static final String [] PRIMITIVE_TYPES = { XmiConstants.BOOLEAN_TYPE, XmiConstants.DOUBLE_TYPE, XmiConstants.FLOAT_TYPE, XmiConstants.INTEGER_TYPE, XmiConstants.LONG_TYPE, XmiConstants.STRING_TYPE }; // shared XmiElements ....................................................... XmiElement.PrimitiveValue PRIMITIVE_VALUE = new XmiElement.PrimitiveValue (this); XmiElement.EnumerationValue ENUMERATION_VALUE = new XmiElement.EnumerationValue (this); XmiElement.ReferenceValue REFERENCE_VALUE = new XmiElement.ReferenceValue (this); // variables ................................................................ String XMI_HREF; // name of attributes storing an href in XMI String XMI_IDREF; // name of attributes storing an idref in XMI String XMI_ID; // name of attributes storing an id in XMI boolean isXmi20; // if true, XMI version is 2.0 String xmiNsPrefix; // prefix of XMI namespace in case of XMI 2.0 (followed by ':' if the prefix is non-empty) String xmlNsPrefix; // prefix of XML namespace in case of XMI 2.0 (followed by ':' if the prefix is non-empty) private HashMap nsURIToPrefix = new HashMap (); // XMI 2.0 only - namespase URI to namespace prefix mapping // storage of all outermost packages private HashMap outermostPackages = new HashMap (); // storage of all available namespaces private HashMap namespaces = new HashMap (); // extents passed as a parameter private RefPackage [] extents; // stores ModelPackage if it is one of the input packages private ModelPackage modelPackage = null; // primitive types package private MofPackage primitiveTypesPackage = null; // stores primitive types contained in @link #primitiveTypesPackage private HashMap primitiveTypes = null; // stores all Alias instances created instead of Corba primitive types private List corbaTypesReferencingPrimitiveTypes = new LinkedList (); // cache storing instance level attributes private HashMap instanceAttributes_cache = new HashMap (); // cache storing references private HashMap instanceReferences_cache = new HashMap (); // cache storing instance level attributes and references by names private HashMap instanceElementsByName_cache = new HashMap (); // cache storing class level attributes private HashMap classAttributes_cache = new HashMap (); // cache storing class level attributes by names private HashMap classElementsByName_cache = new HashMap (); // cache storing structures' fields private HashMap structureFields_cache = new HashMap (); // cache storing labels' prefixes private HashMap labelPrefix_cache = new HashMap (); // list of all currently created outermost composite objects private Collection outermostInstances = new LinkedList (); // cache storing all already resolved names private HashMap resolvedNames_cache = new HashMap (); // all currently known references given by xmi.id, each element is a hashtable // containing references related to one XMI document private HashMap allXmiReferences = new HashMap (); /* // xmi references resolved for the currently read document private HashMap xmiReferences; */ // internal unresolved reference, stores systemId -> ids_map, where ids_map is a // xmiId -> List of UnresolvedReferences mapping private HashMap unresolvedRefs = new HashMap (); // external unresolved references for the currently read document private HashMap unresolvedExternalRefs = new HashMap (); // private List listOfUnresolvedHRefs = new LinkedList (); // private Set allUnresolvedHRefs = new HashSet (); // private HashMap hrefClients = new HashMap (); // true if the main document (not some external) is being processed boolean isMain = true; // set storing systemId's of all already read or currently being read documents private Set readDocuments = new HashSet (); // flag indicating whether an unknown elements should be ignored (otherwise a DebugException is thrown) private boolean ignoreUnknownElements = false; // unknown elements listener that is being notified about names of ignored elements private UnknownElementsListener elemsListener = null; // systemId of the currently read document private String thisSystemId = null; // mapping systemId (possibly relative) -> absolute systemId private HashMap systemIds = new HashMap (); // URL of the read document private URL docURL = null; // global cache used by @link #findOutermostPackages method private HashMap trackedPackages; // cache for resolved proxies enabling Enum and Struct creation and Association proxies private HashMap proxies_cache = new HashMap (); // configuration private XMIInputConfig config; // counter of created instances public int instancesCounter = 0; // xmi reference resolver private XMIReferenceResolver resolver = this; // xmi header consumer private XMIHeaderConsumer headerConsumer = null; // init ..................................................................... public XmiContext (RefPackage [] extents, URL docURL, XMIInputConfig config) { this (extents, config); this.docURL = docURL; if (docURL == null) thisSystemId = ""; // NOI18N else thisSystemId = docURL.toString (); readDocuments.add (thisSystemId); } public XmiContext (RefPackage [] extents, XMIInputConfig config) { String name; this.extents = extents; this.config = config; resolver = config.getReferenceResolver (); if (resolver == null) resolver = this; if (config instanceof InputConfig) { headerConsumer = ((InputConfig) config).getHeaderConsumer (); ignoreUnknownElements = ((InputConfig) config).isUnknownElementsIgnored(); elemsListener = ((InputConfig) config).getUnknownElementsListener(); } // check if ModelPackage is present among input packages (and store it) for (int i = 0; i < extents.length; i++) if (extents [i] instanceof ModelPackage) { modelPackage = (ModelPackage) extents [i]; break; } isMain = true; unresolvedRefs = new HashMap (); allUnresolvedHRefs = new HashSet (); allXmiReferences = new HashMap (); } // methods .................................................................. public void setVersion (Attributes attrs) { xmiNsPrefix = null; String version = attrs.getValue (XmiConstants.XMI_VersionAtt); if (version != null) { if (!(version.equals ("1.0") || version.equals ("1.1") || version.equals ("1.2"))) { throw new DebugException ("Malformed version parameter or unsupported verion of XMI: " + XmiConstants.XMI20_VERSION + " = " + version); } isXmi20 = false; } else { isXmi20 = true; xmiNsPrefix = ""; for (int x = 0; x < attrs.getLength (); x++) { String attrValue = attrs.getValue (x); if (attrValue.equals (XmiConstants.XMI_NAMESPACE_URI)) { String attrName = attrs.getQName (x); if (attrName.startsWith ("xmlns:")) { xmiNsPrefix = attrName.substring (6, attrName.length ()) + ":"; break; } } // if } // for version = attrs.getValue (xmiNsPrefix + XmiConstants.XMI20_VERSION); if (version == null) { throw new DebugException ("XMI version attribute is missing."); } if (!version.equals ("2.0")) { throw new DebugException ("Malformed version parameter or unsupported verion of XMI: " + xmiNsPrefix + XmiConstants.XMI20_VERSION + " = " + version); } } // else if (isXmi20) { XMI_HREF = xmiNsPrefix + XmiConstants.XMI_HREF; XMI_ID = xmiNsPrefix + XmiConstants.XMI20_ID; XMI_IDREF = xmiNsPrefix + XmiConstants.XMI20_IDREF; // obtain namespace declarations for (int x = 0; x < attrs.getLength (); x++) { String attrName = attrs.getQName (x); String attrValue = attrs.getValue (x); if (attrName.equals ("xmlns")) { if (attrValue.equals (XmiConstants.XML_SCHEMA_NAMESPACE_URI)) xmlNsPrefix = ""; else nsURIToPrefix.put (attrValue, null); } else if (attrName.startsWith ("xmlns:")) { String name = attrName.substring (6, attrName.length ()); if (attrValue.equals (XmiConstants.XML_SCHEMA_NAMESPACE_URI)) xmlNsPrefix = name + ":"; else { nsURIToPrefix.put (attrValue, name); } } } // for } else { XMI_HREF = XmiConstants.XMI_HREF; XMI_ID = XmiConstants.XMI_ID; XMI_IDREF = XmiConstants.XMI_IDREF; } trackedPackages = new HashMap (); // used as global cache for findOutermostPackages calls for (int i = 0; i < extents.length; i++) findOutermostPackages (extents [i].refOutermostPackage()); } /** * Detects all outermost packages related to the input extents and stores them. * Stores all related namespaces as well. */ private void findOutermostPackages (RefPackage pkg) { if (trackedPackages.get (pkg) != null) return; String name, uri; MofPackage metaObj = (MofPackage) pkg.refMetaObject (); if (metaObj.getContainer () == null) { Iterator iter = metaObj.getQualifiedName ().iterator (); String fqName = (String) iter.next (); while (iter.hasNext ()) fqName = fqName.concat (XmiConstants.DOT_SEPARATOR).concat ((String) iter.next ()); outermostPackages.put (fqName, pkg); } if (isXmi20) { uri = getTagValue (metaObj, XmiConstants.TAG_NS_URI); if (uri == null) { throw new DebugException ("No tag specifying a namespace uri is attached to MofPackage " + metaObj.getName ()); } name = (String) nsURIToPrefix.get (uri); if (name == null) { throw new DebugException ("XMI document does not contain namespace declaration for " + uri + ", MofPackage " + metaObj.getName ()); } } else { name = getTagValue (metaObj, XmiConstants.TAGID_XMI_NAMESPACE); } if (name != null) { List list = (List) namespaces.get (name); if (list == null) { list = new LinkedList (); namespaces.put (name, list); } list.add (pkg); } trackedPackages.put (pkg, pkg); Iterator iter = pkg.refAllPackages ().iterator (); while (iter.hasNext ()) { findOutermostPackages ((RefPackage) iter.next ()); } } public static String getTagValue (ModelElement element, String tagId) { Collection tags = ((ModelPackage) element.refImmediatePackage()). getAttachesTo().getTag (element); Tag tag = null; for (Iterator it = tags.iterator(); it.hasNext();) { Object obj = it.next (); if (!(obj instanceof Tag)) continue; Tag temp = (Tag) obj; if (tagId.equals (temp.getTagId ())) { tag = temp; break; } } if (tag == null) return null; Collection values = tag.getValues (); if (values.size () == 0) return null; return (String) values.iterator ().next (); } /** * This method is called to applay already read differences on a given document. * * @param href link to an external document * @param diffs list of differences (see @link #XmiElement.Difference.Diff) to be applyed */ public void resolveDifferences (String href, HashMap diffs) { if (href == null) throw new DebugException ("External document to applay differences on is not specified."); try { XmiSAXReader reader = new XmiSAXReader (config); URL doc; if (docURL != null) { String path = docURL.getPath (); int copyTo = path.lastIndexOf ("/"); if (copyTo > -1) { href = path.substring (0, copyTo) + "/" + href; } doc = new URL (docURL.getProtocol (), this.docURL.getHost (), href); } else { doc = new URL (href); } Collection res = reader.read (doc, extents, null, diffs); outermostInstances.addAll (res); } catch (Exception e) { throw new DebugException (e.getMessage ()); } } /** * This private method is called to obtain and cache all class and instance * scoped attributes and references. * Related caches are: * @link #instanceAttributes_cache, @link #instanceReferences_cache, * @link #instanceElementsByName_cache */ private void cacheContainedElements (RefClass proxyClass) { List temp = new LinkedList (); MofClass metaProxyClass = (MofClass) proxyClass.refMetaObject (); List superClasses = metaProxyClass.allSupertypes (); Namespace namespace = null; Iterator it = superClasses.iterator (); while (it.hasNext ()) { namespace = (Namespace) it.next (); temp.addAll (namespace.getContents ()); } temp.addAll (metaProxyClass.getContents ()); List instanceAttributes = new LinkedList (); List instanceReferences = new LinkedList (); List classAttributes = new LinkedList (); HashMap instanceElementsByName = new HashMap (); HashMap classElementsByName = new HashMap (); it = temp.iterator (); while (it.hasNext ()) { RefObject refObject = (RefObject) it.next (); if (refObject instanceof Feature) { boolean instanceLevel = ((Feature) refObject).getScope ().equals (ScopeKindEnum.INSTANCE_LEVEL); if ((refObject instanceof Attribute) && (!((Attribute) refObject).isDerived ())) { if (instanceLevel) { instanceAttributes.add (refObject); instanceElementsByName.put (((Attribute) refObject).getName (), refObject); } else { classAttributes.add (refObject); classElementsByName.put (((Attribute) refObject).getName (), refObject); } } else if (refObject instanceof Reference) { if (instanceLevel) { instanceReferences.add (refObject); instanceElementsByName.put (((Reference) refObject).getName (), refObject); } } // else } // if (refObject instanceof Feature) } // while instanceAttributes_cache.put (proxyClass, instanceAttributes); instanceReferences_cache.put (proxyClass, instanceReferences); instanceElementsByName_cache.put (proxyClass, instanceElementsByName); classAttributes_cache.put (proxyClass, classAttributes); classElementsByName_cache.put (proxyClass, instanceElementsByName); } /** * For a given class proxy, returns list of all instance-scoped attributes * (references are not included). */ public List instanceAttributes (RefClass refClass) { List list = (List) instanceAttributes_cache.get (refClass); if (list == null) { cacheContainedElements (refClass); list = (List) instanceAttributes_cache.get (refClass); } return list; } /** * For a given class proxy, returns list of all (instance-scoped) references. */ public List instanceReferences (RefClass refClass) { List list = (List) instanceReferences_cache.get (refClass); if (list == null) { cacheContainedElements (refClass); list = (List) instanceReferences_cache.get (refClass); } return list; } /** * Returns an attribute, resp. a reference according to given class proxy and * attribute, resp. reference name. * Used when attribute values stored as XLM element attributes are being resolved. */ public StructuralFeature instanceElementByName (RefClass refClass, String name) { HashMap map = (HashMap) instanceElementsByName_cache.get (refClass); if (map == null) { cacheContainedElements (refClass); map = (HashMap) instanceElementsByName_cache.get (refClass); } StructuralFeature feature = (StructuralFeature) map.get (name); if (feature == null) { // [PENDING] // throw new DebugException ("Attribute name cannot be resolved: " + name); } return feature; } public List staticAttributes (RefClass refClass) { List list = (List) classAttributes_cache.get (refClass); if (list == null) { cacheContainedElements (refClass); list = (List) classAttributes_cache.get (refClass); } return list; } public Attribute staticAttributeByName (RefClass refClass, String name) { HashMap map = (HashMap) classElementsByName_cache.get (refClass); if (map == null) { cacheContainedElements (refClass); map = (HashMap) classElementsByName_cache.get (refClass); } return (Attribute) map.get (name); } /** * Returns list of all fields belonging to the given StructureType. */ public List structureFields (StructureType type) { List fields = (List) structureFields_cache.get (type); if (fields != null) return fields; // find fields and cache them fields = new LinkedList (); Iterator content = type.getContents ().iterator (); while (content.hasNext ()) { Object element = content.next (); if (element instanceof StructureField) fields.add (element); } // while structureFields_cache.put (type, fields); return fields; } /** * Returns labels prefix given by "unprefix" tag attached to EnumerationType or * the empty String if no such tag is present. */ public String labelPrefix (EnumerationType type) { if (isXmi20) return ""; String prefix = (String) labelPrefix_cache.get (type); if (prefix != null) return prefix; prefix = getTagValue (type, XmiConstants.TAGID_XMI_ENUMERATION_UNPREFIX); if (prefix == null) prefix = ""; labelPrefix_cache.put (type, prefix); return prefix; } /** * Resolves given fully qualified or namespace prefixed element name. * If the name corresponds to MofClass, related proxy class is returned instead of it. */ public Object resolveElementName (String fqName) { Object result = resolvedNames_cache.get (fqName); if (result != null) return result; int pos = fqName.indexOf (XmiConstants.NS_SEPARATOR); RefPackage outermostPackage = null; if ((pos < 0) && !isXmi20) { // namespace not presented in name, fully qualified name is given int index = fqName.indexOf (XmiConstants.DOT_SEPARATOR); String packageName = fqName; while (index > -1) { packageName = packageName.substring (0, index); outermostPackage = (RefPackage) outermostPackages.get (packageName); if (outermostPackage != null) break; index = packageName.indexOf (XmiConstants.DOT_SEPARATOR); } if (outermostPackage == null) { if (ignoreUnknownElements) { return null; } else { throw new DebugException ("Element name cannot be resolved, unknown package: " + fqName); } } StringTokenizer tokenizer = new StringTokenizer (fqName, "."); LinkedList nameParts = new LinkedList (); tokenizer.nextToken (); // skip the outermost package name while (tokenizer.hasMoreTokens ()) nameParts.add (tokenizer.nextToken ()); Namespace namespace = (Namespace) outermostPackage.refMetaObject (); try { RefObject obj = namespace.resolveQualifiedName (nameParts); if (obj instanceof MofClass) { RefPackage refPkg = (RefPackage) findProxy ((MofClass)obj); if (refPkg != null) result = refPkg.refClass (obj); } else result = obj; } catch (NameNotResolvedException e) { } } else { // name contains namespace prefix, it is of the form NAMESPACE:NAME1(.NAME2)? String nsPrefixName; if (pos < 0) { nsPrefixName = ""; // XMI 2.0 & default namespace } else { nsPrefixName = fqName.substring (0, pos); } List packages = (List) namespaces.get (nsPrefixName); if (packages == null) { if (ignoreUnknownElements) { return null; } else { throw new DebugException ("Namespace cannot be resolved: " + nsPrefixName); } } int pos2 = fqName.indexOf (XmiConstants.DOT_SEPARATOR); Iterator iter = packages.iterator (); while (iter.hasNext ()) { outermostPackage = (RefPackage) iter.next (); try { if (pos2 == -1) { // 1) a "class level" element RefObject metaClass = ((GeneralizableElement) outermostPackage.refMetaObject ()). lookupElementExtended (fqName.substring (pos + 1, fqName.length ())); if (metaClass instanceof MofClass) result = outermostPackage.refClass (metaClass); else result = metaClass; } else { // 2) an "attribute level" element Classifier element = (Classifier) ((GeneralizableElement) outermostPackage.refMetaObject ()). lookupElementExtended (fqName.substring (pos + 1, pos2)); if (element == null) continue; result = element.lookupElementExtended (fqName.substring (pos2 + 1, fqName.length ())); } // else } catch (NameNotFoundException e) { } if (result != null) break; } // while } // else if (result == null) { if (ignoreUnknownElements) { return null; } else { throw new DebugException("Name cannot be resolved: " + fqName); } } resolvedNames_cache.put (fqName, result); return result; } /** * Called by XMIElement.Header to process the read XMI reader. */ public void receiveHeader (String header) { if (headerConsumer != null) { byte [] bytes = new byte [header.length()]; for (int x = 0; x < bytes.length; x++) { bytes [x] = (byte) header.charAt (x); } headerConsumer.consumeHeader (new ByteArrayInputStream (bytes)); } // if } /** * Called when the whole XMI document has been read. * Handles setting of Imports related to Aliases created instead of Corba primitive types. */ public void finish () { if (!isMain) return; HashMap checkedPackages = new HashMap (); Iterator iter = corbaTypesReferencingPrimitiveTypes.iterator (); while (iter.hasNext ()) { ModelElement element = (ModelElement) iter.next (); Namespace container = element.getContainer (); Namespace owner = container.getContainer (); while (owner != null) { container = owner; owner = owner.getContainer (); } while (container.getContainer () != null) container = container.getContainer (); if ((container instanceof MofPackage) && (checkedPackages.get (container) == null)) { MofPackage pkg = (MofPackage) container; Iterator content = pkg.getContents ().iterator (); boolean found = false; while (content.hasNext ()) { ModelElement el = (ModelElement) content.next (); if (el instanceof Import) { if (primitiveTypesPackage.equals (((Import) el).getImportedNamespace ())) { found = true; break; } // if } // if } // while if (!found) { Import imp = modelPackage.getImport ().createImport ( XmiConstants.PRIMITIVE_TYPES_PACKAGE, ANNOTATION, VisibilityKindEnum.PUBLIC_VIS, false ); imp.setImportedNamespace (primitiveTypesPackage); imp.setContainer (pkg); } // if checkedPackages.put (pkg, pkg); } // if } // while checkedPackages = null; Logger.getDefault().log ("Number of created instances: " + instancesCounter); } public XmiElement resolveInstanceOrReference (XmiElement parent, String qName, Attributes attrs) { String idRef = attrs.getValue (XMI_IDREF); if (idRef != null) { REFERENCE_VALUE.init (parent, idRef); return REFERENCE_VALUE; } idRef = attrs.getValue (XMI_HREF); if (idRef != null) { REFERENCE_VALUE.initExternal (parent, idRef); return REFERENCE_VALUE; } Object ref = resolveElementName (qName); if (ref == null && ignoreUnknownElements) { return new XmiElement.Dummy(parent, this, qName); } if (ref instanceof DataTypeClass) { // =================================== // MOF 1.3 compatibility // =================================== return new XmiElement.DataTypeElement (parent, this, qName, attrs); } return new XmiElement.Instance (parent, this, qName, (RefClass) ref, attrs); } /** * Adds created outermost object to the collection returned by * @link #XmiSAXReader.read method as a result. */ public void addOutermostObject (RefObject obj) { outermostInstances.add (obj); } /** * When the reading of XMI is finished, returns collection of all created * outermost objects. */ public Collection getOutermostObjects () { return outermostInstances; } // XMIReferenceResolver implementation ...................................... public void register(String systemId, String xmiId, RefObject object) { String href = systemId + '#' + xmiId; List list = (List) hrefClients.remove (href); if (list != null) { Iterator iter = list.iterator (); while (iter.hasNext ()) { ((Client) iter.next ()).resolvedReference (href, object, true); } // while } // if } public void resolve(XMIReferenceResolver.Client client, RefPackage extent, String systemId, XMIInputConfig configuration, Collection hrefs) throws MalformedXMIException, IOException { String href; listOfUnresolvedHRefs = new LinkedList (); unresolvedExternalRefs = new HashMap (); Iterator iter = hrefs.iterator (); while (iter.hasNext ()) { href = (String) iter.next (); List list = (List) hrefClients.get (href); if (list == null) { list = new LinkedList (); hrefClients.put (href, list); } list.add (client); } // while iter = hrefs.iterator (); while (iter.hasNext ()) { href = (String) iter.next (); XMIReferenceProvider.XMIReference ref = toXMIReference (href); String systId = ref.getSystemId (); String xmiId = ref.getXmiId (); RefObject obj = getReference (systId, xmiId); if (obj != null) { register (systId, xmiId, obj); } else { if (!readDocuments.contains (systId)) { URL url = toURL (systId); if ((url == null) || (!readDocuments.contains (url.toString ()))) readExternalDocument (systId); } // if } } // while } // .......................................................................... /** * If an instance identified by a given xmiId has been created, it is returned, * otherwise |
... 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.