/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * http://glassfish.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package com.sun.xml.ws.db.sdo; import com.sun.xml.ws.util.xml.XmlUtil; import commonj.sdo.DataObject; import commonj.sdo.Property; import commonj.sdo.Type; import commonj.sdo.impl.HelperProvider; import commonj.sdo.helper.HelperContext; import commonj.sdo.helper.TypeHelper; import commonj.sdo.helper.XMLDocument; import commonj.sdo.helper.XSDHelper; import org.eclipse.persistence.sdo.SDOType; import org.eclipse.persistence.sdo.helper.SDOXMLHelper; import org.eclipse.persistence.sdo.helper.SDOXSDHelper; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.helpers.NamespaceSupport; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.stream.XMLStreamReader; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.FileInputStream; import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TimeZone; /** * A set of core utility methods that shapes the sdo databinding * Created by IntelliJ IDEA. * User: giglee * Date: May 13, 2009 * Time: 10:21:12 AM * To change this template use File | Settings | File Templates. */ public class SDOUtils { public static final String NS_XMLNS = "http://www.w3.org/2001/XMLSchema"; public static final String NS_WSDL = "http://schemas.xmlsoap.org/wsdl/"; private static final String NS_XSD = "http://www.w3.org/2001/XMLSchema"; private static final QName SCHEMA_INCLUDE_QNAME = new QName(NS_XSD, "include"); private static final QName SCHEMA_IMPORT_QNAME = new QName(NS_XSD, "import"); public static final QName QNAME_SCHEMA = new QName(NS_XMLNS, "schema"); static volatile TransformerFactory transformerFactory = null; static volatile DocumentBuilderFactory dbf = null; public static Transformer newTransformer() { if (transformerFactory == null) { synchronized(SDOUtils.class) { if (transformerFactory == null) { transformerFactory = XmlUtil.newTransformerFactory(false); } } } try { return transformerFactory.newTransformer(); } catch (TransformerConfigurationException e) { throw new RuntimeException(e); } } public static DocumentBuilder newDocumentBuilder() { if (dbf == null) { synchronized(SDOUtils.class) { if (dbf == null) { DocumentBuilderFactory tmpDBF = XmlUtil.newDocumentBuilderFactory(false); tmpDBF.setValidating(false); tmpDBF.setNamespaceAware(true); tmpDBF.setIgnoringElementContentWhitespace(true); tmpDBF.setIgnoringComments(true); dbf = tmpDBF; } } } try { DocumentBuilder documentBuilder = dbf.newDocumentBuilder(); return documentBuilder; } catch (ParserConfigurationException e) { throw new RuntimeException(e); } } /** * Serialize a DataObject to the specified element * Per bug 6120620,, we use only GMT timezone */ public static Element sdoToDom(HelperContext hc, DataObject obj, String targetNamespace, String localName) throws ParserConfigurationException, IOException { SDOXMLHelper sdoXMLHelper = (SDOXMLHelper) hc.getXMLHelper(); // Removed this from JRF for ADF use case. //sdoXMLHelper.setTimeZone(TimeZone.getTimeZone("GMT")); sdoXMLHelper.setTimeZoneQualified(true); XMLDocument xmlDoc = sdoXMLHelper.createDocument(obj, targetNamespace, localName); if (xmlDoc == null) { return null; } Document doc = newDocumentBuilder().newDocument(); DOMResult result = new DOMResult(doc); sdoXMLHelper.save(xmlDoc, result, null); return ((Document) result.getNode()).getDocumentElement(); } /** * Serialize a DataObject to the specified xml element in text xml * * @param hc * @param obj * @param targetNamespace * @param localName * @return * @throws ParserConfigurationException * @throws IOException */ public static Source sdoToXML(HelperContext hc, DataObject obj, String targetNamespace, String localName) throws ParserConfigurationException, IOException { SDOXMLHelper sdoXMLHelper = (SDOXMLHelper) hc.getXMLHelper(); sdoXMLHelper.setTimeZone(TimeZone.getTimeZone("GMT")); sdoXMLHelper.setTimeZoneQualified(true); XMLDocument xmlDoc = sdoXMLHelper.createDocument(obj, targetNamespace, localName); if (xmlDoc == null) { return null; } ByteArrayOutputStream bout = new ByteArrayOutputStream(); StreamResult result = new StreamResult(bout); sdoXMLHelper.save(xmlDoc, result, null); byte[] bytes = bout.toByteArray(); System.out.println("data obj converted to xml: " + new String(bytes)); return new StreamSource(new ByteArrayInputStream(bytes)); } /** * Register the types defined in the given schema with the given sdo helper context * * @param context * @param schemas */ public static void registerSDOContext(HelperContext context, List<Source> schemas) { SDOXSDHelper xsdHelper = (SDOXSDHelper) context.getXSDHelper(); SDODatabindingSchemaResolver schemaResolver = new SDODatabindingSchemaResolver(schemas); for (Source source : schemas) { //SDOUtils.printDOM(source); xsdHelper.define(source, schemaResolver); } } public static List<Source> getSchemaClosureFromWSDL(Source wsdlSource) { String systemId = wsdlSource.getSystemId(); Document wsdl = createDOM(wsdlSource); List<Source> list = new ArrayList<Source>(); addSchemaFragmentSource(wsdl, systemId, list); return list; } public static Document createDOM(Source wsdlSource) { Transformer trans = newTransformer(); DocumentBuilder builder = newDocumentBuilder(); Document doc = builder.newDocument(); DOMResult result = new DOMResult(doc); try { trans.transform(wsdlSource, result); } catch (TransformerException te) { throw new RuntimeException(te); } return (Document) result.getNode(); } public static Map<String, Source> getMetadataClosure(List<Source> schemas) { Map<String, Source> closureDocs = new HashMap<String, Source>(); Map<String, Source> currentDocs = new HashMap<String, Source>(); Set<String> remaining = new HashSet<String>(); for (Source src : schemas) { currentDocs.put(src.getSystemId(), src); } remaining.addAll(currentDocs.keySet()); while (!remaining.isEmpty()) { Iterator<String> it = remaining.iterator(); String current = it.next(); remaining.remove(current); Source currentDoc = currentDocs.get(current); if (currentDoc == null) { currentDoc = loadSourceFromURL(current); } Set<String> imports = new HashSet<String>(); currentDoc = getImports(currentDoc, imports); closureDocs.put(current, currentDoc); for (String importedDoc : imports) { if (closureDocs.get(importedDoc) == null) { remaining.add(importedDoc); } } } return closureDocs; } @SuppressWarnings("CallToThreadDumpStack") private static Source loadSourceFromURL(String systemID) { Source targetXSD; try { URL targetURL = new URL(systemID); InputStream is = targetURL.openStream(); targetXSD = new StreamSource(is); targetXSD.setSystemId(targetURL.toExternalForm()); } catch (IOException e) { e.printStackTrace(); return null; } return targetXSD; } private static Source getImports(Source currentDoc, Set<String> importedDocs) { Document doc = createDOM(currentDoc); Element root = doc.getDocumentElement(); try { NodeList imports = root.getElementsByTagNameNS(SCHEMA_INCLUDE_QNAME.getNamespaceURI(), SCHEMA_INCLUDE_QNAME.getLocalPart()); NodeList includes = root.getElementsByTagNameNS(SCHEMA_IMPORT_QNAME.getNamespaceURI(), SCHEMA_INCLUDE_QNAME.getLocalPart()); if (imports != null) { for (int i = 0; i < imports.getLength(); i++) { Element e = (Element) imports.item(i); String importedDoc = e.getAttributeNS(NS_XMLNS, "schemaLocation"); if (importedDoc != null) { URL u = new URL(currentDoc.getSystemId()); importedDocs.add(new URL(u, importedDoc).toString()); } } } if (includes != null) { for (int i = 0; i < imports.getLength(); i++) { Element e = (Element) imports.item(i); String importedDoc = e.getAttributeNS(NS_XMLNS, "schemaLocation"); if (importedDoc != null) { URL u = new URL(currentDoc.getSystemId()); importedDocs.add(new URL(u, importedDoc).toString()); } } } } catch (Exception e) { throw new RuntimeException(e); } return new DOMSource(doc, currentDoc.getSystemId()); } private static void addSchemaFragmentSource(Document doc, String systemId, List<Source> list) { Element e = doc.getDocumentElement(); assert e.getNamespaceURI().equals(NS_WSDL); assert e.getLocalName().equals("definitions"); NodeList typesList = e.getElementsByTagNameNS(NS_WSDL, "types"); for (int i = 0; i < typesList.getLength(); i++) { NodeList schemaList = ((Element) typesList.item(i)).getElementsByTagNameNS(NS_XMLNS, "schema"); for (int j = 0; j < schemaList.getLength(); j++) { Element elem = (Element) schemaList.item(j); NamespaceSupport nss = new NamespaceSupport(); buildNamespaceSupport(nss, elem); patchDOMFragment(nss, elem); list.add(new DOMSource(elem, systemId + "#schema" + j)); } } } private static void buildNamespaceSupport(NamespaceSupport nss, Node node) { if (node == null || node.getNodeType() != Node.ELEMENT_NODE) { return; } buildNamespaceSupport(nss, node.getParentNode()); nss.pushContext(); NamedNodeMap atts = node.getAttributes(); for (int i = 0; i < atts.getLength(); i++) { Attr a = (Attr) atts.item(i); if ("xmlns".equals(a.getPrefix())) { nss.declarePrefix(a.getLocalName(), a.getValue()); continue; } if ("xmlns".equals(a.getName())) { nss.declarePrefix("", a.getValue()); continue; } } } private static void patchDOMFragment(NamespaceSupport nss, Element elem) { NamedNodeMap atts = elem.getAttributes(); for (Enumeration en = nss.getPrefixes(); en.hasMoreElements();) { String prefix = (String) en.nextElement(); for (int i = 0; i < atts.getLength(); i++) { Attr a = (Attr) atts.item(i); if (!"xmlns".equals(a.getPrefix()) || !a.getLocalName().equals("prefix")) { elem.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:" + prefix, nss.getURI(prefix)); } } } } public static Object unwrapPrimitives(Object obj) { if (obj == null) { return obj; } if (!(obj instanceof DataObject)) { return obj; } DataObject dataObject = (DataObject) obj; if (dataObject.getClass().getName().endsWith("WrapperImpl")) { if (dataObject.get(0) != null) { System.out.println("unwrapped object: " + dataObject.get(0).getClass().getName()); } return dataObject.get(0); } return obj; } @SuppressWarnings("CallToThreadDumpStack") public static void printDOM(Source src) { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); StreamResult sr = new StreamResult(bos); TransformerFactory tf = XmlUtil.newTransformerFactory(false); Transformer trans = tf.newTransformer(); trans.transform(src, sr); System.out.println("**********\n" + bos.toString()); bos.close(); } catch (Exception e) { e.printStackTrace(); } } public static String dom2String(DOMSource domSrc) throws TransformerConfigurationException, TransformerException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); StreamResult sr = new StreamResult(bos); TransformerFactory tf = XmlUtil.newTransformerFactory(false); Transformer trans = tf.newTransformer(); trans.transform(domSrc, sr); return sr.toString(); } // note only use for debugging, once the reader is read, the cursor can't be set back @SuppressWarnings("CallToThreadDumpStack") public static void printXMLReader(XMLStreamReader xml) { try { Document doc = SDOUtils.newDocument(); SAX2DOMContentHandler handler = new SAX2DOMContentHandler(doc); Stax2SAXAdapter adapter = new Stax2SAXAdapter(xml, false); adapter.parse(handler); printDOM(new DOMSource(doc)); } catch (Exception e) { e.printStackTrace(); } } /** * get the element name represented by this property * @param context * @param p * @return */ public static QName getPropertyElementName(HelperContext context, Property p) { XSDHelper helper = context.getXSDHelper(); String localName = p.getName(); String ns = helper.getNamespaceURI(p); return new QName(ns, localName); } // used by tests public static List defineSchema(HelperContext hc, File f) throws Exception { FileInputStream fin = null; try { fin = new FileInputStream(f); InputStreamReader reader = new InputStreamReader(fin); StreamSource source = new StreamSource(reader); return ((SDOXSDHelper) hc.getXSDHelper()).define(source, null); } finally { if (fin != null) { try { fin.close(); } catch (IOException ioe) { } } } } public static Document newDocument() { return newDocumentBuilder().newDocument(); } /** * Check whether a java class is supported * The builtin type includes all the default type mappings specified in the SDO Spec * @param javaType * @param qname * @return */ public static boolean validateBuiltinType(String javaType, QName qname) { return validateSupportedType(HelperProvider.getDefaultContext(), javaType, qname); } public static boolean validateSupportedType(HelperContext hc, String javaType, QName qname) { TypeHelper typeHelper = hc.getTypeHelper(); if (qname != null) { Type type = typeHelper.getType(qname.getNamespaceURI(), qname.getLocalPart()); String java = ((SDOType) type).getInstanceClassName(); if (java != null) { return java.equals(javaType); } return false; } else { if (isPrimitive(javaType)) { return true; } try { Class cls = Thread.currentThread().getContextClassLoader().loadClass(javaType); Type type = typeHelper.getType(cls); return type == null ? false : true; } catch (Exception e) { e.printStackTrace(); return false; } } } // all primitives listed here is supported private static boolean isPrimitive(String type) { if (type.equals("int") || type.equals("short") || type.equals("long") || type.equals("byte") || type.equals("float") || type.equals("double") || type.equals("boolean")) { return true; } // the rest we will let toplink handle it return false; } public static Set<SchemaInfo> getSchemas(File f) throws Exception { FileInputStream fin = null; try { fin = new FileInputStream(f); StreamSource source = new StreamSource(fin); source.setSystemId(f.toURL().toExternalForm()); List<Source> main_schema = new ArrayList<Source>(); main_schema.add(source); Map<String, Source> map = SDOUtils.getMetadataClosure(main_schema); Set<SchemaInfo> schemas = new HashSet<SchemaInfo>(); for (Map.Entry<String, Source> entry : map.entrySet()) { SchemaInfo info = new SchemaInfo(entry.getKey(), null, entry.getValue()); schemas.add(info); } return schemas; } finally { if (fin != null) { fin.close(); } } } public static Set<SchemaInfo> getSchemas(String filePath) throws Exception { Set<SchemaInfo> schemas = new HashSet<SchemaInfo>(); Document document = newDocumentBuilder().parse(new File(filePath)); Element rootEl = document.getDocumentElement(); if (QNAME_SCHEMA.equals(new QName(rootEl.getNamespaceURI(), rootEl.getLocalName()))) { SchemaInfo info = new SchemaInfo(filePath, null, new DOMSource(rootEl)); schemas.add(info); } else if ("http://schemas.xmlsoap.org/wsdl/".equals(rootEl.getNamespaceURI())) { Element types = null; Node n = rootEl.getFirstChild(); while (types == null) { if (n instanceof Element && ((Element)n).getLocalName().equals("types")) { types = (Element)n; } else { n = n.getNextSibling(); } } NodeList nl = types.getChildNodes(); for (int i = 0; i < nl.getLength(); i++ ) { Node x = nl.item(i); if (x instanceof Element && ((Element)x).getLocalName().equals("schema")) { SchemaInfo info = new SchemaInfo(filePath, null, new DOMSource((Element)x)); schemas.add(info); } } // Definition def = WSDLHelper.readWsdl(url, document); // SchemaCollection schemaCollection = SchemaAnalyzer.collectSchemas(def); // schemas = SchemaHelper.getSchemaInfos(url.toString(), schemaCollection,true); // for (SchemaInfo schema : schemas) { // Element schemaElement = schema.getSchemaElement(); // SchemaHelper.fixMissingNamespaces(schemaElement); // } } else { // throw new IOException("Document found at '" + sdoSchema + "' is not a valid schema/wsdl document."); } return schemas; } }