View Javadoc

1   /**
2    *
3    *  Licensed to the Apache Software Foundation (ASF) under one or more
4    *  contributor license agreements.  See the NOTICE file distributed with
5    *  this work for additional information regarding copyright ownership.
6    *  The ASF licenses this file to You under the Apache License, Version 2.0
7    *  (the "License"); you may not use this file except in compliance with
8    *  the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing, software
13   *  distributed under the License is distributed on an "AS IS" BASIS,
14   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   *  See the License for the specific language governing permissions and
16   *  limitations under the License.
17   */
18  package org.apache.geronimo.deployment.xmlbeans;
19  
20  import java.util.Map;
21  import java.util.HashMap;
22  import java.util.ArrayList;
23  import java.util.Collection;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.io.File;
27  import java.io.IOException;
28  import java.io.InputStream;
29  import java.net.URL;
30  
31  import javax.xml.namespace.QName;
32  
33  import org.w3c.dom.Element;
34  import org.apache.xmlbeans.XmlOptions;
35  import org.apache.xmlbeans.XmlException;
36  import org.apache.xmlbeans.XmlObject;
37  import org.apache.xmlbeans.SchemaTypeLoader;
38  import org.apache.xmlbeans.SchemaType;
39  import org.apache.xmlbeans.QNameSet;
40  import org.apache.xmlbeans.XmlValidationError;
41  
42  /**
43   * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
44   */
45  public class XmlBeansUtil {
46      private static final Map NAMESPACE_UPDATES = new HashMap();
47      //TODO thread safe? conncurrentReaderMap?
48      private static final Map substitutionGroups = new HashMap();
49      private static final XmlObject[] NO_ELEMENTS = new XmlObject[]{};
50  
51      static {
52          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/application-client", "http://geronimo.apache.org/xml/ns/j2ee/application-client-1.2");
53          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");
54          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/application", "http://geronimo.apache.org/xml/ns/j2ee/application-1.2");
55          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/application-1.1", "http://geronimo.apache.org/xml/ns/j2ee/application-1.2");
56          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/deployment", "http://geronimo.apache.org/xml/ns/deployment-1.2");
57          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/deployment-1.1", "http://geronimo.apache.org/xml/ns/deployment-1.2");
58          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/connector", "http://geronimo.apache.org/xml/ns/j2ee/connector-1.2");
59          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/connector-1.1", "http://geronimo.apache.org/xml/ns/j2ee/connector-1.2");
60          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/deployment/javabean", "http://geronimo.apache.org/xml/ns/deployment/javabean-1.0");
61          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/loginconfig", "http://geronimo.apache.org/xml/ns/loginconfig-1.2");
62          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/loginconfig-1.1", "http://geronimo.apache.org/xml/ns/loginconfig-1.2");
63          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/naming", "http://geronimo.apache.org/xml/ns/naming-1.2");
64          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/naming-1.1", "http://geronimo.apache.org/xml/ns/naming-1.2");
65          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/security", "http://geronimo.apache.org/xml/ns/security-1.2");
66          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/security-1.1", "http://geronimo.apache.org/xml/ns/security-1.2");
67          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/web", "http://geronimo.apache.org/xml/ns/j2ee/web-1.2");
68          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/web-1.1", "http://geronimo.apache.org/xml/ns/j2ee/web-1.2");
69          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/web/jetty", "http://geronimo.apache.org/xml/ns/j2ee/web/jetty-1.2");
70          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");
71          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/web/jetty/config", "http://geronimo.apache.org/xml/ns/j2ee/web/jetty/config-1.0");
72          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/web/tomcat", "http://geronimo.apache.org/xml/ns/j2ee/web/tomcat-1.2");
73          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");
74          NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/web/tomcat/config", "http://geronimo.apache.org/xml/ns/j2ee/web/tomcat/config-1.0");
75          NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/openejb-jar", "http://openejb.apache.org/xml/ns/openejb-jar-2.2");
76          NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/openejb-jar-2.1", "http://openejb.apache.org/xml/ns/openejb-jar-2.2");
77          NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/openejb-jar-2.2", "http://openejb.apache.org/xml/ns/openejb-jar-2.2");
78          NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/pkgen", "http://openejb.apache.org/xml/ns/pkgen-2.1");
79          NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/pkgen-2.0", "http://openejb.apache.org/xml/ns/pkgen-2.1");
80          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");
81          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");
82          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");
83          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");
84          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");
85      }
86  
87      private XmlBeansUtil() {
88      }
89  
90  
91      public static XmlObject parse(File file) throws IOException, XmlException {
92          ArrayList errors = new ArrayList();
93          XmlObject parsed = XmlObject.Factory.parse(file, createXmlOptions(errors));
94          if (errors.size() != 0) {
95              throw new XmlException(errors.toArray().toString());
96          }
97          return parsed;
98      }
99  
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 }