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   * @version $Id$
34   */
35  public class DescriptorTag
36  {
37      /**
38       * The tag name.
39       */
40      private String tagName;
41  
42      /**
43       * Whether multiple occurrences of the tag in the descriptor are allowed.
44       */
45      private boolean multipleAllowed;
46  
47      /**
48       * Class that wraps this tag and provides for merging same tags.
49       */
50      private Class mergeableClass;
51  
52      /**
53       * Constructor.
54       *
55       * @param tagName           The tag name of the element
56       */
57      public DescriptorTag( String tagName )
58      {
59          this( tagName, false, null );
60      }
61  
62      /**
63       * Constructor.
64       *
65       * @param tagName           The tag name of the element
66       * @param isMultipleAllowed Whether the element may occur multiple times in the descriptor
67       * @deprecated Use {@link #DescriptorTag(String,boolean,Class)} instead
68       */
69      public DescriptorTag( String tagName, boolean isMultipleAllowed )
70      {
71          this( tagName, isMultipleAllowed, null );
72      }
73  
74      /**
75       * Constructor.
76       *
77       * @param tagName           The tag name of the element
78       * @param isMultipleAllowed Whether the element may occur multiple times in the descriptor
79       * @param mergeableClass    Concrete implementation of {@link Mergeable} that is bound this tag.
80       */
81      public DescriptorTag( String tagName, boolean isMultipleAllowed, Class mergeableClass )
82      {
83          this.tagName = tagName;
84          this.multipleAllowed = isMultipleAllowed;
85          this.mergeableClass = mergeableClass;
86      }
87  
88      public boolean equals( Object other )
89      {
90          boolean eq = false;
91          if ( other instanceof DescriptorTag )
92          {
93              DescriptorTag tag = (DescriptorTag) other;
94              if ( tag.getTagName().equals( this.tagName ) )
95              {
96                  eq = true;
97              }
98          }
99          return eq;
100     }
101 
102     public int hashCode()
103     {
104         return this.getTagName().hashCode();
105     }
106 
107     public String getTagName()
108     {
109         return this.tagName;
110     }
111 
112     /**
113      * Returns whether the tag may occur multiple times in the descriptor.
114      *
115      * @return Whether multiple occurrences are allowed
116      */
117     public boolean isMultipleAllowed()
118     {
119         return this.multipleAllowed;
120     }
121 
122     /**
123      * Determines if a particular Tag is mergeable or not.
124      * <p/>
125      * Basically means if we have a {@link Mergeable} class registered for a tag instance.
126      *
127      * @return <code>true</code> if this tag is mergeable.
128      */
129     public boolean isMergeable()
130     {
131         return null != this.mergeableClass;
132     }
133 
134     public String toString()
135     {
136         return getTagName();
137     }
138 
139     /**
140      * Creates an {@link Mergeable} instance from the registered class for this
141      * tag instance.
142      *
143      * @return instance of {@link Mergeable}.
144      * @throws Exception if there was an error creating an instance.
145      */
146     public Mergeable createMergeable( Element element )
147         throws Exception
148     {
149         Constructor cons = this.mergeableClass.getConstructor( new Class[] { Element.class } );
150         // XXX Is there a better way to determine this?
151         if ( this.mergeableClass.getSuperclass().equals( AbstractMergeableElementList.class ) )
152         {
153             return (AbstractMergeableElementList) cons.newInstance( new Object[] { element } );
154         }
155         else if ( this.mergeableClass.getSuperclass().equals( AbstractMergeableElement.class ) )
156         {
157             return (AbstractMergeableElement) cons.newInstance( new Object[] { element } );
158         }
159         else
160         {
161             // TODO set up Logger
162             // if (getLogger ().isErrorEnabled ())
163             //     getLogger.error ( "Could not create Mergeable instance for specified class '" + this.mergeableClass + "'" );
164             throw new Exception( "Could not create Mergeable instance for specified class " + "'" + this.mergeableClass
165                 + "'" );
166         }
167     }
168 }