001 /** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one or more 004 * contributor license agreements. See the NOTICE file distributed with 005 * this work for additional information regarding copyright ownership. 006 * The ASF licenses this file to You under the Apache License, Version 2.0 007 * (the "License"); you may not use this file except in compliance with 008 * the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 package org.apache.geronimo.deployment.xmlbeans; 019 020 import java.util.Map; 021 import java.util.HashMap; 022 import java.util.ArrayList; 023 import java.util.Collection; 024 import java.util.Iterator; 025 import java.util.List; 026 import java.io.File; 027 import java.io.IOException; 028 import java.io.InputStream; 029 import java.net.URL; 030 031 import javax.xml.namespace.QName; 032 033 import org.w3c.dom.Element; 034 import org.apache.xmlbeans.XmlOptions; 035 import org.apache.xmlbeans.XmlException; 036 import org.apache.xmlbeans.XmlObject; 037 import org.apache.xmlbeans.SchemaTypeLoader; 038 import org.apache.xmlbeans.SchemaType; 039 import org.apache.xmlbeans.QNameSet; 040 import org.apache.xmlbeans.XmlValidationError; 041 042 /** 043 * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $ 044 */ 045 public class XmlBeansUtil { 046 private static final Map NAMESPACE_UPDATES = new HashMap(); 047 //TODO thread safe? conncurrentReaderMap? 048 private static final Map substitutionGroups = new HashMap(); 049 private static final XmlObject[] NO_ELEMENTS = new XmlObject[]{}; 050 051 static { 052 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/application-client", "http://geronimo.apache.org/xml/ns/j2ee/application-client-1.2"); 053 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/application-client-1.1", "http://geronimo.apache.org/xml/ns/j2ee/application-client-1.2"); 054 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/application", "http://geronimo.apache.org/xml/ns/j2ee/application-1.2"); 055 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/application-1.1", "http://geronimo.apache.org/xml/ns/j2ee/application-1.2"); 056 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/deployment", "http://geronimo.apache.org/xml/ns/deployment-1.2"); 057 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/deployment-1.1", "http://geronimo.apache.org/xml/ns/deployment-1.2"); 058 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/connector", "http://geronimo.apache.org/xml/ns/j2ee/connector-1.2"); 059 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/connector-1.1", "http://geronimo.apache.org/xml/ns/j2ee/connector-1.2"); 060 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/deployment/javabean", "http://geronimo.apache.org/xml/ns/deployment/javabean-1.0"); 061 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/loginconfig", "http://geronimo.apache.org/xml/ns/loginconfig-1.2"); 062 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/loginconfig-1.1", "http://geronimo.apache.org/xml/ns/loginconfig-1.2"); 063 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/naming", "http://geronimo.apache.org/xml/ns/naming-1.2"); 064 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/naming-1.1", "http://geronimo.apache.org/xml/ns/naming-1.2"); 065 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/security", "http://geronimo.apache.org/xml/ns/security-1.2"); 066 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/security-1.1", "http://geronimo.apache.org/xml/ns/security-1.2"); 067 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/web", "http://geronimo.apache.org/xml/ns/j2ee/web-1.2"); 068 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/web-1.1", "http://geronimo.apache.org/xml/ns/j2ee/web-1.2"); 069 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/web/jetty", "http://geronimo.apache.org/xml/ns/j2ee/web/jetty-1.2"); 070 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/web/jetty-1.1", "http://geronimo.apache.org/xml/ns/j2ee/web/jetty-1.2"); 071 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/web/jetty/config", "http://geronimo.apache.org/xml/ns/j2ee/web/jetty/config-1.0"); 072 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/web/tomcat", "http://geronimo.apache.org/xml/ns/j2ee/web/tomcat-1.2"); 073 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/web/tomcat-1.1", "http://geronimo.apache.org/xml/ns/j2ee/web/tomcat-1.2"); 074 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/web/tomcat/config", "http://geronimo.apache.org/xml/ns/j2ee/web/tomcat/config-1.0"); 075 NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/openejb-jar", "http://openejb.apache.org/xml/ns/openejb-jar-2.2"); 076 NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/openejb-jar-2.1", "http://openejb.apache.org/xml/ns/openejb-jar-2.2"); 077 NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/openejb-jar-2.2", "http://openejb.apache.org/xml/ns/openejb-jar-2.2"); 078 NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/pkgen", "http://openejb.apache.org/xml/ns/pkgen-2.1"); 079 NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/pkgen-2.0", "http://openejb.apache.org/xml/ns/pkgen-2.1"); 080 NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/corba-css-config_1_0", "http://openejb.apache.org/xml/ns/corba-css-config-2.1"); 081 NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/corba-css-config-2.0", "http://openejb.apache.org/xml/ns/corba-css-config-2.1"); 082 NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/corba-tss-config_1_0", "http://openejb.apache.org/xml/ns/corba-tss-config-2.1"); 083 NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/corba-tss-config-2.0", "http://openejb.apache.org/xml/ns/corba-tss-config-2.1"); 084 NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/corba-tss-config-2.1", "http://openejb.apache.org/xml/ns/corba-tss-config-2.1"); 085 } 086 087 private XmlBeansUtil() { 088 } 089 090 091 public static XmlObject parse(File file) throws IOException, XmlException { 092 ArrayList errors = new ArrayList(); 093 XmlObject parsed = XmlObject.Factory.parse(file, createXmlOptions(errors)); 094 if (errors.size() != 0) { 095 throw new XmlException(errors.toArray().toString()); 096 } 097 return parsed; 098 } 099 100 public static XmlObject parse(URL url, ClassLoader cl) throws IOException, XmlException { 101 ArrayList errors = new ArrayList(); 102 Thread currentThread = Thread.currentThread(); 103 ClassLoader oldcl = currentThread.getContextClassLoader(); 104 currentThread.setContextClassLoader(cl); 105 XmlObject parsed; 106 try { 107 parsed = XmlObject.Factory.parse(url, createXmlOptions(errors)); 108 } finally { 109 currentThread.setContextClassLoader(oldcl); 110 } 111 if (errors.size() != 0) { 112 throw new XmlException(errors.toArray().toString()); 113 } 114 return parsed; 115 } 116 117 public static XmlObject parse(InputStream is) throws IOException, XmlException { 118 ArrayList errors = new ArrayList(); 119 XmlObject parsed = XmlObject.Factory.parse(is, createXmlOptions(errors)); 120 if (errors.size() != 0) { 121 throw new XmlException(errors.toArray().toString()); 122 } 123 return parsed; 124 } 125 126 public static XmlObject parse(String xml) throws XmlException { 127 ArrayList errors = new ArrayList(); 128 XmlObject parsed = XmlObject.Factory.parse(xml, createXmlOptions(errors)); 129 if (errors.size() != 0) { 130 throw new XmlException(errors.toArray().toString()); 131 } 132 return parsed; 133 } 134 135 public static XmlObject parse(Element element) throws XmlException { 136 ArrayList errors = new ArrayList(); 137 XmlObject parsed = XmlObject.Factory.parse(element, createXmlOptions(errors)); 138 if (errors.size() != 0) { 139 throw new XmlException(errors.toArray().toString()); 140 } 141 return parsed; 142 } 143 144 public static XmlOptions createXmlOptions(Collection errors) { 145 XmlOptions options = new XmlOptions(); 146 options.setLoadLineNumbers(); 147 options.setErrorListener(errors); 148 options.setLoadSubstituteNamespaces(NAMESPACE_UPDATES); 149 return options; 150 } 151 152 public static void registerSubstitutionGroupElements(QName substitutionGroup, QNameSet substitutions) { 153 QNameSet oldSubstitutions = (QNameSet) substitutionGroups.get(substitutionGroup); 154 if (oldSubstitutions != null) { 155 substitutions = oldSubstitutions.union(substitutions); 156 } 157 substitutionGroups.put(substitutionGroup, substitutions); 158 } 159 160 public static void unregisterSubstitutionGroupElements(QName substitutionGroup, QNameSet substitutions) { 161 QNameSet oldSubstitutions = (QNameSet) substitutionGroups.get(substitutionGroup); 162 if (oldSubstitutions != null && substitutions != null) { 163 QNameSet difference = oldSubstitutions.intersect(substitutions.inverse()); 164 substitutionGroups.put(substitutionGroup, difference); 165 } 166 } 167 168 public static QNameSet getQNameSetForSubstitutionGroup(QName substitutionGroup) { 169 return (QNameSet) substitutionGroups.get(substitutionGroup); 170 } 171 172 public static XmlObject[] selectSubstitutionGroupElements(QName substitutionGroup, XmlObject container) { 173 QNameSet substitutionGroupMembers = getQNameSetForSubstitutionGroup(substitutionGroup); 174 if (substitutionGroupMembers == null) { 175 return NO_ELEMENTS; 176 } 177 return container.selectChildren(substitutionGroupMembers); 178 } 179 180 public static void validateDD(XmlObject dd) throws XmlException { 181 XmlOptions xmlOptions = new XmlOptions(); 182 xmlOptions.setLoadLineNumbers(); 183 Collection errors = new ArrayList(); 184 xmlOptions.setErrorListener(errors); 185 try { 186 if (!dd.validate(xmlOptions)) { 187 188 for (Iterator iterator = errors.iterator(); iterator.hasNext();) { 189 Object o = iterator.next(); 190 if (o instanceof XmlValidationError) { 191 XmlValidationError validationError = (XmlValidationError) o; 192 List expected = validationError.getExpectedQNames(); 193 QName actual = validationError.getOffendingQName(); 194 if (expected != null) { 195 for (Iterator iterator1 = expected.iterator(); iterator1.hasNext();) { 196 QName expectedQName = (QName) iterator1.next(); 197 QNameSet substitutions = getQNameSetForSubstitutionGroup(expectedQName); 198 if (substitutions != null && substitutions.contains(actual)) { 199 iterator.remove(); 200 break; 201 } 202 } 203 } 204 } 205 } 206 207 if (!errors.isEmpty()) { 208 throw new XmlException("Invalid deployment descriptor: " + errors + "\nDescriptor: " + dd.toString(), null, errors); 209 } 210 } 211 } catch (NullPointerException e) { 212 //ignore 213 } 214 // System.out.println("descriptor: " + dd.toString()); 215 } 216 }