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 }