001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018: package org.apache.tools.ant.taskdefs;
019:
020: import org.apache.tools.ant.BuildException;
021: import org.apache.tools.ant.Project;
022: import org.apache.tools.ant.Task;
023: import org.apache.tools.ant.DirectoryScanner;
024: import org.apache.tools.ant.util.FileUtils;
025: import org.apache.tools.ant.types.FileSet;
026: import org.apache.tools.ant.types.Path;
027:
028: import java.io.File;
029: import java.util.List;
030: import java.util.LinkedList;
031: import java.util.ListIterator;
032:
033: /**
034: * This task takes file and turns them into a URL, which it then assigns
035: * to a property. Use when for setting up RMI codebases.
036: * <p/>
037: * nested filesets are supported; if present, these are turned into the
038: * url with the given separator between them (default = " ").
039: *
040: * @ant.task category="core" name="makeurl"
041: */
042:
043: public class MakeUrl extends Task {
044:
045: /**
046: * name of the property to set
047: */
048: private String property;
049:
050: /**
051: * name of a file to turn into a URL
052: */
053: private File file;
054:
055: /**
056: * separator char
057: */
058: private String separator = " ";
059:
060: /**
061: * filesets of nested files to add to this url
062: */
063: private List filesets = new LinkedList();
064:
065: /**
066: * paths to add
067: */
068: private List paths = new LinkedList();
069:
070: /**
071: * validation flag
072: */
073: private boolean validate = true;
074:
075: // error message strings
076: /** Missing file */
077: public static final String ERROR_MISSING_FILE = "A source file is missing :";
078: /** No property defined */
079: public static final String ERROR_NO_PROPERTY = "No property defined";
080: /** No files defined */
081: public static final String ERROR_NO_FILES = "No files defined";
082:
083: /**
084: * set the name of a property to fill with the URL
085: *
086: * @param property the name of the property.
087: */
088: public void setProperty(String property) {
089: this .property = property;
090: }
091:
092: /**
093: * the name of a file to be converted into a URL
094: *
095: * @param file the file to be converted.
096: */
097: public void setFile(File file) {
098: this .file = file;
099: }
100:
101: /**
102: * a fileset of jar files to include in the URL, each
103: * separated by the separator
104: *
105: * @param fileset the fileset to be added.
106: */
107: public void addFileSet(FileSet fileset) {
108: filesets.add(fileset);
109: }
110:
111: /**
112: * set the separator for the multi-url option.
113: *
114: * @param separator the separator to use.
115: */
116: public void setSeparator(String separator) {
117: this .separator = separator;
118: }
119:
120: /**
121: * set this flag to trigger validation that every named file exists.
122: * Optional: default=true
123: *
124: * @param validate a <code>boolean</code> value.
125: */
126: public void setValidate(boolean validate) {
127: this .validate = validate;
128: }
129:
130: /**
131: * add a path to the URL. All elements in the path
132: * will be converted to individual URL entries
133: *
134: * @param path a path value.
135: */
136: public void addPath(Path path) {
137: paths.add(path);
138: }
139:
140: /**
141: * convert the filesets to urls.
142: *
143: * @return null for no files
144: */
145: private String filesetsToURL() {
146: if (filesets.isEmpty()) {
147: return "";
148: }
149: int count = 0;
150: StringBuffer urls = new StringBuffer();
151: ListIterator list = filesets.listIterator();
152: while (list.hasNext()) {
153: FileSet set = (FileSet) list.next();
154: DirectoryScanner scanner = set
155: .getDirectoryScanner(getProject());
156: String[] files = scanner.getIncludedFiles();
157: for (int i = 0; i < files.length; i++) {
158: File f = new File(scanner.getBasedir(), files[i]);
159: validateFile(f);
160: String asUrl = toURL(f);
161: urls.append(asUrl);
162: log(asUrl, Project.MSG_DEBUG);
163: urls.append(separator);
164: count++;
165: }
166: }
167: //at this point there is one trailing space to remove, if the list is not empty.
168: return stripTrailingSeparator(urls, count);
169: }
170:
171: /**
172: * convert the string buffer to a string, potentially stripping
173: * out any trailing separator
174: *
175: * @param urls URL buffer
176: * @param count number of URL entries
177: * @return trimmed string, or empty string
178: */
179: private String stripTrailingSeparator(StringBuffer urls, int count) {
180: if (count > 0) {
181: urls.delete(urls.length() - separator.length(), urls
182: .length());
183: return new String(urls);
184: } else {
185: return "";
186: }
187: }
188:
189: /**
190: * convert all paths to URLs
191: *
192: * @return the paths as a separated list of URLs
193: */
194: private String pathsToURL() {
195: if (paths.isEmpty()) {
196: return "";
197: }
198: int count = 0;
199: StringBuffer urls = new StringBuffer();
200: ListIterator list = paths.listIterator();
201: while (list.hasNext()) {
202: Path path = (Path) list.next();
203: String[] elements = path.list();
204: for (int i = 0; i < elements.length; i++) {
205: File f = new File(elements[i]);
206: validateFile(f);
207: String asUrl = toURL(f);
208: urls.append(asUrl);
209: log(asUrl, Project.MSG_DEBUG);
210: urls.append(separator);
211: count++;
212: }
213: }
214: //at this point there is one trailing space to remove, if the list is not empty.
215: return stripTrailingSeparator(urls, count);
216: }
217:
218: /**
219: * verify that the file exists, if {@link #validate} is set
220: *
221: * @param fileToCheck file that may need to exist
222: * @throws BuildException with text beginning {@link #ERROR_MISSING_FILE}
223: */
224: private void validateFile(File fileToCheck) {
225: if (validate && !fileToCheck.exists()) {
226: throw new BuildException(ERROR_MISSING_FILE
227: + fileToCheck.toString());
228: }
229: }
230:
231: /**
232: * Create the url
233: *
234: * @throws org.apache.tools.ant.BuildException
235: * if something goes wrong with the build
236: */
237: public void execute() throws BuildException {
238: validate();
239: //now exit here if the property is already set
240: if (getProject().getProperty(property) != null) {
241: return;
242: }
243: String url;
244: String filesetURL = filesetsToURL();
245: if (file != null) {
246: validateFile(file);
247: url = toURL(file);
248: //and add any files if also defined
249: if (filesetURL.length() > 0) {
250: url = url + separator + filesetURL;
251: }
252: } else {
253: url = filesetURL;
254: }
255: //add path URLs
256: String pathURL = pathsToURL();
257: if (pathURL.length() > 0) {
258: if (url.length() > 0) {
259: url = url + separator + pathURL;
260: } else {
261: url = pathURL;
262: }
263: }
264: log("Setting " + property + " to URL " + url,
265: Project.MSG_VERBOSE);
266: getProject().setNewProperty(property, url);
267: }
268:
269: /**
270: * check for errors
271: * @throws BuildException if we are not configured right
272: */
273: private void validate() {
274: //validation
275: if (property == null) {
276: throw new BuildException(ERROR_NO_PROPERTY);
277: }
278: if (file == null && filesets.isEmpty() && paths.isEmpty()) {
279: throw new BuildException(ERROR_NO_FILES);
280: }
281: }
282:
283: /**
284: * convert a file to a URL;
285: *
286: * @param fileToConvert
287: * @return the file converted to a URL
288: */
289: private String toURL(File fileToConvert) {
290: String url;
291: //create the URL
292: //ant equivalent of fileToConvert.toURI().toURL().toExternalForm();
293: url = FileUtils.getFileUtils().toURI(
294: fileToConvert.getAbsolutePath());
295:
296: return url;
297: }
298:
299: }
|