001: // THIS SOFTWARE IS PROVIDED BY SOFTARIS PTY.LTD. AND OTHER METABOSS
002: // CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
003: // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
004: // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTARIS PTY.LTD.
005: // OR OTHER METABOSS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
006: // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
007: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
008: // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
009: // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
010: // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
011: // EVEN IF SOFTARIS PTY.LTD. OR OTHER METABOSS CONTRIBUTORS ARE ADVISED OF THE
012: // POSSIBILITY OF SUCH DAMAGE.
013: //
014: // Copyright 2000-2005 © Softaris Pty.Ltd. All Rights Reserved.
015: package com.metaboss.sdlctools.applications.anttasks.builder;
016:
017: import java.util.ArrayList;
018: import java.util.Arrays;
019: import java.util.HashSet;
020: import java.util.Iterator;
021: import java.util.List;
022: import java.util.Set;
023:
024: import org.apache.tools.ant.BuildException;
025: import org.apache.tools.ant.types.Path;
026:
027: import com.metaboss.sdlctools.applications.anttasks.ModelElementRefType;
028: import com.metaboss.sdlctools.models.metabossmodel.ModelElement;
029:
030: /** The abstract element of the MetaBoss builder task. It supports
031: * following subelements:
032: * <UL>
033: * <LI>CompileClasspath - this is the standard ant Path element specifying the
034: * additional classpath to be used during compilation performed within this step.</LI>
035: * </UL>
036: */
037: public abstract class MetaBossBuilderTaskElement {
038: // This structure is used by subtypes to initialise element metadata
039: protected static class ElementMetadata {
040: public String ElementTypeName = null;
041: public boolean SupportsModelElementRefs = false;
042: public Class[] AllowedModelElementTypes = null;
043:
044: public ElementMetadata() {
045: }
046: }
047:
048: private ElementMetadata mElementMetadata = null;
049:
050: // The task, which is an owner of this element
051: private MetaBossBuilderTask mOwnerTask = null;
052: // The classpath to be added to compilation
053: private Path mCompileClasspath = null;
054: // The root model element associated with this task element to be used if none set explicitly
055: private ModelElement mDefaultRootModelElement = null;
056: // The root model element associated with this task element
057: private ModelElement mRootModelElement = null;
058: // The additional root model elements associated with this task element
059: // they will be considered in addition to the root model element when
060: // coming up with the list of included elements
061: private ModelElement[] mAdditionalRootModelElements = null;
062: // List of the custom references to the model elements. If this
063: // list is empty it means that whole root element should be used
064: private List mModelElementIncludes = null;
065:
066: /** The only available constructor */
067: public MetaBossBuilderTaskElement(MetaBossBuilderTask pOwnerTask,
068: ElementMetadata pElementMetadata) {
069: if (pOwnerTask == null)
070: throw new IllegalArgumentException(
071: "OwnerTask may not be null when constructiing MetaBossBuilderTaskElement.");
072: mOwnerTask = pOwnerTask;
073: if (pElementMetadata == null)
074: throw new IllegalArgumentException(
075: "ElementMetadata may not be null when constructiing MetaBossBuilderTaskElement.");
076: mElementMetadata = pElementMetadata;
077: }
078:
079: // Sets additional root model elements to consider
080: public void setAdditionalRootModelElements(
081: ModelElement[] pAdditionalRootModelElements) {
082: mAdditionalRootModelElements = pAdditionalRootModelElements;
083: }
084:
085: // Hidden default constructor
086: private MetaBossBuilderTaskElement() {
087: }
088:
089: /** Returns the owner of this element */
090: public final MetaBossBuilderTask getOwnerTask() {
091: return mOwnerTask;
092: }
093:
094: /** This method is used to return element metadata */
095: public ElementMetadata getElementMetadata() {
096: return mElementMetadata;
097: }
098:
099: /** The setter for the root model element to be used if ref is not set explicitly */
100: public void setDefaultRootModelElement(
101: ModelElement pDefaultRootModelElement)
102: throws BuildException {
103: if (!mElementMetadata.SupportsModelElementRefs)
104: throw new BuildException("Element <"
105: + mElementMetadata.ElementTypeName
106: + "> does not support 'ref' attribute.");
107: mDefaultRootModelElement = pDefaultRootModelElement;
108: }
109:
110: /** The setter for the "ref" attribute.
111: * Only works after setAllowModelElements() was called and the list
112: * of allowed model elements has been set */
113: public void setRef(String pRef) throws BuildException {
114: if (!mElementMetadata.SupportsModelElementRefs)
115: throw new BuildException("Element <"
116: + mElementMetadata.ElementTypeName
117: + "> does not support 'ref' attribute.");
118: mRootModelElement = getOwnerTask().getModelElement(pRef,
119: mElementMetadata.AllowedModelElementTypes);
120: }
121:
122: /** The special creator asking to include only particular ModelElements in to the resulting module.
123: * This allows to filter down elements owned by root element. For example if 'ref' attribute of the
124: * module dealing with services is referring to the System, the IncludeModelElement subelements could be used
125: * to only specify certain subset of services */
126: public ModelElementRefType createIncludeModelElement()
127: throws BuildException {
128: if (!mElementMetadata.SupportsModelElementRefs)
129: throw new BuildException("Element <"
130: + mElementMetadata.ElementTypeName
131: + "> does not support <ModelElement> subelements.");
132: if (mModelElementIncludes == null)
133: mModelElementIncludes = new ArrayList();
134: ModelElementRefType lModelElementRefType = new ModelElementRefType(
135: getOwnerTask(),
136: mElementMetadata.AllowedModelElementTypes);
137: mModelElementIncludes.add(lModelElementRefType);
138: return lModelElementRefType;
139: }
140:
141: /** The getter for the all ModelElements referenced by ref,xpath attributes and <ModelElement> subelements */
142: public ModelElement getRootModelElement() throws BuildException {
143: if (!mElementMetadata.SupportsModelElementRefs)
144: throw new BuildException(
145: "Element <"
146: + mElementMetadata.ElementTypeName
147: + "> does not support association with the model elements.");
148: if (mRootModelElement != null)
149: return mRootModelElement;
150: if (mDefaultRootModelElement != null)
151: return mDefaultRootModelElement;
152: throw new BuildException(
153: "Attribute 'ref' is not specified. It is mandatory for the <"
154: + mElementMetadata.ElementTypeName
155: + "> element.");
156: }
157:
158: /** The getter for the all ModelElements referenced by IncludeModelElement subelements */
159: public ModelElement[] getIncludedModelElements()
160: throws BuildException {
161: if (!mElementMetadata.SupportsModelElementRefs)
162: throw new BuildException(
163: "Element <"
164: + mElementMetadata.ElementTypeName
165: + "> does not support association with the model elements.");
166:
167: List lRootElements = new ArrayList();
168: lRootElements.add(getRootModelElement());
169: if (mAdditionalRootModelElements != null)
170: lRootElements.addAll(Arrays
171: .asList(mAdditionalRootModelElements));
172:
173: // If no includes were given - the whole root model element is returned
174: if (mModelElementIncludes == null)
175: return (ModelElement[]) lRootElements
176: .toArray(new ModelElement[lRootElements.size()]);
177:
178: // Collect all modules from all definitions
179: Set lAllModules = new HashSet();
180: for (Iterator lIter = mModelElementIncludes.iterator(); lIter
181: .hasNext();) {
182: ModelElementRefType lModelElementRefType = (ModelElementRefType) lIter
183: .next();
184: for (Iterator lRootElementsIter = lRootElements.iterator(); lRootElementsIter
185: .hasNext();)
186: lAllModules
187: .addAll(Arrays
188: .asList(lModelElementRefType
189: .getReferencedModelElements((ModelElement) lRootElementsIter
190: .next())));
191: }
192: return (ModelElement[]) lAllModules
193: .toArray(new ModelElement[lAllModules.size()]);
194: }
195:
196: /** The special creator asking to build compile classpath */
197: public Path createCompileClasspath() {
198: if (mCompileClasspath == null)
199: mCompileClasspath = new Path(getOwnerTask().getProject());
200: return mCompileClasspath.createPath();
201: }
202:
203: // The setter for the "compileclasspath" attribute
204: public void setCompileClasspath(Path pCompileClasspath) {
205: if (mCompileClasspath == null)
206: mCompileClasspath = new Path(getOwnerTask().getProject());
207: mCompileClasspath.add(pCompileClasspath);
208: }
209:
210: /** The getter for the compile classpath. Combines owner task compile classapth
211: * with the module one - to give a combined classpath */
212: public Path getCompileClasspath() {
213: Path lOwnerCompileClasspath = mOwnerTask.getCompileClasspath();
214: if (lOwnerCompileClasspath == null && mCompileClasspath == null)
215: return null;
216: if (lOwnerCompileClasspath != null && mCompileClasspath == null)
217: return lOwnerCompileClasspath;
218: if (lOwnerCompileClasspath == null && mCompileClasspath != null)
219: return mCompileClasspath;
220: // Need to combine two paths
221: Path lCompileClasspath = new Path(getOwnerTask().getProject());
222: lCompileClasspath.add(lOwnerCompileClasspath);
223: lCompileClasspath.add(mCompileClasspath);
224: return lCompileClasspath;
225: }
226: }
|