KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > ManifestClassPath


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18 package org.apache.tools.ant.taskdefs;
19
20 import java.io.File JavaDoc;
21 import java.io.UnsupportedEncodingException JavaDoc;
22
23 import org.apache.tools.ant.Task;
24 import org.apache.tools.ant.types.Path;
25 import org.apache.tools.ant.BuildException;
26 import org.apache.tools.ant.launch.Locator;
27 import org.apache.tools.ant.util.FileUtils;
28
29 /**
30  * Converts a Path into a property suitable as a Manifest classpath.
31  *
32  * @since Ant 1.7
33  *
34  * @ant.task category="property"
35  */

36 public class ManifestClassPath extends Task {
37
38     /** The property name to hold the classpath value. */
39     private String JavaDoc name;
40
41     /** The directory the classpath will be relative from. */
42     private File JavaDoc dir;
43
44     /** The maximum parent directory level to traverse. */
45     private int maxParentLevels = 2;
46
47     /** The classpath to convert. */
48     private Path path;
49
50     /**
51      * Sets a property, which must not already exist, with a space
52      * separated list of files and directories relative to the jar
53      * file's parent directory.
54      */

55     public void execute() {
56         if (name == null) {
57           throw new BuildException("Missing 'property' attribute!");
58         }
59         if (dir == null) {
60           throw new BuildException("Missing 'jarfile' attribute!");
61         }
62         if (getProject().getProperty(name) != null) {
63           throw new BuildException("Property '" + name + "' already set!");
64         }
65         if (path == null) {
66             throw new BuildException("Missing nested <classpath>!");
67         }
68
69         // Normalize the reference directory (containing the jar)
70
final FileUtils fileUtils = FileUtils.getFileUtils();
71         dir = fileUtils.normalize(dir.getAbsolutePath());
72
73         // Create as many directory prefixes as parent levels to traverse,
74
// in addition to the reference directory itself
75
File JavaDoc currDir = dir;
76         String JavaDoc[] dirs = new String JavaDoc[maxParentLevels + 1];
77         for (int i = 0; i < maxParentLevels + 1; ++i) {
78             dirs[i] = currDir.getAbsolutePath() + File.separatorChar;
79             currDir = currDir.getParentFile();
80             if (currDir == null) {
81                 maxParentLevels = i + 1;
82                 break;
83             }
84         }
85
86         String JavaDoc[] elements = path.list();
87         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
88         StringBuffer JavaDoc element = new StringBuffer JavaDoc();
89         for (int i = 0; i < elements.length; ++i) {
90             // Normalize the current file
91
File JavaDoc pathEntry = new File JavaDoc(elements[i]);
92             pathEntry = fileUtils.normalize(pathEntry.getAbsolutePath());
93             String JavaDoc fullPath = pathEntry.getAbsolutePath();
94
95             // Find the longest prefix shared by the current file
96
// and the reference directory.
97
String JavaDoc relPath = null;
98             for (int j = 0; j <= maxParentLevels; ++j) {
99                 String JavaDoc dir = dirs[j];
100                 if (!fullPath.startsWith(dir)) {
101                     continue;
102                 }
103
104                 // We have a match! Add as many ../ as parent
105
// directory traversed to get the relative path
106
element.setLength(0);
107                 for (int k = 0; k < j; ++k) {
108                     element.append("..");
109                     element.append(File.separatorChar);
110                 }
111                 element.append(fullPath.substring(dir.length()));
112                 relPath = element.toString();
113                 break;
114             }
115
116             // No match, so bail out!
117
if (relPath == null) {
118                 throw new BuildException(
119                     "No suitable relative path from "
120                     + dir + " to " + fullPath);
121             }
122
123             // Manifest's ClassPath: attribute always uses forward
124
// slashes '/', and is space-separated. Ant will properly
125
// format it on 72 columns with proper line continuation
126
if (File.separatorChar != '/') {
127                 relPath = relPath.replace(File.separatorChar, '/');
128             }
129             if (pathEntry.isDirectory()) {
130                 relPath = relPath + '/';
131             }
132             try {
133                 relPath = Locator.encodeURI(relPath);
134             } catch (UnsupportedEncodingException JavaDoc exc) {
135                 throw new BuildException(exc);
136             }
137             buffer.append(relPath);
138             buffer.append(' ');
139         }
140
141         // Finally assign the property with the manifest classpath
142
getProject().setNewProperty(name, buffer.toString().trim());
143     }
144
145     /**
146      * Sets the property name to hold the classpath value.
147      *
148      * @param name the property name
149      */

150     public void setProperty(String JavaDoc name) {
151         this.name = name;
152     }
153
154     /**
155      * The JAR file to contain the classpath attribute in its manifest.
156      *
157      * @param jarfile the JAR file. Need not exist yet, but its parent
158      * directory must exist on the other hand.
159      */

160     public void setJarFile(File JavaDoc jarfile) {
161         File JavaDoc parent = jarfile.getParentFile();
162         if (!parent.isDirectory()) {
163             throw new BuildException("Jar's directory not found: " + parent);
164         }
165         this.dir = parent;
166     }
167
168     /**
169      * Sets the maximum parent directory levels allowed when computing
170      * a relative path.
171      *
172      * @param levels the max level. Defaults to 2.
173      */

174     public void setMaxParentLevels(int levels) {
175         this.maxParentLevels = levels;
176     }
177
178     /**
179      * Adds the classpath to convert.
180      *
181      * @param path the classpath to convert.
182      */

183     public void addClassPath(Path path) {
184         this.path = path;
185     }
186
187 }
188
Popular Tags