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
19 package org.apache.geronimo.schema;
20
21 import java.util.HashMap;
22 import java.util.Map;
23
24 import javax.xml.namespace.QName;
25
26 import org.apache.geronimo.xbeans.j2ee.ApplicationClientDocument;
27 import org.apache.geronimo.xbeans.j2ee.ApplicationDocument;
28 import org.apache.geronimo.xbeans.j2ee.ConnectorDocument;
29 import org.apache.geronimo.xbeans.j2ee.EjbJarDocument;
30 import org.apache.geronimo.xbeans.j2ee.WebAppDocument;
31 import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
32 import org.apache.xmlbeans.SchemaType;
33 import org.apache.xmlbeans.XmlCursor;
34 import org.apache.xmlbeans.XmlDocumentProperties;
35 import org.apache.xmlbeans.XmlException;
36 import org.apache.xmlbeans.XmlObject;
37
38 /**
39 * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
40 */
41 public class SchemaConversionUtils {
42 public static final String J2EE_NAMESPACE = "http://java.sun.com/xml/ns/j2ee";
43 public static final String JAVAEE_NAMESPACE = "http://java.sun.com/xml/ns/javaee";
44
45 static final String GERONIMO_NAMING_NAMESPACE = "http://geronimo.apache.org/xml/ns/naming-1.2";
46 private static final String GERONIMO_SECURITY_NAMESPACE = "http://geronimo.apache.org/xml/ns/security-1.2";
47 private static final String GERONIMO_SERVICE_NAMESPACE = "http://geronimo.apache.org/xml/ns/deployment-1.2";
48
49 private static final Map GERONIMO_SCHEMA_CONVERSIONS = new HashMap();
50
51 static {
52
53 GERONIMO_SCHEMA_CONVERSIONS.put("gbean-ref", new NamespaceElementConverter(GERONIMO_NAMING_NAMESPACE));
54 GERONIMO_SCHEMA_CONVERSIONS.put("ejb-ref", new NamespaceElementConverter(GERONIMO_NAMING_NAMESPACE));
55 GERONIMO_SCHEMA_CONVERSIONS.put("ejb-local-ref", new NamespaceElementConverter(GERONIMO_NAMING_NAMESPACE));
56 GERONIMO_SCHEMA_CONVERSIONS.put("service-ref", new NamespaceElementConverter(GERONIMO_NAMING_NAMESPACE));
57 GERONIMO_SCHEMA_CONVERSIONS.put("resource-ref", new NamespaceElementConverter(GERONIMO_NAMING_NAMESPACE));
58 GERONIMO_SCHEMA_CONVERSIONS.put("resource-env-ref", new NamespaceElementConverter(GERONIMO_NAMING_NAMESPACE));
59 GERONIMO_SCHEMA_CONVERSIONS.put("message-destination", new NamespaceElementConverter(GERONIMO_NAMING_NAMESPACE));
60 GERONIMO_SCHEMA_CONVERSIONS.put("cmp-connection-factory", new NamespaceElementConverter(GERONIMO_NAMING_NAMESPACE));
61 GERONIMO_SCHEMA_CONVERSIONS.put("workmanager", new NamespaceElementConverter(GERONIMO_NAMING_NAMESPACE));
62 GERONIMO_SCHEMA_CONVERSIONS.put("resource-adapter", new NamespaceElementConverter(GERONIMO_NAMING_NAMESPACE));
63 GERONIMO_SCHEMA_CONVERSIONS.put("web-container", new NamespaceElementConverter(GERONIMO_NAMING_NAMESPACE));
64
65 GERONIMO_SCHEMA_CONVERSIONS.put("security", new SecurityElementConverter());
66 GERONIMO_SCHEMA_CONVERSIONS.put("default-principal", new NamespaceElementConverter(GERONIMO_SECURITY_NAMESPACE));
67
68 GERONIMO_SCHEMA_CONVERSIONS.put("gbean", new GBeanElementConverter());
69 GERONIMO_SCHEMA_CONVERSIONS.put("environment", new NamespaceElementConverter(GERONIMO_SERVICE_NAMESPACE));
70 GERONIMO_SCHEMA_CONVERSIONS.put("client-environment", new NamespaceElementConverter(GERONIMO_SERVICE_NAMESPACE));
71 GERONIMO_SCHEMA_CONVERSIONS.put("server-environment", new NamespaceElementConverter(GERONIMO_SERVICE_NAMESPACE));
72 }
73
74 private SchemaConversionUtils() {
75 }
76
77 public static void registerNamespaceConversions(Map conversions) {
78 GERONIMO_SCHEMA_CONVERSIONS.putAll(conversions);
79 }
80
81 public static void convertToGeronimoSubSchemas(XmlCursor cursor) {
82 cursor.toStartDoc();
83 XmlCursor end = cursor.newCursor();
84 try {
85 while (cursor.hasNextToken()) {
86 convertSingleElementToGeronimoSubSchemas(cursor, end);
87 cursor.toNextToken();
88 }
89 } finally {
90 end.dispose();
91 }
92 }
93
94 public static boolean convertSingleElementToGeronimoSubSchemas(XmlCursor cursor, XmlCursor end) {
95 if (cursor.isStart()) {
96 String localName = cursor.getName().getLocalPart();
97 ElementConverter converter = (ElementConverter) GERONIMO_SCHEMA_CONVERSIONS.get(localName);
98 if (converter != null) {
99 converter.convertElement(cursor, end);
100 return true;
101 }
102 return false;
103 }
104
105 return false;
106 }
107
108 public static XmlObject fixGeronimoSchema(XmlObject rawPlan, QName desiredElement, SchemaType desiredType) throws XmlException {
109 XmlCursor cursor = rawPlan.newCursor();
110 try {
111 if (findNestedElement(cursor, desiredElement)) {
112 cursor.push();
113 convertToGeronimoSubSchemas(cursor);
114 cursor.pop();
115 XmlObject temp = cursor.getObject();
116
117 XmlObject result = temp.changeType(desiredType);
118 if (result == null || result.schemaType() != desiredType) {
119 result = temp.copy().changeType(desiredType);
120 }
121 XmlBeansUtil.validateDD(result);
122 return result;
123 } else {
124 return null;
125 }
126 } finally {
127 cursor.dispose();
128 }
129 }
130
131 public static XmlObject getNestedObject(XmlObject xmlObject, QName desiredElement) {
132 XmlCursor cursor = xmlObject.newCursor();
133 try {
134 if (findNestedElement(cursor, desiredElement)) {
135 XmlObject child = cursor.getObject();
136
137 return child.copy();
138 }
139 } finally {
140 cursor.dispose();
141 }
142 throw new IllegalArgumentException("xmlobject did not have desired element: " + desiredElement + "/n" + xmlObject);
143 }
144
145 public static boolean findNestedElement(XmlCursor cursor, QName desiredElement) {
146 while (cursor.hasNextToken()) {
147 if (cursor.isStart()) {
148 QName element = cursor.getName();
149 if (element.equals(desiredElement)) {
150 return true;
151 }
152 }
153 cursor.toNextToken();
154 }
155 return false;
156 }
157
158 public static boolean findNestedElement(XmlCursor cursor, String desiredElement) {
159 while (cursor.hasNextToken()) {
160 if (cursor.isStart()) {
161 String element = cursor.getName().getLocalPart();
162 if (element.equals(desiredElement)) {
163 return true;
164 }
165 }
166 cursor.toNextToken();
167 }
168 return false;
169 }
170
171 public static XmlObject getNestedObjectAsType(XmlObject xmlObject, QName desiredElement, SchemaType type) {
172 XmlCursor cursor = xmlObject.newCursor();
173 try {
174 if (findNestedElement(cursor, desiredElement)) {
175 XmlObject child = cursor.getObject();
176
177 XmlObject result = child.copy().changeType(type);
178 assert result.schemaType() == type;
179 return result;
180 }
181 } finally {
182 cursor.dispose();
183 }
184 throw new IllegalArgumentException("xmlobject did not have desired element: " + desiredElement + "\n" + xmlObject);
185 }
186
187
188 public static boolean convertToSchema(XmlCursor cursor, String namespace, String schemaLocationURL, String version) {
189
190 XmlDocumentProperties xmlDocumentProperties = cursor.documentProperties();
191 xmlDocumentProperties.remove(XmlDocumentProperties.DOCTYPE_NAME);
192 xmlDocumentProperties.remove(XmlDocumentProperties.DOCTYPE_PUBLIC_ID);
193 xmlDocumentProperties.remove(XmlDocumentProperties.DOCTYPE_SYSTEM_ID);
194
195 boolean isFirstStart = true;
196 while (cursor.hasNextToken()) {
197 if (cursor.isStart()) {
198 if (namespace.equals(cursor.getName().getNamespaceURI())) {
199
200 return false;
201 }
202 cursor.setName(new QName(namespace, cursor.getName().getLocalPart()));
203 cursor.toNextToken();
204 if (isFirstStart) {
205 cursor.insertNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
206 cursor.insertAttributeWithValue(new QName("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation", "xsi"), namespace + schemaLocationURL);
207 cursor.insertAttributeWithValue(new QName("version"), version);
208 isFirstStart = false;
209 }
210 } else {
211 cursor.toNextToken();
212 }
213 }
214 return true;
215 }
216
217 public static boolean convertSchemaVersion (XmlCursor cursor, String namespace, String schemaLocationURL, String version) {
218 boolean isFirstStart = true;
219
220
221 while (cursor.hasNextToken()) {
222 if (cursor.isStart()) {
223
224 cursor.setName(new QName(namespace, cursor.getName().getLocalPart()));
225 if (isFirstStart) {
226
227 cursor.setAttributeText(new QName("version"), version);
228
229 cursor.setAttributeText(new QName("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation", "xsi"), namespace + " "+schemaLocationURL);
230 isFirstStart = false;
231 }
232 cursor.toNextToken();
233
234 } else {
235 cursor.toNextToken();
236 }
237 }
238
239
240 return true;
241 }
242
243 /**
244 * Reorders elements to match descriptionGroup
245 *
246 * @param namespace
247 * @param cursor XmlCursor positioned at first element of "group" to be reordered
248 */
249 public static void convertToDescriptionGroup(String namespace, XmlCursor cursor, XmlCursor moveable) {
250 moveable.toCursor(cursor);
251 moveElements("description", namespace, moveable, cursor);
252 moveElements("display-name", namespace, moveable, cursor);
253 moveElements("icon", namespace, moveable, cursor);
254 }
255
256 public static void convertToJNDIEnvironmentRefsGroup(String namespace, XmlCursor cursor, XmlCursor moveable) {
257 moveElements("env-entry", namespace, moveable, cursor);
258 moveElements("ejb-ref", namespace, moveable, cursor);
259 moveElements("ejb-local-ref", namespace, moveable, cursor);
260 moveElements("resource-ref", namespace, moveable, cursor);
261 moveElements("resource-env-ref", namespace, moveable, cursor);
262 moveElements("message-destination-ref", namespace, moveable, cursor);
263 if (cursor.toPrevSibling()) {
264 do {
265 String name = cursor.getName().getLocalPart();
266 if ("env-entry".equals(name)) {
267 cursor.push();
268 cursor.toFirstChild();
269 convertToDescriptionGroup(namespace, cursor, moveable);
270 convertToEnvEntryGroup(namespace, cursor, moveable);
271 cursor.pop();
272 }
273 } while (cursor.toPrevSibling());
274 }
275 }
276
277 public static void convertToEnvEntryGroup(String namespace, XmlCursor cursor, XmlCursor moveable) {
278 moveElements("env-entry-name", namespace, moveable, cursor);
279 moveElements("env-entry-type", namespace, moveable, cursor);
280 moveElements("env-entry-value", namespace, moveable, cursor);
281 }
282
283 private static void moveElements(String localName, String namespace, XmlCursor moveable, XmlCursor toHere) {
284 QName name = new QName(namespace, localName);
285
286 while (name.equals(toHere.getName()) && toHere.toNextSibling()) {
287 }
288 moveable.toCursor(toHere);
289 while (moveable.toNextSibling(name)) {
290 moveable.moveXml(toHere);
291 }
292 }
293
294 }