View Javadoc
1   package org.codehaus.plexus.metadata.merge.support;
2   
3   /*
4    * ========================================================================
5    *
6    * Copyright 2003 The Apache Software Foundation. Code from this file
7    * was originally imported from the Jakarta Cactus project.
8    *
9    * Copyright 2004-2006 Vincent Massol.
10   *
11   * Licensed under the Apache License, Version 2.0 (the "License");
12   * you may not use this file except in compliance with the License.
13   * You may obtain a copy of the License at
14   *
15   *   http://www.apache.org/licenses/LICENSE-2.0
16   *
17   * Unless required by applicable law or agreed to in writing, software
18   * distributed under the License is distributed on an "AS IS" BASIS,
19   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20   * See the License for the specific language governing permissions and
21   * limitations under the License.
22   *
23   * ========================================================================
24   */
25  
26  import java.lang.reflect.Constructor;
27  
28  import org.jdom2.Element;
29  
30  /**
31   * Represents the various top-level tags in a deployment descriptor as a typesafe enumeration.
32   *
33   */
34  public class DescriptorTag {
35      /**
36       * The tag name.
37       */
38      private String tagName;
39  
40      /**
41       * Whether multiple occurrences of the tag in the descriptor are allowed.
42       */
43      private boolean multipleAllowed;
44  
45      /**
46       * Class that wraps this tag and provides for merging same tags.
47       */
48      private Class mergeableClass;
49  
50      /**
51       * Constructor.
52       *
53       * @param tagName           The tag name of the element
54       */
55      public DescriptorTag(String tagName) {
56          this(tagName, false, null);
57      }
58  
59      /**
60       * Constructor.
61       *
62       * @param tagName           The tag name of the element
63       * @param isMultipleAllowed Whether the element may occur multiple times in the descriptor
64       * @deprecated Use {@link #DescriptorTag(String,boolean,Class)} instead
65       */
66      public DescriptorTag(String tagName, boolean isMultipleAllowed) {
67          this(tagName, isMultipleAllowed, null);
68      }
69  
70      /**
71       * Constructor.
72       *
73       * @param tagName           The tag name of the element
74       * @param isMultipleAllowed Whether the element may occur multiple times in the descriptor
75       * @param mergeableClass    Concrete implementation of {@link Mergeable} that is bound this tag.
76       */
77      public DescriptorTag(String tagName, boolean isMultipleAllowed, Class mergeableClass) {
78          this.tagName = tagName;
79          this.multipleAllowed = isMultipleAllowed;
80          this.mergeableClass = mergeableClass;
81      }
82  
83      public boolean equals(Object other) {
84          boolean eq = false;
85          if (other instanceof DescriptorTag) {
86              DescriptorTag tag = (DescriptorTag) other;
87              if (tag.getTagName().equals(this.tagName)) {
88                  eq = true;
89              }
90          }
91          return eq;
92      }
93  
94      public int hashCode() {
95          return this.getTagName().hashCode();
96      }
97  
98      public String getTagName() {
99          return this.tagName;
100     }
101 
102     /**
103      * Returns whether the tag may occur multiple times in the descriptor.
104      *
105      * @return Whether multiple occurrences are allowed
106      */
107     public boolean isMultipleAllowed() {
108         return this.multipleAllowed;
109     }
110 
111     /**
112      * Determines if a particular Tag is mergeable or not.
113      * <p>
114      * Basically means if we have a {@link Mergeable} class registered for a tag instance.</p>
115      *
116      * @return <code>true</code> if this tag is mergeable.
117      */
118     public boolean isMergeable() {
119         return null != this.mergeableClass;
120     }
121 
122     public String toString() {
123         return getTagName();
124     }
125 
126     /**
127      * Creates an {@link Mergeable} instance from the registered class for this
128      * tag instance.
129      *
130      * @param element {@link Element}.
131      * @return instance of {@link Mergeable}.
132      * @throws Exception if there was an error creating an instance.
133      */
134     public Mergeable createMergeable(Element element) throws Exception {
135         Constructor cons = this.mergeableClass.getConstructor(new Class[] {Element.class});
136         // XXX Is there a better way to determine this?
137         if (this.mergeableClass.getSuperclass().equals(AbstractMergeableElementList.class)) {
138             return (AbstractMergeableElementList) cons.newInstance(new Object[] {element});
139         } else if (this.mergeableClass.getSuperclass().equals(AbstractMergeableElement.class)) {
140             return (AbstractMergeableElement) cons.newInstance(new Object[] {element});
141         } else {
142             // TODO set up Logger
143             // if (getLogger ().isErrorEnabled ())
144             //     getLogger.error ( "Could not create Mergeable instance for specified class '" + this.mergeableClass +
145             // "'" );
146             throw new Exception(
147                     "Could not create Mergeable instance for specified class " + "'" + this.mergeableClass + "'");
148         }
149     }
150 }