- /*
- * Copyright 2001-2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
- package org.apache.tools.ant.taskdefs.optional.starteam;
-
- import com.starbase.starteam.Folder;
- import com.starbase.starteam.Label;
- import com.starbase.starteam.PropertyNames;
- import com.starbase.starteam.StarTeamFinder;
- import com.starbase.starteam.View;
- import com.starbase.starteam.ViewConfiguration;
- import com.starbase.util.OLEDate;
- import java.text.ParseException;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.Hashtable;
- import java.util.StringTokenizer;
- import org.apache.tools.ant.BuildException;
- import org.apache.tools.ant.util.DateUtils;
- import org.apache.tools.ant.DirectoryScanner;
- import org.apache.tools.ant.Project;
-
- /**
- * TreeBasedTask.java
- * This abstract class is the base for any tasks that are tree-based, that
- * is, for tasks which iterate over a tree of folders in StarTeam which
- * is reflected in a tree of folder the local machine.
- *
- * This class provides the tree-iteration functionality. Derived classes
- * will implement their specific task functionality by the visitor pattern,
- * specifically by implementing the method
- * <code>visit(Folder rootStarteamFolder, java.io.File rootLocalFolder)</code>
- *
- * Created: Sat Dec 15 16:55:19 2001
- *
- * @version 1.0
- * @see <A HREF="http://www.starbase.com/">StarBase Web Site</A>
- */
-
- public abstract class TreeBasedTask extends StarTeamTask {
-
-
- ///////////////////////////////////////////////////////////////
- // default values for attributes.
- ///////////////////////////////////////////////////////////////
- /**
- * This constant sets the filter to include all files. This default has
- * the same result as <CODE>setIncludes("*")</CODE>.
- *
- * @see #getIncludes()
- * @see #setIncludes(String includes)
- */
- public static final String DEFAULT_INCLUDESETTING = "*";
-
- /**
- * This disables the exclude filter by default. In other words, no files
- * are excluded. This setting is equivalent to
- * <CODE>setExcludes(null)</CODE>.
- *
- * @see #getExcludes()
- * @see #setExcludes(String excludes)
- */
- public static final String DEFAULT_EXCLUDESETTING = null;
-
- //ATTRIBUTES settable from ant.
-
- /**
- * The root folder of the operation in StarTeam.
- */
- private String rootStarteamFolder = "/";
-
- /**
- * The local folder corresponding to starteamFolder. If not specified
- * the Star Team default folder will be used.
- */
- private String rootLocalFolder = null;
-
- /**
- * All files that fit this pattern are checked out.
- */
- private String includes = DEFAULT_INCLUDESETTING;
-
- /**
- * All files fitting this pattern are ignored.
- */
- private String excludes = DEFAULT_EXCLUDESETTING;
-
- /**
- * StarTeam label on which to perform task.
- */
- private String label = null;
-
- /**
- * Set recursion to false to check out files in only the given folder
- * and not in its subfolders.
- */
- private boolean recursive = true;
-
- /**
- * Set preloadFileInformation to true to load all file information from the server
- * at once. Increases performance significantly for projects with many files and/or folders.
- */
- private boolean preloadFileInformation = true;
-
- /**
- * If forced set to true, files in the target directory will
- * be processed regardless of status in the repository.
- * Usually this should be true if rootlocalfolder is set
- * because status will be relative to the default folder, not
- * to the one being processed.
- */
- private boolean forced = false;
-
- private Label labelInUse = null;
-
- /**
- * holder for the asofdate attribute
- */
- private String asOfDate = null;
-
- /**
- * holder for the asofdateformat attribute
- */
- private String asOfDateFormat = null;
-
-
-
- ///////////////////////////////////////////////////////////////
- // GET/SET methods.
- // Setters, of course are where ant user passes in values.
- ///////////////////////////////////////////////////////////////
-
- /**
- * Set the root of the subtree in the StarTeam repository from which to
- * work; optional. Defaults to the root folder of the view ('/').
- * @param rootStarteamFolder the root folder
- */
- public void setRootStarteamFolder(String rootStarteamFolder) {
- this.rootStarteamFolder = rootStarteamFolder;
- }
-
- /**
- * returns the root folder in the Starteam repository
- * used for this operation
- * @return the root folder in use
- */
- public String getRootStarteamFolder() {
- return this.rootStarteamFolder;
- }
-
- /**
- * Set the local folder that will be the root of the tree
- * to which files are checked out; optional.
- * If this is not supplied, then the StarTeam "default folder"
- * associated with <tt>rootstarteamfolder</tt> is used.
- *
- * @param rootLocalFolder
- * the local folder that will mirror
- * this.rootStarteamFolder
- *
- * @see rootLocalFolder
- */
- public void setRootLocalFolder(String rootLocalFolder) {
- this.rootLocalFolder = rootLocalFolder;
- }
-
-
-
- /**
- * Returns the local folder specified by the user,
- * corresponding to the starteam folder for this operation
- * or null if not specified.
- *
- * @return the local folder that mirrors this.rootStarteamFolder
- * @see rootLocalFolder
- */
- public String getRootLocalFolder() {
- return this.rootLocalFolder;
- }
-
-
- /**
- * Declare files to include using standard <tt>includes</tt> patterns; optional.
- * @param includes A string of filter patterns to include. Separate the
- * patterns by spaces.
- * @see #getIncludes()
- * @see #setExcludes(String excludes)
- * @see #getExcludes()
- */
- public void setIncludes(String includes) {
- this.includes = includes;
- }
-
- /**
- * Gets the patterns from the include filter. Rather that duplicate the
- * details of AntStarTeamCheckOut's filtering here, refer to these
- * links:
- *
- * @return A string of filter patterns separated by spaces.
- * @see #setIncludes(String includes)
- * @see #setExcludes(String excludes)
- * @see #getExcludes()
- */
- public String getIncludes() {
- return includes;
- }
-
- /**
- * if excludes have been specified, emit the list to the log
- */
- protected void logIncludes() {
- if (this.DEFAULT_INCLUDESETTING != this.includes) {
- log(" Includes specified: " + this.includes);
- }
- }
-
- /**
- * Declare files to exclude using standard <tt>excludes</tt> patterns; optional.
- * When filtering files, AntStarTeamCheckOut
- * uses an unmodified version of <CODE>DirectoryScanner</CODE>'s
- * <CODE>match</CODE> method, so here are the patterns straight from the
- * Ant source code:
- * <BR><BR>
- * Matches a string against a pattern. The pattern contains two special
- * characters:
- * <BR>'*' which means zero or more characters,
- * <BR>'?' which means one and only one character.
- * <BR><BR>
- * For example, if you want to check out all files except .XML and
- * .HTML files, you would put the following line in your program:
- * <CODE>setExcludes("*.XML,*.HTML");</CODE>
- * Finally, note that filters have no effect on the <B>directories</B>
- * that are scanned; you could not skip over all files in directories
- * whose names begin with "project," for instance.
- * <BR><BR>
- * Treatment of overlapping inlcudes and excludes: To give a simplistic
- * example suppose that you set your include filter to "*.htm *.html"
- * and your exclude filter to "index.*". What happens to index.html?
- * AntStarTeamCheckOut will not check out index.html, as it matches an
- * exclude filter ("index.*"), even though it matches the include
- * filter, as well.
- * <BR><BR>
- * Please also read the following sections before using filters:
- *
- * @param excludes A string of filter patterns to exclude. Separate the
- * patterns by spaces.
- * @see #setIncludes(String includes)
- * @see #getIncludes()
- * @see #getExcludes()
- */
- public void setExcludes(String excludes) {
- this.excludes = excludes;
- }
-
- /**
- * Gets the patterns from the exclude filter. Rather that duplicate the
- * details of AntStarTeanCheckOut's filtering here, refer to these
- * links:
- *
- * @return A string of filter patterns separated by spaces.
- * @see #setExcludes(String excludes)
- * @see #setIncludes(String includes)
- * @see #getIncludes()
- */
- public String getExcludes() {
- return excludes;
- }
-
- /**
- * if excludes have been specified, emit the list to the log
- */
- protected void logExcludes() {
- if (this.DEFAULT_EXCLUDESETTING != this.excludes) {
- log(" Excludes specified: " + this.excludes);
- }
- }
-
-
- /**
- * protected function to allow subclasses to set the label (or not).
- * sets the StarTeam label
- *
- * @param label name of the StarTeam label to be set
- */
- protected void _setLabel(String label) {
- if (null != label) {
- label = label.trim();
- if (label.length() > 0) {
- this.label = label;
- }
- }
- }
-
- /**
- * non-public method callable only by derived classes that implement
- * setAsOfDate (so that derived tasks that do not accept this
- * parameter will fail if user attempts to use it.
- *
- * @param asOfDate asOfDate entered by user.
- * @since Ant 1.6
- */
- protected void _setAsOfDate(String asOfDate) {
- if (asOfDate != null && asOfDate.length() > 0) {
- this.asOfDate = asOfDate;
- }
- }
-
- /**
- * non-public method callable only by derived classes that implement
- * setAsOfDateFormat (so that derived tasks that do not accept this
- * parameter will fail if user attempts to use it.
- *
- * @param asOfDateFormat asOfDate format entered by user.
- * @since Ant 1.6
- */
- protected void _setAsOfDateFormat(String asOfDateFormat) {
- if (asOfDateFormat != null && asOfDateFormat.length() > 0) {
- this.asOfDateFormat = asOfDateFormat;
- }
- }
-
-
- /**
- * return the asOfDate entered by the user for internal use by derived
- * classes.
- *
- * @return the asOfDate entered by the user
- * @since Ant 1.6
- */
- protected String getAsOfDate() {
- return this.asOfDate;
- }
-
-
-
- /**
- * If an asofDate parameter has been supplied by the user return a
- * StarTeam view based on the configuration of the StarTeam view
- * specified the user as of the date specified in the parameter.
- * If no asofDate has been specified, return null.
- *
- * This method is meant to be called from within implementations of the
- * <code>createSnapshotView</code> abstract method.
- *
- * @param raw the raw view to be configured as of the supplied date
- *
- * @return the view as configured.
- * @exception BuildException
- * thrown if the date is not parsable by the default or
- * supplied format patterns.
- * @since Ant 1.6
- */
- protected View getViewConfiguredByDate(View raw) throws BuildException {
- if (this.asOfDate == null) {
- return null;
- }
- Date asOfDate = null;
- SimpleDateFormat fmt = null;
- if (this.asOfDateFormat != null) {
- fmt = new SimpleDateFormat(this.asOfDateFormat);
- try {
- asOfDate = fmt.parse(this.asOfDate);
- }
- catch (ParseException px)
- {
- throw new BuildException("AsOfDate "
- + this.asOfDate
- + " not parsable by supplied format "
- + this.asOfDateFormat);
- }
- } else {
- try {
- asOfDate = DateUtils.parseIso8601DateTimeOrDate(
- this.asOfDate);
- } catch (ParseException px) {
- throw new BuildException("AsOfDate "
- + this.asOfDate
- + " not parsable by default"
- + " ISO8601 formats");
- }
- }
- return new View(raw, ViewConfiguration.createFromTime(
- new OLEDate(asOfDate)));
- }
-
-
-
- /**
- * return the label passed to the task by the user as a string
- *
- * @return the label passed to the task by the user as a string
- */
- protected String getLabel() {
- return this.label;
- }
-
- /**
- * Get the value of recursive.
- * @return value of recursive.
- */
- public boolean isRecursive() {
- return this.recursive;
- }
-
- /**
- * Flag to set to include files in subfolders in the operation; optional,
- * default true.
- * @param v Value to assign to recursive.
- */
- public void setRecursive(boolean v) {
- this.recursive = v;
- }
-
- /**
- * Get the value of preloadFileInformation.
- * @return value of preloadFileInformation.
- */
- public boolean isPreloadFileInformation() {
- return this.preloadFileInformation;
- }
-
- /**
- * Flag to set to preload file information from the server; optional,
- * default true.
- * Increases performance significantly for projects with many files
- * and/or folders.
- * @param v Value to assign to preloadFileInformation.
- */
- public void setPreloadFileInformation(boolean v) {
- this.preloadFileInformation = v;
- }
-
- /**
- * Get the value of forced.
- * @return value of forced.
- */
- public boolean isForced() {
- return this.forced;
- }
-
- /**
- * Flag to force actions regardless of the status
- * that StarTeam is maintaining for the file; optional, default false.
- * If <tt>rootlocalfolder</tt> is set then
- * this should be set "true" as otherwise the checkout will be based on statuses
- * which do not relate to the target folder.
- * @param v Value to assign to forced.
- */
- public void setForced(boolean v) {
- this.forced = v;
- }
-
- /**
- * returns true if a label has been specified and it is a view label.
- *
- * @return true if a label has been specified and it is a view label
- */
- protected boolean isUsingViewLabel() {
- return null != this.labelInUse && this.labelInUse.isViewLabel();
- }
- /**
- * returns true if a label has been specified and it is a revision label.
- *
- * @return true if a label has been specified and it is a revision label
- */
- protected boolean isUsingRevisionLabel() {
- return null != this.labelInUse && this.labelInUse.isRevisionLabel();
- }
-
- /**
- * returns the label being used
- *
- * @return the label being used
- */
- protected Label getLabelInUse() {
- return this.labelInUse;
- }
-
- /**
- * show the label in the log and its type.
- */
- protected void logLabel() {
- if (this.isUsingViewLabel()) {
- log(" Using view label " + getLabel());
- } else if (this.isUsingRevisionLabel()) {
- log(" Using revision label " + getLabel());
- }
- }
-
- /**
- * show the asofDate in the log
- * @since Ant 1.6
- */
- protected void logAsOfDate() {
- if (null != this.asOfDate) {
- log(" Using view as of date " + getAsOfDate());
- }
- }
-
-
-
-
-
- ///////////////////////////////////////////////////////////////
- // INCLUDE-EXCLUDE processing
- ///////////////////////////////////////////////////////////////
-
- /**
- * Look if the file should be processed by the task.
- * Don't process it if it fits no include filters or if
- * it fits an exclude filter.
- *
- * @param pName the item name to look for being included.
- *
- * @return whether the file should be processed or not.
- */
- protected boolean shouldProcess(String pName) {
- boolean includeIt = matchPatterns(getIncludes(), pName);
- boolean excludeIt = matchPatterns(getExcludes(), pName);
- return (includeIt && !excludeIt);
- }
-
- /**
- * Convenience method to see if a string match a one pattern
- * in given set of space-separated patterns.
- * @param patterns the space-separated list of patterns.
- * @param pName the name to look for matching.
- * @return whether the name match at least one pattern.
- */
- protected boolean matchPatterns(String patterns, String pName) {
- if (patterns == null) {
- return false;
- }
- StringTokenizer exStr = new StringTokenizer(patterns, ",");
- while (exStr.hasMoreTokens()) {
- if (DirectoryScanner.match(exStr.nextToken(), pName)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Finds and opens the root starteam folder of the operation specified
- * by this task. This will be one of the following cases:
- *
- * @return Starteam's root folder for the operation.
- * @exception BuildException
- * if the root folder cannot be found in the repository
- */
- private final Folder configureRootStarteamFolder()
- throws BuildException {
- Folder starteamrootfolder = null;
- try {
- // no root local mapping has been specified.
- View snapshot = openView();
-
- // find the starteam folder specified to be the root of the
- // operation. Throw if it can't be found.
-
- starteamrootfolder =
- StarTeamFinder.findFolder(snapshot.getRootFolder(),
- this.rootStarteamFolder);
-
- if (this.isPreloadFileInformation()) {
- PropertyNames pn = getServer().getPropertyNames();
- String[] props = new String[] {pn.FILE_NAME, pn.FILE_PATH,
- pn.FILE_STATUS, pn.MODIFIED_TIME,
- pn.FILE_FILE_TIME_AT_CHECKIN,
- pn.MODIFIED_USER_ID, pn.FILE_SIZE};
-
- int depth = this.isRecursive() ? -1 : 0;
- starteamrootfolder.populateNow(getServer().getTypeNames().FILE,
- props, depth);
- }
-
-
- } catch (BuildException e) {
- throw e;
- } catch (Exception e) {
- StringBuffer msg = new StringBuffer("Unable to find root folder ")
- .append(this.rootStarteamFolder)
- .append(" in repository at ")
- .append(getURL());
- if (this.label != null) {
- msg.append(" using specified label ").append(this.label);
- }
- if (this.asOfDate != null) {
- msg.append(" as of specified date ")
- .append(this.asOfDate);
- }
- throw new BuildException(msg.toString(), e);
-
- }
-
- if (null == starteamrootfolder) {
- throw new BuildException("Unable to find root folder "
- + this.rootStarteamFolder + " in repository at " + getURL());
- }
-
- return starteamrootfolder;
- }
-
- /**
- * Returns the local folder mapped to the given StarTeam root folder
- * of the operation. There are two cases here, depending on whether
- * <code>rootLocalFolder</code> is defined.
- * If <code>rootLocalFolder</code> is defined, it will be used to
- * establish a root mapping. Otherwise, the repository's default root
- * folder will be used.
- *
- * @param starteamrootfolder
- * root Starteam folder initialized for the operation
- *
- * @return the local folder corresponding to the root Starteam folder.
- * @see findRootStarteamFolder
- */
- private final java.io.File getLocalRootMapping(Folder starteamrootfolder) {
- // set the local folder.
- String localrootfolder;
- if (null != this.rootLocalFolder) {
- localrootfolder = rootLocalFolder;
- } else {
- // either use default path or root local mapping,
- // which is now embedded in the root folder
- localrootfolder = starteamrootfolder.getPathFragment();
- }
-
- return new java.io.File(localrootfolder);
-
- }
-
- /**
- * extenders should emit to the log an entry describing the parameters
- * that will be used by this operation.
- *
- * @param starteamrootFolder
- * root folder in StarTeam for the operation
- * @param targetrootFolder
- * root local folder for the operation (whether specified by the user or not.
- */
- protected abstract void logOperationDescription(
- Folder starteamrootFolder, java.io.File targetrootFolder);
-
- /**
- * This method does the work of opening the supplied Starteam view and
- * calling the <code>visit()</code> method to perform the task.
- * Derived classes can customize the called methods
- * <code>testPreconditions()</code> and <code>visit()</code>.
- *
- * @exception BuildException if any error occurs in the processing
- * @see <code>testPreconditions()</code>
- * @see <code>visit()</code>
- */
-
- public final void execute() throws BuildException {
- try {
-
- Folder starteamrootfolder = configureRootStarteamFolder();
-
- // set the local folder.
- java.io.File localrootfolder =
- getLocalRootMapping(starteamrootfolder);
-
- testPreconditions();
-
- // Tell user what he is doing
- logOperationDescription(starteamrootfolder, localrootfolder);
-
- // Inspect everything in the root folder and then recursively
- visit(starteamrootfolder, localrootfolder);
-
- } catch (Exception e) {
- throw new BuildException(e);
- } finally {
- disconnectFromServer();
- }
- }
-
- private void findLabel(View v) throws BuildException {
- Label[] allLabels = v.getLabels();
- for (int i = 0; i < allLabels.length; i++) {
- Label stLabel = allLabels[i];
- log("checking label " + stLabel.getName(), Project.MSG_DEBUG);
- if (stLabel != null && !stLabel.isDeleted() && stLabel.getName().equals(this.label)) {
- if (!stLabel.isRevisionLabel() && !stLabel.isViewLabel()) {
- throw new BuildException("Unexpected label type.");
- }
- log("using label " + stLabel.getName(), Project.MSG_VERBOSE);
- this.labelInUse = stLabel;
- return;
- }
- }
- throw new BuildException("Error: label "
- + this.label
- + " does not exist in view "
- + v.getFullName());
-
- }
-
- /**
- * Helper method calls on the StarTeam API to retrieve an ID number
- * for the specified view, corresponding to this.label.
- * @param v the <code>View</code> in which to search for <code>this.label</code>
- * @return the ID number corresponding to <code>this.label</code> or -1 if
- * no label was provided.
- * @exception BuildException if <code>this.label</code> does not correspond
- * to any label in the supplied view
- */
- protected int getLabelID(View v) throws BuildException {
- if (null != this.label) {
- findLabel(v);
- return this.labelInUse.getID();
- }
- return -1;
- }
-
- protected int getIDofLabelInUse() {
- if (null != this.labelInUse) {
- return this.labelInUse.getID();
- }
- return -1;
- }
-
- /**
- * Derived classes must override this class to define actual processing
- * to be performed on each folder in the tree defined for the task
- *
- * @param rootStarteamFolder
- * the StarTeam folderto be visited
- * @param rootLocalFolder
- * the local mapping of rootStarteamFolder
- *
- * @exception BuildException
- */
- protected abstract void visit(Folder rootStarteamFolder,
- java.io.File rootLocalFolder)
- throws BuildException;
-
-
-
-
- /**
- * Derived classes must override this method to define tests for
- * any preconditons required by the task. This method is called at
- * the beginning of the execute() method.
- *
- * @exception BuildException throw if any fatal error exists in the
- * parameters supplied. If there is a non-fatal condition, just writing
- * to the log may be appropriate.
- * @see <code>execute()</code>
- */
- protected abstract void testPreconditions() throws BuildException;
-
-
- /**
- * Return the full repository path name of a file. Surprisingly there's
- * no method in com.starbase.starteam.File to provide this.
- *
- * @param remotefile the Star Team file whose path is to be returned
- *
- * @return the full repository path name of a file.
- */
- public static String getFullRepositoryPath(
- com.starbase.starteam.File remotefile) {
- StringBuffer sb = new StringBuffer();
- sb.append(remotefile.getParentFolderHierarchy())
- .append(remotefile.getName());
- return sb.toString();
- }
-
- /**
- * This class implements a map of existing local files to possibly
- * existing repository files. The map is created by a TreeBasedTask
- * upon recursing into a directory. Each local item is mapped to an
- * unattached StarTeam object of the proper type, File->File and
- * Directory->Folder.
- *
- * As the TreeBased does its work, it deletes from the map all items
- * it has processed.
- *
- * When the TreeBased task processes all the items from the repository,
- * whatever items left in the UnmatchedFileMap are uncontrolled items
- * and can be processed as appropriate to the task. In the case of
- * Checkouts, they can be optionally deleted from the local tree. In the
- * case of Checkins they can optionally be added to the repository.
- */
- protected abstract class UnmatchedFileMap extends Hashtable {
-
- /**
- * initializes the UnmatchedFileMap with entries from the local folder
- * These will be mapped to the corresponding StarTeam entry even though
- * it will not, in fact, exist in the repository. But through it, it
- * can be added, listed, etc.
- *
- * @param localFolder
- * the local folder from which the mappings will be made.
- * @param remoteFolder
- * the corresponding StarTeam folder which will be processed.
- */
- UnmatchedFileMap init(java.io.File localFolder, Folder remoteFolder) {
- if (!localFolder.exists()) {
- return this;
- }
-
- String[] localFiles = localFolder.list();
-
- for (int i = 0; i < localFiles.length; i++) {
- String fn = localFiles[i];
- java.io.File localFile =
- new java.io.File(localFolder, localFiles[i]).getAbsoluteFile();
-
- log("adding " + localFile + " to UnmatchedFileMap",
- Project.MSG_DEBUG);
-
- if (localFile.isDirectory()) {
- this.put(localFile, new Folder(remoteFolder, fn, fn));
- } else {
- com.starbase.starteam.File remoteFile =
- new com.starbase.starteam.File(remoteFolder);
- remoteFile.setName(fn);
- this.put(localFile, remoteFile);
- }
- }
- return this;
- }
-
- /**
- * remove an item found to be controlled from the map.
- *
- * @param localFile the local item found to be controlled.
- */
- void removeControlledItem(java.io.File localFile) {
- if (isActive()) {
- log("removing processed " + localFile.getAbsoluteFile()
- + " from UnmatchedFileMap", Project.MSG_DEBUG);
- this.remove(localFile.getAbsoluteFile());
- }
- }
- /**
- * override will perform the action appropriate for its task to perform
- * on items which are on the local tree but not in StarTeam. It is
- * assumed that this method will not be called until all the items in
- * the corresponding folder have been processed, and that the internal
- * map * will contain only uncontrolled items.
- */
- abstract void processUncontrolledItems() throws BuildException;
-
- /**
- * overrides must define this to declare how this method knows if it
- * is active. This presents extra clock cycles when the functionality
- * is not called for.
- *
- * @return True if this object is to perform its functionality.
- */
- protected abstract boolean isActive();
-
- }
-
- }
-
-
-