001: /*
002: * ========================================================================
003: *
004: * Copyright 2003-2005 The Apache Software Foundation.
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * 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: * ========================================================================
019: */
020: package org.apache.cactus.integration.ant.deployment.application;
021:
022: import java.util.ArrayList;
023: import java.util.Iterator;
024: import java.util.List;
025:
026: import org.w3c.dom.Document;
027: import org.w3c.dom.DocumentType;
028: import org.w3c.dom.Element;
029: import org.w3c.dom.Node;
030: import org.w3c.dom.NodeList;
031:
032: /**
033: * Encapsulates the DOM representation of an EAR descriptor
034: * (<code>application.xml</code>) to provide convenience methods for easy
035: * access and manipulation.
036: *
037: * @since Cactus 1.5
038: * @version $Id: DefaultApplicationXml.java 239141 2005-02-15 10:31:44Z vmassol $
039: */
040: public class DefaultApplicationXml implements ApplicationXml {
041: // Instance Variables ------------------------------------------------------
042:
043: /**
044: * The DOM representation of the deployment descriptor.
045: */
046: private final Document document;
047:
048: /**
049: * The root element of the descriptor.
050: */
051: private final Element rootElement;
052:
053: /**
054: * Specifies the order in which the top-level elements must appear in the
055: * descriptor, according to the DTD.
056: */
057: private static final ApplicationXmlTag[] ELEMENT_ORDER = {
058: ApplicationXmlTag.ICON, ApplicationXmlTag.DISPLAY_NAME,
059: ApplicationXmlTag.DESCRIPTION, ApplicationXmlTag.MODULE,
060: ApplicationXmlTag.SECURITY_ROLE };
061:
062: // Constructors ------------------------------------------------------------
063:
064: /**
065: * Constructor.
066: *
067: * @param theDocument The DOM document representing the parsed deployment
068: * descriptor
069: */
070: public DefaultApplicationXml(Document theDocument) {
071: this .document = theDocument;
072: this .rootElement = theDocument.getDocumentElement();
073: }
074:
075: // Public Methods ----------------------------------------------------------
076:
077: /**
078: * @see ApplicationXml#getDocument()
079: */
080: public final Document getDocument() {
081: return this .document;
082: }
083:
084: /**
085: * @see ApplicationXml#getVersion()
086: */
087: public final ApplicationXmlVersion getVersion() {
088: DocumentType docType = this .document.getDoctype();
089: if (docType != null) {
090: return ApplicationXmlVersion.valueOf(docType);
091: }
092: return null;
093: }
094:
095: /**
096: * @see ApplicationXml#getWebModule(String)
097: */
098: public final Element getWebModule(String theWebUri) {
099: if (theWebUri == null) {
100: throw new NullPointerException();
101: }
102: Iterator moduleElements = getElements(ApplicationXmlTag.MODULE);
103: while (moduleElements.hasNext()) {
104: Element moduleElement = (Element) moduleElements.next();
105: Iterator webElements = getNestedElements(moduleElement,
106: ApplicationXmlTag.WEB);
107: if (webElements.hasNext()) {
108: Element webElement = (Element) webElements.next();
109: if (theWebUri.equals(getNestedText(webElement,
110: ApplicationXmlTag.WEB_URI))) {
111: return webElement;
112: }
113: }
114: }
115: return null;
116: }
117:
118: /**
119: * @see ApplicationXml#getWebModuleContextRoot(String)
120: */
121: public final String getWebModuleContextRoot(String theWebUri) {
122: Element webModuleElement = getWebModule(theWebUri);
123: if (webModuleElement == null) {
124: throw new IllegalArgumentException("Web module ["
125: + theWebUri + "] is not defined");
126: }
127: return getNestedText(webModuleElement,
128: ApplicationXmlTag.CONTEXT_ROOT);
129: }
130:
131: /**
132: * @see ApplicationXml#getWebModuleUris()
133: */
134: public final Iterator getWebModuleUris() {
135: List webUris = new ArrayList();
136: Iterator moduleElements = getElements(ApplicationXmlTag.MODULE);
137: while (moduleElements.hasNext()) {
138: Element moduleElement = (Element) moduleElements.next();
139: Iterator webElements = getNestedElements(moduleElement,
140: ApplicationXmlTag.WEB);
141: if (webElements.hasNext()) {
142: Element webElement = (Element) webElements.next();
143: String webUri = getNestedText(webElement,
144: ApplicationXmlTag.WEB_URI);
145: if (webUri != null) {
146: webUris.add(webUri);
147: }
148: }
149: }
150: return webUris.iterator();
151: }
152:
153: /**
154: * @see ApplicationXml#getElements(ApplicationXmlTag)
155: */
156: public final Iterator getElements(ApplicationXmlTag theTag) {
157: List elements = new ArrayList();
158: NodeList nodeList = this .rootElement
159: .getElementsByTagName(theTag.getTagName());
160: for (int i = 0; i < nodeList.getLength(); i++) {
161: elements.add(nodeList.item(i));
162: }
163: return elements.iterator();
164: }
165:
166: /**
167: * @see ApplicationXml#addWebModule(String, String)
168: */
169: public void addWebModule(String theUri, String theContext) {
170: Element moduleElement = this .document
171: .createElement(ApplicationXmlTag.MODULE.getTagName());
172: Element webElement = this .document
173: .createElement(ApplicationXmlTag.WEB.getTagName());
174: webElement.appendChild(createNestedText(
175: ApplicationXmlTag.WEB_URI, theUri));
176: webElement.appendChild(createNestedText(
177: ApplicationXmlTag.CONTEXT_ROOT, theContext));
178: moduleElement.appendChild(webElement);
179: addElement(ApplicationXmlTag.MODULE, moduleElement);
180: }
181:
182: // Private Methods ---------------------------------------------------------
183:
184: /**
185: * Returns an iterator over the child elements of the specified element that
186: * match the specified tag.
187: *
188: * @param theParent The element of which the nested elements should be
189: * retrieved
190: * @param theTag The descriptor tag of which the elements should be
191: * returned
192: * @return An iterator over the elements matching the tag, in the order
193: * they occur in the descriptor
194: */
195: private Iterator getNestedElements(Element theParent,
196: ApplicationXmlTag theTag) {
197: List elements = new ArrayList();
198: NodeList nodeList = theParent.getElementsByTagName(theTag
199: .getTagName());
200: for (int i = 0; i < nodeList.getLength(); i++) {
201: elements.add(nodeList.item(i));
202: }
203: return elements.iterator();
204: }
205:
206: /**
207: * Returns the text nested inside a child element of the specified element.
208: *
209: * @param theElement The element of which the nested text should be
210: * returned
211: * @param theTag The descriptor tag in which the text is nested
212: * @return The text nested in the element
213: */
214: private String getNestedText(Element theElement,
215: ApplicationXmlTag theTag) {
216: NodeList nestedElements = theElement
217: .getElementsByTagName(theTag.getTagName());
218: if (nestedElements.getLength() > 0) {
219: Node nestedText = nestedElements.item(0).getFirstChild();
220: if (nestedText != null) {
221: return nestedText.getNodeValue();
222: }
223: }
224: return null;
225: }
226:
227: /**
228: * Creates an element that contains nested text.
229: *
230: * @param theTag The tag to create an instance of
231: * @param theText The text that should be nested in the element
232: * @return The created DOM element
233: */
234: private Element createNestedText(ApplicationXmlTag theTag,
235: String theText) {
236: Element element = this .document.createElement(theTag
237: .getTagName());
238: element.appendChild(this .document.createTextNode(theText));
239: return element;
240: }
241:
242: /**
243: * Adds an element of the specified tag to the descriptor.
244: *
245: * @param theTag The descriptor tag
246: * @param theElement The element to add
247: */
248: public final void addElement(ApplicationXmlTag theTag,
249: Element theElement) {
250: Node importedNode = this .document.importNode(theElement, true);
251: Node refNode = getInsertionPointFor(theTag);
252: this .rootElement.insertBefore(importedNode, refNode);
253: }
254:
255: /**
256: * Returns the node before which the specified tag should be inserted, or
257: * <code>null</code> if the node should be inserted at the end of the
258: * descriptor.
259: *
260: * @param theTag The tag that should be inserted
261: * @return The node before which the tag can be inserted
262: */
263: private Node getInsertionPointFor(ApplicationXmlTag theTag) {
264: for (int i = 0; i < ELEMENT_ORDER.length; i++) {
265: if (ELEMENT_ORDER[i] == theTag) {
266: for (int j = i + 1; j < ELEMENT_ORDER.length; j++) {
267: NodeList elements = this .rootElement
268: .getElementsByTagName(ELEMENT_ORDER[j]
269: .getTagName());
270: if (elements.getLength() > 0) {
271: Node result = elements.item(0);
272: Node previous = result.getPreviousSibling();
273: while ((previous != null)
274: && ((previous.getNodeType() == Node.COMMENT_NODE) || (previous
275: .getNodeType() == Node.TEXT_NODE))) {
276: result = previous;
277: previous = result.getPreviousSibling();
278: }
279: return result;
280: }
281: }
282: break;
283: }
284: }
285: return null;
286: }
287: }
|