|
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.