001 // Copyright 2004, 2005 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.hivemind.ant;
016
017 import java.io.File;
018
019 import org.apache.tools.ant.BuildException;
020 import org.apache.tools.ant.Task;
021 import org.apache.tools.ant.types.Path;
022
023 /**
024 * Utility used to create a manifest class path.
025 * It takes, as input, a reference to a path. It converts this
026 * into a space-separated list of file names. The default
027 * behavior is to simply strip off the directory portion of
028 * each file entirely.
029 *
030 * <p>
031 * The final result is assigned to the property.
032 *
033 * @author Howard Lewis Ship
034 */
035 public class ManifestClassPath extends Task
036 {
037 private String _property;
038 private Path _classpath;
039 private File _directory;
040
041 public Path createClasspath()
042 {
043 _classpath = new Path(getProject());
044
045 return _classpath;
046 }
047
048 public String getProperty()
049 {
050 return _property;
051 }
052
053 public void setProperty(String string)
054 {
055 _property = string;
056 }
057
058 public void execute()
059 {
060 if (_classpath == null)
061 throw new BuildException("You must specify a classpath to generate the manifest entry from");
062
063 if (_property == null)
064 throw new BuildException("You must specify a property to assign the manifest classpath to");
065
066 StringBuffer buffer = new StringBuffer();
067
068 String[] paths = _classpath.list();
069
070 String stripPrefix = null;
071
072 if (_directory != null)
073 stripPrefix = _directory.getPath();
074
075 // Will paths ever be null?
076
077 boolean needSep = false;
078
079 for (int i = 0; i < paths.length; i++)
080 {
081 String path = paths[i];
082
083 if (stripPrefix != null)
084 {
085 if (!path.startsWith(stripPrefix))
086 continue;
087
088 // Sometimes, people put the prefix directory in as a
089 // classpath entry; we ignore it (otherwise
090 // we get a IndexOutOfBoundsException
091
092 if (path.length() == stripPrefix.length())
093 continue;
094
095 if (needSep)
096 buffer.append(' ');
097
098 // Strip off the directory and the seperator, leaving
099 // just the relative path.
100
101 buffer.append(filter(path.substring(stripPrefix.length() + 1)));
102
103 needSep = true;
104
105 }
106 else
107 {
108 if (needSep)
109 buffer.append(' ');
110
111 File f = new File(path);
112
113 buffer.append(f.getName());
114
115 needSep = true;
116 }
117 }
118
119 getProject().setProperty(_property, buffer.toString());
120 }
121
122 public File getDirectory()
123 {
124 return _directory;
125 }
126
127 /**
128 * Sets a containing directory. This has two effects:
129 * <ul>
130 * <li>Only files in the classpath that are contained by the directory are included.
131 * <li>The directory path is stripped from each path, leaving a relative path
132 * to the file.
133 * </ul>
134 */
135 public void setDirectory(File file)
136 {
137 _directory = file;
138 }
139
140 /**
141 * Classpath entries must use a forward slash, regardless of what the
142 * local filesystem uses.
143 */
144 protected String filter(String value)
145 {
146 if (File.separatorChar == '/')
147 return value;
148
149 return value.replace(File.separatorChar, '/');
150 }
151 }