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.tools;
016:
017: import java.io.File;
018: import java.util.Arrays;
019: import java.util.HashSet;
020: import java.util.Iterator;
021: import java.util.Set;
022:
023: import org.apache.tools.ant.BuildException;
024: import org.apache.tools.ant.Project;
025: import org.apache.tools.ant.taskdefs.Javac;
026: import org.apache.tools.ant.types.Path;
027: import org.apache.tools.ant.types.PatternSet;
028:
029: import com.metaboss.sdlctools.applications.anttasks.AntMetaBossUtils;
030: import com.metaboss.sdlctools.applications.anttasks.builder.MetaBossBuilderTask;
031: import com.metaboss.sdlctools.applications.anttasks.builder.ToolInvocationDefinition;
032: import com.metaboss.util.ObjectUtils;
033:
034: /** This definition is responsible for invocation of the Java compiler */
035: public class JavaCompilerInvocationDefinition extends
036: ToolInvocationDefinition {
037: // This class provides definition of the source definition
038: private static class SourceSetDefinition {
039: private JavaCompilerInvocationDefinition mOwnerDefinition;
040: public File RootDirectory;
041: public Set Includes = new HashSet();
042: public Set Excludes = new HashSet();
043:
044: public SourceSetDefinition(
045: JavaCompilerInvocationDefinition pOwnerDefinition) {
046: mOwnerDefinition = pOwnerDefinition;
047: }
048:
049: public boolean equals(Object pOther) {
050: if (this == pOther)
051: return true;
052: if (pOther instanceof SourceSetDefinition) {
053: SourceSetDefinition lOther = (SourceSetDefinition) pOther;
054: mOwnerDefinition.getOwnerTask().getLogger().verbose(
055: "Comparing two SourceSetDefinitions...");
056:
057: // Compare root directory
058: if (!ObjectUtils.equals(
059: RootDirectory.getAbsolutePath(),
060: lOther.RootDirectory.getAbsolutePath())) {
061: mOwnerDefinition.getOwnerTask().getLogger()
062: .verbose(
063: "Root directory comparison mismatch ('"
064: + RootDirectory
065: .getAbsolutePath()
066: + " vs "
067: + lOther.RootDirectory
068: .getAbsolutePath()
069: + ")");
070: return false;
071: }
072: // Compare includes
073: if (Includes.size() != lOther.Includes.size()) {
074: mOwnerDefinition.getOwnerTask().getLogger()
075: .verbose(
076: "Includes size mismatch ("
077: + Includes.size() + " vs "
078: + lOther.Includes.size()
079: + ")");
080: return false;
081: }
082: for (Iterator lIncludesIterator = lOther.Includes
083: .iterator(); lIncludesIterator.hasNext();) {
084: if (!Includes.contains(lIncludesIterator.next())) {
085: mOwnerDefinition.getOwnerTask().getLogger()
086: .verbose("Includes contents mismatch");
087: return false;
088: }
089: }
090: // Compare excludes
091: if (Excludes.size() != lOther.Excludes.size()) {
092: mOwnerDefinition.getOwnerTask().getLogger()
093: .verbose(
094: "Excludes size mismatch ("
095: + Excludes.size() + " vs "
096: + lOther.Excludes.size()
097: + ")");
098: return false;
099: }
100: for (Iterator lExcludesIterator = lOther.Excludes
101: .iterator(); lExcludesIterator.hasNext();) {
102: if (!Excludes.contains(lExcludesIterator.next())) {
103: mOwnerDefinition.getOwnerTask().getLogger()
104: .verbose("Excludes contents mismatch");
105: return false;
106: }
107: }
108: mOwnerDefinition.getOwnerTask().getLogger().verbose(
109: "SourceSetDefinitions are equal");
110: return true; // Everything appears to be in order
111: }
112: return false;
113: }
114: };
115:
116: private String mInvocationName = null;
117: private SourceSetDefinition mSourceSet;
118: private String mClasspathReference = null; // Actual classpath to use
119: private String mClasspathName = null; // Logical classpath to use
120: private Path mAdditionalClasspath = null; // Additonal physical classpath to use
121:
122: /** Public constructor for the invocation */
123: public JavaCompilerInvocationDefinition(
124: MetaBossBuilderTask pOwnerTask, String pInvocationName) {
125: super (pOwnerTask, pInvocationName);
126: mSourceSet = new SourceSetDefinition(this );
127: }
128:
129: /** Sets the reference to the predefined Java class path. This classpath is
130: * predefined in the project */
131: public void setClasspathReference(String pClasspathReference) {
132: mClasspathReference = pClasspathReference;
133: }
134:
135: /** Sets the name of the predefined Java class path. This classpath is
136: * predefined internally in the in the resources stored stored in MetaBossAntIntegration.jar file */
137: public void setClasspathName(String pClasspathName) {
138: mClasspathName = pClasspathName;
139: }
140:
141: /** Sets the additional classpath to use */
142: public void setAdditionalClasspath(Path pAdditionalClasspath) {
143: mAdditionalClasspath = pAdditionalClasspath;
144: }
145:
146: /** Getter for the additional classpath to use */
147: public Path getAdditionalClasspath() {
148: return mAdditionalClasspath;
149: }
150:
151: /** Getter for the the name of the predefined Java classpath */
152: public String getClasspathName() {
153: return mClasspathName;
154: }
155:
156: /** Getter for the the reference to the predefined Java class path */
157: public String getClasspathReference() {
158: return mClasspathReference;
159: }
160:
161: /** Adds single source directory to include */
162: public void setSourceRootDir(File pRootDirectory) {
163: if (mSourceSet.RootDirectory != null)
164: throw new BuildException(
165: "One instance of the JavaCompilerInvocationDefinition can only support one source directory.");
166: mSourceSet.RootDirectory = pRootDirectory;
167: }
168:
169: /** Adds list of includes to the set of includes */
170: public void addSourceIncludes(String[] pIncludes) {
171: mSourceSet.Includes.addAll(Arrays.asList(pIncludes));
172: }
173:
174: /** Adds single include to the set of includes */
175: public void addSourceInclude(String pInclude) {
176: mSourceSet.Includes.add(pInclude);
177: }
178:
179: /** Adds list of excludes to the set of excludes */
180: public void addSourceExcludes(String[] pExcludes) {
181: mSourceSet.Excludes.addAll(Arrays.asList(pExcludes));
182: }
183:
184: /** Adds single exclude to the set of excludes from generated source path */
185: public void addSourceExclude(String pExclude) {
186: mSourceSet.Excludes.add(pExclude);
187: }
188:
189: /** Overridden to compare details of the invocation */
190: public boolean equals(Object pOther) {
191: if (this == pOther)
192: return true;
193: if (pOther instanceof JavaCompilerInvocationDefinition) {
194: JavaCompilerInvocationDefinition lOther = (JavaCompilerInvocationDefinition) pOther;
195: getOwnerTask().getLogger().verbose(
196: "Comparing two " + getClass().getName()
197: + " instances...");
198:
199: // Compare names
200: if (!getToolInvocationName().equals(
201: lOther.getToolInvocationName())) {
202: getOwnerTask()
203: .getLogger()
204: .verbose(
205: "Name mismatch ('"
206: + getToolInvocationName()
207: + "' vs '"
208: + lOther
209: .getToolInvocationName()
210: + "')");
211: return false;
212: }
213: // Compare sourcesets
214: if (!mSourceSet.equals(lOther.mSourceSet)) {
215: getOwnerTask().getLogger()
216: .verbose("SourceSet mismatch");
217: return false;
218: }
219: if (!ObjectUtils.equals(mClasspathReference,
220: lOther.mClasspathReference)) {
221: getOwnerTask().getLogger().verbose(
222: "Classpath Reference mismatch ('"
223: + mClasspathReference + "' vs '"
224: + lOther.mClasspathReference + "')");
225: return false;
226: }
227: if (!ObjectUtils.equals(mClasspathName,
228: lOther.mClasspathName)) {
229: getOwnerTask().getLogger().verbose(
230: "Classpath Name mismatch ('" + mClasspathName
231: + "' vs '" + lOther.mClasspathName
232: + "')");
233: return false;
234: }
235: if (!AntMetaBossUtils.pathEquals(mAdditionalClasspath,
236: lOther.mAdditionalClasspath)) {
237: getOwnerTask().getLogger().verbose(
238: "Additional Classpath mismatch ('"
239: + mAdditionalClasspath + "' vs '"
240: + lOther.mAdditionalClasspath + "')");
241: return false;
242: }
243: getOwnerTask().getLogger().verbose(
244: "The instances are equal");
245: return true; // Everything appears to be in order
246: }
247: return false;
248: }
249:
250: // This method answers question whether this tool invocation could be combined with the given one.
251: // Overidden to see if we can combine java compiler
252: public boolean canCombine(ToolInvocationDefinition pOther)
253: throws BuildException {
254: if (this == pOther)
255: return true;
256: if (pOther instanceof JavaCompilerInvocationDefinition) {
257: JavaCompilerInvocationDefinition lOther = (JavaCompilerInvocationDefinition) pOther;
258: // Can only combine if same classpath and same source dir
259: if (mSourceSet.RootDirectory == null
260: || lOther.mSourceSet.RootDirectory == null
261: || mSourceSet.RootDirectory
262: .equals(lOther.mSourceSet.RootDirectory) == false)
263: return false;
264: if (!ObjectUtils.equals(mClasspathReference,
265: lOther.mClasspathReference))
266: return false;
267: if (!ObjectUtils.equals(mClasspathName,
268: lOther.mClasspathName))
269: return false;
270: if (!ObjectUtils.equals(mAdditionalClasspath,
271: lOther.mAdditionalClasspath))
272: return false;
273: return true;
274: }
275: return false;
276: }
277:
278: // This method combines this tool invocation definition with the given one.
279: public ToolInvocationDefinition combine(
280: ToolInvocationDefinition pOther) throws BuildException {
281: if (!canCombine(pOther))
282: throw new BuildException(
283: "Internal error. Attempt is made to combine tool invocations, which can not be combined.");
284: JavaCompilerInvocationDefinition lOther = (JavaCompilerInvocationDefinition) pOther;
285: JavaCompilerInvocationDefinition lCombinedInvocation = new JavaCompilerInvocationDefinition(
286: getOwnerTask(), "Combined invocation");
287: // The values below should only be copied from one of the ingredients because they are the same
288: lCombinedInvocation
289: .setClasspathReference(getClasspathReference());
290: lCombinedInvocation.setClasspathName(getClasspathName());
291: lCombinedInvocation
292: .setAdditionalClasspath(getAdditionalClasspath());
293:
294: // Combine sourcesets
295: lCombinedInvocation.mSourceSet.RootDirectory = mSourceSet.RootDirectory;
296: lCombinedInvocation.mSourceSet.Includes
297: .addAll(mSourceSet.Includes);
298: lCombinedInvocation.mSourceSet.Includes
299: .addAll(lOther.mSourceSet.Includes);
300: lCombinedInvocation.mSourceSet.Excludes
301: .addAll(mSourceSet.Excludes);
302: lCombinedInvocation.mSourceSet.Excludes
303: .addAll(lOther.mSourceSet.Excludes);
304: return lCombinedInvocation;
305: }
306:
307: /** This method will have to invoke the generator */
308: public void invoke() throws BuildException {
309: MetaBossBuilderTask lOwnerTask = getOwnerTask();
310: Project lThisProject = getOwnerTask().getProject();
311: // Now create and execute the java compiler task
312: Javac lJavacTask = (Javac) lThisProject.createTask("javac");
313: lJavacTask.setTaskName(lOwnerTask.getTaskName());
314: // lJavacTask.setFork(true);
315: // lJavacTask.setMemoryInitialSize("16m");
316: // lJavacTask.setMemoryMaximumSize("256m");
317: // Dest dir
318: lJavacTask.setDestdir(lOwnerTask.getClassDir());
319: Path lClasspath = lJavacTask.createClasspath();
320: if (mClasspathName != null)
321: lClasspath.addExisting(lOwnerTask.getPath(mClasspathName));
322: if (mAdditionalClasspath != null)
323: lClasspath.addExisting(mAdditionalClasspath);
324: if (mClasspathReference != null) {
325: Object lReferencedPath = lThisProject
326: .getReference(mClasspathReference);
327: if ((lReferencedPath == null)
328: || ((lReferencedPath instanceof Path) == false))
329: throw new BuildException("The path with id '"
330: + mClasspathReference
331: + "' is not found in the project");
332: lClasspath.addExisting((Path) lReferencedPath);
333: }
334: lJavacTask.setFailonerror(true);
335: lJavacTask.setDebug(getOwnerTask().isDebugBuild());
336: if (mSourceSet.RootDirectory == null)
337: throw new BuildException(
338: "Compiler instruction does not specify any source directory");
339: Path lSrc = lJavacTask.createSrc();
340: lSrc.setLocation(mSourceSet.RootDirectory);
341: // Work on includes
342: for (Iterator lIncludesIterator = mSourceSet.Includes
343: .iterator(); lIncludesIterator.hasNext();) {
344: PatternSet.NameEntry lIncludeNameEntry = lJavacTask
345: .createInclude();
346: lIncludeNameEntry
347: .setName((String) lIncludesIterator.next());
348: }
349: // Work on excludes
350: for (Iterator lExcludesIterator = mSourceSet.Excludes
351: .iterator(); lExcludesIterator.hasNext();) {
352: PatternSet.NameEntry lExcludeNameEntry = lJavacTask
353: .createExclude();
354: lExcludeNameEntry
355: .setName((String) lExcludesIterator.next());
356: }
357: lJavacTask.execute();
358: }
359: }
|