001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.metadata;
023:
024: import java.util.ArrayList;
025: import java.util.Iterator;
026:
027: import org.w3c.dom.Element;
028: import org.w3c.dom.NodeList;
029: import org.w3c.dom.Node;
030:
031: import org.jboss.deployment.DeploymentException;
032: import org.jboss.logging.Logger;
033: import org.jboss.util.StringPropertyReplacer;
034:
035: /**
036: * An abstract base class for metadata containers.
037: *
038: * @author <a href="mailto:sebastien.alborini@m4x.org">Sebastien Alborini</a>
039: * @version $Revision: 57209 $
040: */
041: public abstract class MetaData implements Cloneable, XmlLoadable {
042: // Constants -----------------------------------------------------
043:
044: protected static Logger log = Logger.getLogger(MetaData.class);
045:
046: // These do not really belong here
047:
048: public static final byte TX_NOT_SUPPORTED = 0;
049: public static final byte TX_REQUIRED = 1;
050: public static final byte TX_SUPPORTS = 2;
051: public static final byte TX_REQUIRES_NEW = 3;
052: public static final byte TX_MANDATORY = 4;
053: public static final byte TX_NEVER = 5;
054: public static final byte TX_UNKNOWN = 6;
055:
056: // Attributes ----------------------------------------------------
057:
058: // Static --------------------------------------------------------
059:
060: /**
061: * Returns an iterator over the children of the given element with
062: * the given tag name.
063: *
064: * @param element The parent element
065: * @param tagName The name of the desired child
066: * @return An interator of children or null if element is null.
067: */
068: public static Iterator getChildrenByTagName(Element element,
069: String tagName) {
070: if (element == null)
071: return null;
072: // getElementsByTagName gives the corresponding elements in the whole
073: // descendance. We want only children
074:
075: NodeList children = element.getChildNodes();
076: ArrayList goodChildren = new ArrayList();
077: for (int i = 0; i < children.getLength(); i++) {
078: Node currentChild = children.item(i);
079: if (currentChild.getNodeType() == Node.ELEMENT_NODE
080: && ((Element) currentChild).getTagName().equals(
081: tagName)) {
082: goodChildren.add(currentChild);
083: }
084: }
085: return goodChildren.iterator();
086: }
087:
088: /**
089: * Gets the child of the specified element having the specified unique
090: * name. If there are more than one children elements with the same name
091: * and exception is thrown.
092: *
093: * @param element The parent element
094: * @param tagName The name of the desired child
095: * @return The named child.
096: *
097: * @throws DeploymentException Child was not found or was not unique.
098: */
099: public static Element getUniqueChild(Element element, String tagName)
100: throws DeploymentException {
101: Iterator goodChildren = getChildrenByTagName(element, tagName);
102:
103: if (goodChildren != null && goodChildren.hasNext()) {
104: Element child = (Element) goodChildren.next();
105: if (goodChildren.hasNext()) {
106: throw new DeploymentException("expected only one "
107: + tagName + " tag");
108: }
109: return child;
110: } else {
111: throw new DeploymentException("expected one " + tagName
112: + " tag");
113: }
114: }
115:
116: /**
117: * Gets the child of the specified element having the
118: * specified name. If the child with this name doesn't exist
119: * then null is returned instead.
120: *
121: * @param element the parent element
122: * @param tagName the name of the desired child
123: * @return either the named child or null
124: */
125: public static Element getOptionalChild(Element element,
126: String tagName) throws DeploymentException {
127: return getOptionalChild(element, tagName, null);
128: }
129:
130: /**
131: * Gets the child of the specified element having the
132: * specified name. If the child with this name doesn't exist
133: * then the supplied default element is returned instead.
134: *
135: * @param element the parent element
136: * @param tagName the name of the desired child
137: * @param defaultElement the element to return if the child
138: * doesn't exist
139: * @return either the named child or the supplied default
140: */
141: public static Element getOptionalChild(Element element,
142: String tagName, Element defaultElement)
143: throws DeploymentException {
144: Iterator goodChildren = getChildrenByTagName(element, tagName);
145:
146: if (goodChildren != null && goodChildren.hasNext()) {
147: Element child = (Element) goodChildren.next();
148: if (goodChildren.hasNext()) {
149: throw new DeploymentException("expected only one "
150: + tagName + " tag");
151: }
152: return child;
153: } else {
154: return defaultElement;
155: }
156: }
157:
158: /**
159: * Get an attribute value of the given element.
160: *
161: * @param element The element to get the attribute value for.
162: * @param attrName The attribute name
163: * @return The attribute value or null.
164: */
165: public static String getElementAttribute(final Element element,
166: final String attrName) {
167: return getElementAttribute(element, attrName, true);
168: }
169:
170: /**
171: * Get an attribute value of the given element.
172: *
173: * @param element The element to get the attribute value for.
174: * @param attrName The attribute name
175: * @param replace Whether to replace system properties
176: * @return The attribute value or null.
177: */
178: public static String getElementAttribute(final Element element,
179: final String attrName, boolean replace) {
180: if (element == null)
181: return null;
182:
183: if (attrName == null || element.hasAttribute(attrName) == false)
184: return null;
185:
186: String result = element.getAttribute(attrName);
187: if (replace)
188: return StringPropertyReplacer.replaceProperties(result
189: .trim());
190: else
191: return result.trim();
192: }
193:
194: /**
195: * Get the content of the given element.
196: *
197: * @param element The element to get the content for.
198: * @return The content of the element or null.
199: */
200: public static String getElementContent(final Element element) {
201: return getElementContent(element, null);
202: }
203:
204: /**
205: * Get the content of the given element.
206: *
207: * @param element The element to get the content for.
208: * @param defaultStr The default to return when there is no content.
209: * @return The content of the element or the default.
210: */
211: public static String getElementContent(Element element,
212: String defaultStr) {
213: return getElementContent(element, defaultStr, true);
214: }
215:
216: /**
217: * Get the content of the given element.
218: *
219: * @param element The element to get the content for.
220: * @param defaultStr The default to return when there is no content.
221: * @param replace Whether to replace system properties
222: * @return The content of the element or the default.
223: */
224: public static String getElementContent(Element element,
225: String defaultStr, boolean replace) {
226: if (element == null)
227: return defaultStr;
228:
229: NodeList children = element.getChildNodes();
230: String result = "";
231: for (int i = 0; i < children.getLength(); i++) {
232: if (children.item(i).getNodeType() == Node.TEXT_NODE
233: || children.item(i).getNodeType() == Node.CDATA_SECTION_NODE) {
234: result += children.item(i).getNodeValue();
235: } else if (children.item(i).getNodeType() == Node.COMMENT_NODE) {
236: // Ignore comment nodes
237: } else {
238: result += children.item(i).getFirstChild();
239: }
240: }
241: if (replace)
242: return StringPropertyReplacer.replaceProperties(result
243: .trim());
244: else
245: return result.trim();
246: }
247:
248: public static String getFirstElementContent(Element element,
249: String defaultStr) {
250: return getFirstElementContent(element, defaultStr, true);
251: }
252:
253: public static String getFirstElementContent(Element element,
254: String defaultStr, boolean replace) {
255: if (element == null)
256: return defaultStr;
257:
258: NodeList children = element.getChildNodes();
259: String result = "";
260: for (int i = 0; i < children.getLength(); i++) {
261: if (children.item(i).getNodeType() == Node.TEXT_NODE
262: || children.item(i).getNodeType() == Node.CDATA_SECTION_NODE) {
263: String val = children.item(i).getNodeValue();
264: result += val;
265: } else if (children.item(i).getNodeType() == Node.COMMENT_NODE) {
266: // Ignore comment nodes
267: }
268: /* For some reason, the original version gets the text of the first child
269: else
270: {
271: result += children.item(i).getFirstChild();
272: }
273: */
274: }
275: if (replace)
276: return StringPropertyReplacer.replaceProperties(result
277: .trim());
278: else
279: return result.trim();
280: }
281:
282: /**
283: * Macro to get the content of a unique child element.
284: *
285: * @param element The parent element.
286: * @param tagName The name of the desired child.
287: * @return The element content or null.
288: */
289: public static String getUniqueChildContent(Element element,
290: String tagName) throws DeploymentException {
291: return getElementContent(getUniqueChild(element, tagName));
292: }
293:
294: /**
295: * Macro to get the content of an optional child element.
296: *
297: * @param element The parent element.
298: * @param tagName The name of the desired child.
299: * @return The element content or null.
300: */
301: public static String getOptionalChildContent(Element element,
302: String tagName) throws DeploymentException {
303: return getElementContent(getOptionalChild(element, tagName));
304: }
305:
306: /**
307: * Macro to get the content of an optional child element with default value.
308: *
309: * @param element The parent element.
310: * @param tagName The name of the desired child.
311: * @return The element content or null.
312: */
313: public static String getOptionalChildContent(Element element,
314: String tagName, String defaultValue)
315: throws DeploymentException {
316: return getElementContent(getOptionalChild(element, tagName),
317: defaultValue);
318: }
319:
320: public static boolean getOptionalChildBooleanContent(
321: Element element, String name) throws DeploymentException {
322: Element child = getOptionalChild(element, name);
323: if (child != null) {
324: String value = getElementContent(child).toLowerCase();
325: return value.equalsIgnoreCase("true")
326: || value.equalsIgnoreCase("yes");
327: }
328:
329: return false;
330: }
331:
332: public static boolean getOptionalChildBooleanContent(
333: Element element, String name, boolean defaultValue)
334: throws DeploymentException {
335: Element child = getOptionalChild(element, name);
336: boolean flag = defaultValue;
337: if (child != null) {
338: String value = getElementContent(child).toLowerCase();
339: flag = value.equalsIgnoreCase("true")
340: || value.equalsIgnoreCase("yes");
341: }
342:
343: return flag;
344: }
345:
346: // Constructors --------------------------------------------------
347:
348: // Public --------------------------------------------------------
349:
350: /** Create a field wise copy of the object.
351: */
352: public Object clone() {
353: Object clone = null;
354: try {
355: clone = super .clone();
356: } catch (CloneNotSupportedException ignore) {
357: }
358: return clone;
359: }
360:
361: /**
362: * Imports either the jboss or ejb-jar from the given element.
363: *
364: * @param element The element to import.
365: *
366: * @throws DeploymentException Unrecognized root tag.
367: */
368: public void importXml(Element element) throws DeploymentException {
369: String rootTag = element.getOwnerDocument()
370: .getDocumentElement().getTagName();
371:
372: if (rootTag.equals("jboss")) {
373: // import jboss.xml
374: importJbossXml(element);
375: } else if (rootTag.equals("ejb-jar")) {
376: // import ejb-jar.xml
377: importEjbJarXml(element);
378: } else {
379: throw new DeploymentException("Unrecognized root tag : "
380: + rootTag);
381: }
382: }
383:
384: /**
385: * Non-operation.
386: *
387: * @param element
388: *
389: * @throws DeploymentException
390: */
391: public void importEjbJarXml(Element element)
392: throws DeploymentException {
393: // empty
394: }
395:
396: /**
397: * Non-operation.
398: *
399: * @param element
400: *
401: * @throws DeploymentException
402: */
403: public void importJbossXml(Element element)
404: throws DeploymentException {
405: // empty
406: }
407:
408: // Package protected ---------------------------------------------
409:
410: // Protected -----------------------------------------------------
411:
412: /**
413: * Check if we are running in a JDK v1.3 virtual machine or better.
414: *
415: * @return True if the virtual machine is v1.3 or better.
416: */
417: protected boolean jdk13Enabled() {
418: // should use "java.version" ?
419: String javaVersion = System.getProperty("java.vm.version");
420: return javaVersion.compareTo("1.3") >= 0;
421: }
422:
423: // Private -------------------------------------------------------
424:
425: // Inner classes -------------------------------------------------
426: }
427: /*
428: vim:ts=3:sw=3:et
429: */
|