/* * Copyright 2008 Lockheed Martin Corporation, except as stated in the file * entitled Licensing-Information. * * All modifications copyright 2009-2015 Data Access Technologies, Inc. * * Licensed under the Academic Free License version 3.0 * (http://www.opensource.org/licenses/afl-3.0.php), except as stated * in the file entitled Licensing-Information. * * Contributors: * MDS - initial API and implementation * */ package org.modeldriven.fuml.xmi.stream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.xml.namespace.QName; import javax.xml.stream.events.Namespace; import javax.xml.stream.events.XMLEvent; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.modeldriven.fuml.config.FumlConfiguration; import org.modeldriven.fuml.config.NamespaceDomain; import org.modeldriven.fuml.xmi.XmiConstants; import org.modeldriven.fuml.xmi.XmiException; /** * Encapsulates context information for the current XMI stream, including * namespaces and other resources. Namespaces are loaded from the (XML) root * element based on a configurable set of supported namespaces for various * domains. If no namespace is found within the supported namespaces for a * particular domain, an error is thrown. * * @author Scott Cinnamond */ public class StreamContext { private static Log log = LogFactory.getLog(StreamContext.class); private Namespace[] namespaces; private Namespace defaultNamespace; private Map<NamespaceDomain, Namespace> namespaceDomainMap = new HashMap<NamespaceDomain, Namespace>(); private Map<String, Namespace> namespaceLocalNameMap = new HashMap<String, Namespace>(); private Map<String, Namespace> namespaceURIMap = new HashMap<String, Namespace>(); @SuppressWarnings("unused") private StreamContext() {} public StreamContext(XMLEvent root) { loadNamespaces(root); loadDefaultNamespace(root); } private void loadDefaultNamespace(XMLEvent root) { defaultNamespace = this.getUmlNamespace(); } @SuppressWarnings("unchecked") private void loadNamespaces(XMLEvent root) { List<Namespace> list = new ArrayList<Namespace> (); Iterator<Namespace> namespaceIter = root.asStartElement().getNamespaces(); while (namespaceIter.hasNext()) { Namespace namespace = namespaceIter.next(); list.add(namespace); QName name = namespace.getName(); if (log.isDebugEnabled()) log.debug("root namespace: " + name.toString()); String uri = namespace.getValue(); if (!XmiConstants.NAMESPACE_PREFIX.equals(name.getPrefix())) continue; //not a namespace namespaceLocalNameMap.put(name.getLocalPart(), namespace); namespaceURIMap.put(namespace.getNamespaceURI(), namespace); NamespaceDomain domain = FumlConfiguration.getInstance().findNamespaceDomain(uri); if (domain == null) { log.debug("could not find domain for namespace '" + uri + "' - mapping only by local name"); continue; } Namespace existing = this.namespaceDomainMap.get(domain); if (existing != null) throw new XmiException("multiple " + domain.value() + " namespaces (" + existing.getNamespaceURI() + ", " + namespace.getNamespaceURI() + ")"); this.namespaceDomainMap.put(domain, namespace); } // while() if (getXmiNamespace() == null) { throw new XmiException(createNamespaceMessge(NamespaceDomain.XMI)); } if (getUmlNamespace() == null) { throw new XmiException(createNamespaceMessge(NamespaceDomain.UML)); } namespaces = new Namespace[list.size()]; list.toArray(namespaces); } private String createNamespaceMessge(NamespaceDomain domain) { String[] supported = FumlConfiguration.getInstance().getSupportedNamespaceURIsForDomain(domain); String msg = "no supported " + domain.value().toUpperCase() + " namespace found - expected one of ["; for (int i = 0; i < supported.length; i++) { if (i > 0) msg += ", "; msg += supported[i]; } msg += "] (remedy: use supported namespace or modify configuration file '" + FumlConfiguration.getInstance().getActiveConfigFileName() + "')"; return msg; } public Namespace getXmiNamespace() { return namespaceDomainMap.get(NamespaceDomain.XMI); } public Namespace getUmlNamespace() { return namespaceDomainMap.get(NamespaceDomain.UML); } public Namespace getDefaultNamespace() { return defaultNamespace; } public Namespace getEcoreNamespace() { return namespaceDomainMap.get(NamespaceDomain.ECORE); } public Namespace getMagicdrawNamespace() { return namespaceDomainMap.get(NamespaceDomain.MAGICDRAW); } public Namespace getNamespaceByLocalName(String localName) { return this.namespaceLocalNameMap.get(localName); } public Namespace getNamespaceByURI(String uri) { return this.namespaceURIMap.get(uri); } public Namespace[] getNamespaces() { return namespaces; } }