KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > build > tasks > IdReplaceTask


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM - Initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.pde.internal.build.tasks;
12
13 import java.io.*;
14 import java.util.*;
15 import org.apache.tools.ant.BuildException;
16 import org.apache.tools.ant.Task;
17
18 /**
19  * Internal task.
20  * This task aims at replacing the generic ids used into a feature.xml by another value, and also replace the feature version number if necessary.
21  * @since 3.0
22  */

23 public class IdReplaceTask extends Task {
24     private static final String JavaDoc UTF_8 = "UTF-8"; //$NON-NLS-1$
25
private static final String JavaDoc FEATURE_START_TAG = "<feature";//$NON-NLS-1$
26
private static final String JavaDoc ID = "id";//$NON-NLS-1$
27
private static final String JavaDoc VERSION = "version";//$NON-NLS-1$
28
private static final String JavaDoc COMMA = ","; //$NON-NLS-1$
29
private static final String JavaDoc BACKSLASH = "\""; //$NON-NLS-1$
30
private static final String JavaDoc EMPTY = ""; //$NON-NLS-1$
31
private static final String JavaDoc PLUGIN_START_TAG = "<plugin"; //$NON-NLS-1$
32
private static final String JavaDoc INCLUDES_START_TAG = "<includes"; //$NON-NLS-1$
33
private static final String JavaDoc COMMENT_START_TAG = "<!--"; //$NON-NLS-1$
34
private static final String JavaDoc COMMENT_END_TAG = "-->"; //$NON-NLS-1$
35

36     //Path of the file where we are replacing the values
37
private String JavaDoc featureFilePath;
38     //Map of the plugin ids and version (key) and their version number (value)
39
// the key is id:version and the value is the actual version of the element
40
// the keys are such that a regular lookup will always return the appropriate value if available
41
private Map pluginIds = new HashMap(10);
42     //Map of the feature ids and version (key) and their version number (value)
43
// the key is id:version and the value is the actual version of the element
44
// the keys are such that a regular lookup will always return the appropriate value if available
45
private Map featureIds = new HashMap(4);
46     //The new version number for this feature
47
private String JavaDoc selfVersion;
48
49     private boolean contentChanged = false;
50
51     private final static String JavaDoc GENERIC_VERSION_NUMBER = "0.0.0"; //$NON-NLS-1$
52
private final static String JavaDoc QUALIFIER = "qualifier"; //$NON-NLS-1$
53

54     /**
55      * The location of a feature.xml file
56      * @param path
57      */

58     public void setFeatureFilePath(String JavaDoc path) {
59         featureFilePath = path;
60     }
61
62     /**
63      * The value with which the current version of the feature will be replaced.
64      * @param version
65      */

66     public void setSelfVersion(String JavaDoc version) {
67         selfVersion = version;
68     }
69
70     /**
71      * Set the values to use when replacing a generic value used in a plugin reference.
72      * Note all the pluginIds that have a generic number into the feature.xml must be
73      * listed in <param>values</param>.
74      * @param values a comma separated list alternating pluginId and versionNumber.
75      * For example: org.eclipse.pde.build,2.1.0,org.eclipse.core.resources,1.2.0
76      */

77     public void setPluginIds(String JavaDoc values) {
78         pluginIds = new HashMap(10);
79         for (StringTokenizer tokens = new StringTokenizer(values, COMMA); tokens.hasMoreTokens();) {
80             String JavaDoc token = tokens.nextToken().trim();
81             String JavaDoc id = EMPTY;
82             if (!token.equals(EMPTY))
83                 id = token;
84
85             String JavaDoc version = EMPTY;
86             token = tokens.nextToken().trim();
87             if (!token.equals(EMPTY))
88                 version = token;
89             pluginIds.put(id, version);
90         }
91     }
92
93     /**
94      * Set the values to use when replacing a generic value used in a feature reference
95      * Note that all the featureIds that have a generic number into the feature.xml must
96      * be liste in <param>values</param>.
97      * @param values
98      */

99     public void setFeatureIds(String JavaDoc values) {
100         featureIds = new HashMap(10);
101         for (StringTokenizer tokens = new StringTokenizer(values, COMMA); tokens.hasMoreTokens();) {
102             String JavaDoc token = tokens.nextToken().trim();
103             String JavaDoc id = EMPTY;
104             if (!token.equals(EMPTY))
105                 id = token;
106
107             String JavaDoc version = EMPTY;
108             token = tokens.nextToken().trim();
109             if (!token.equals(EMPTY))
110                 version = token;
111             featureIds.put(id, version);
112         }
113     }
114
115     public void execute() {
116         StringBuffer JavaDoc buffer = null;
117         try {
118             buffer = readFile(new File(featureFilePath));
119         } catch (IOException e) {
120             throw new BuildException(e);
121         }
122
123         //Skip feature declaration because it contains the word "plugin"
124
int startComment = scan(buffer, 0, COMMENT_START_TAG);
125         int endComment = startComment > -1 ? scan(buffer, startComment, COMMENT_END_TAG) : -1;
126         int startFeature = scan(buffer, 0, FEATURE_START_TAG);
127
128         while (startComment != -1 && startFeature > startComment && startFeature < endComment) {
129             startFeature = scan(buffer, endComment, FEATURE_START_TAG);
130             startComment = scan(buffer, endComment, COMMENT_START_TAG);
131             endComment = startComment > -1 ? scan(buffer, startComment, COMMENT_END_TAG) : -1;
132         }
133
134         if (startFeature == -1)
135             return;
136
137         int endFeature = scan(buffer, startFeature, ">"); //$NON-NLS-1$
138

139         if (selfVersion != null) {
140             boolean versionFound = false;
141             while (!versionFound) {
142                 int startVersionWord = scan(buffer, startFeature, VERSION);
143                 if (startVersionWord == -1 || startVersionWord > endFeature)
144                     return;
145                 if (!Character.isWhitespace(buffer.charAt(startVersionWord - 1))) {
146                     startFeature = startVersionWord + VERSION.length();
147                     continue;
148                 }
149                 //Verify that the word version found is the actual attribute
150
int endVersionWord = startVersionWord + VERSION.length();
151                 while (Character.isWhitespace(buffer.charAt(endVersionWord)) && endVersionWord < endFeature) {
152                     endVersionWord++;
153                 }
154                 if (endVersionWord > endFeature) { //version has not been found
155
System.err.println("Could not find the tag 'version' in the feature header, file: " + featureFilePath); //$NON-NLS-1$
156
return;
157                 }
158
159                 if (buffer.charAt(endVersionWord) != '=') {
160                     startFeature = endVersionWord;
161                     continue;
162                 }
163
164                 int startVersionId = scan(buffer, startVersionWord + 1, BACKSLASH);
165                 int endVersionId = scan(buffer, startVersionId + 1, BACKSLASH);
166                 buffer.replace(startVersionId + 1, endVersionId, selfVersion);
167                 endFeature = endFeature + (selfVersion.length() - (endVersionId - startVersionId));
168                 contentChanged = true;
169                 versionFound = true;
170             }
171         }
172
173         int startElement = endFeature;
174         int startId = 0;
175         while (true) {
176             int startPlugin = scan(buffer, startElement + 1, PLUGIN_START_TAG);
177             int startInclude = scan(buffer, startElement + 1, INCLUDES_START_TAG);
178
179             if (startPlugin == -1 && startInclude == -1)
180                 break;
181
182             startComment = scan(buffer, startElement + 1, COMMENT_START_TAG);
183             endComment = startComment > -1 ? scan(buffer, startComment, COMMENT_END_TAG) : -1;
184
185             int foundElement = -1;
186             boolean isPlugin = false;
187
188             //Find which of a plugin or a feature is referenced first
189
if (startPlugin == -1 || startInclude == -1) {
190                 foundElement = startPlugin != -1 ? startPlugin : startInclude;
191                 isPlugin = (startPlugin != -1 ? true : false);
192             } else {
193                 if (startPlugin < startInclude) {
194                     foundElement = startPlugin;
195                     isPlugin = true;
196                 } else {
197                     foundElement = startInclude;
198                     isPlugin = false;
199                 }
200             }
201
202             if (startComment != -1 && foundElement > startComment && foundElement < endComment) {
203                 startElement = endComment;
204                 continue;
205             }
206
207             int startElementId, endElementId;
208             int startVersionWord, startVersionId, endVersionId;
209
210             startId = scan(buffer, foundElement, ID);
211             startVersionWord = scan(buffer, foundElement, VERSION);
212             // Which comes first, version or id.
213
if (startId < startVersionWord) {
214                 startElementId = scan(buffer, startId + 1, BACKSLASH);
215                 endElementId = scan(buffer, startElementId + 1, BACKSLASH);
216
217                 // search for version again since the id could have "version" in it.
218
startVersionWord = scan(buffer, endElementId + 1, VERSION);
219                 startVersionId = scan(buffer, startVersionWord + 1, BACKSLASH);
220                 endVersionId = scan(buffer, startVersionId + 1, BACKSLASH);
221             } else {
222                 startVersionId = scan(buffer, startVersionWord + 1, BACKSLASH);
223                 endVersionId = scan(buffer, startVersionId + 1, BACKSLASH);
224
225                 // search for id again since the version qualifier could contain "id"
226
startId = scan(buffer, endVersionId + 1, ID);
227                 startElementId = scan(buffer, startId + 1, BACKSLASH);
228                 endElementId = scan(buffer, startElementId + 1, BACKSLASH);
229             }
230
231             if (startId == -1 || startVersionWord == -1)
232                 break;
233
234             char[] elementId = new char[endElementId - startElementId - 1];
235             buffer.getChars(startElementId + 1, endElementId, elementId, 0);
236
237             char[] versionId = new char[endVersionId - startVersionId - 1];
238             buffer.getChars(startVersionId + 1, endVersionId, versionId, 0);
239             
240             if (!new String JavaDoc(versionId).equals(GENERIC_VERSION_NUMBER) && !new String JavaDoc(versionId).endsWith(QUALIFIER)) {
241                 startElement = startVersionId;
242                 continue;
243             }
244
245             startVersionId++;
246             String JavaDoc replacementVersion = null;
247             Version v = new Version(new String JavaDoc(versionId));
248             String JavaDoc lookupKey = new String JavaDoc(elementId) + ':' + v.getMajor() + '.' + v.getMinor() + '.' + v.getMicro();
249             if (isPlugin) {
250                 replacementVersion = (String JavaDoc) pluginIds.get(lookupKey);
251             } else {
252                 replacementVersion = (String JavaDoc) featureIds.get(lookupKey);
253             }
254             int change = 0;
255             if (replacementVersion == null) {
256                 System.err.println("Could not find " + new String JavaDoc(elementId)); //$NON-NLS-1$
257
} else {
258                 buffer.replace(startVersionId, endVersionId, replacementVersion);
259                 contentChanged = true;
260                 change = endVersionId - startVersionId - replacementVersion.length();
261             }
262             startElement = (endElementId > endVersionId) ? endElementId - change: endVersionId - change;
263         }
264
265         if (!contentChanged)
266             return;
267
268         try {
269             OutputStreamWriter w = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(featureFilePath)), UTF_8);
270             w.write(buffer.toString());
271             w.close();
272         } catch (FileNotFoundException e) {
273             // ignore
274
} catch (IOException e) {
275             throw new BuildException(e);
276         }
277     }
278
279     private int scan(StringBuffer JavaDoc buf, int start, String JavaDoc targetName) {
280         return scan(buf, start, new String JavaDoc[] {targetName});
281     }
282
283     private int scan(StringBuffer JavaDoc buf, int start, String JavaDoc[] targets) {
284         for (int i = start; i < buf.length(); i++) {
285             for (int j = 0; j < targets.length; j++) {
286                 if (i < buf.length() - targets[j].length()) {
287                     String JavaDoc match = buf.substring(i, i + targets[j].length());
288                     if (targets[j].equalsIgnoreCase(match))
289                         return i;
290                 }
291             }
292         }
293         return -1;
294     }
295
296     private StringBuffer JavaDoc readFile(File targetName) throws IOException {
297         InputStreamReader reader = new InputStreamReader(new BufferedInputStream(new FileInputStream(targetName)), UTF_8);
298         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
299         char[] buf = new char[4096];
300         int count;
301         try {
302             count = reader.read(buf, 0, buf.length);
303             while (count != -1) {
304                 result.append(buf, 0, count);
305                 count = reader.read(buf, 0, buf.length);
306             }
307         } finally {
308             try {
309                 reader.close();
310             } catch (IOException e) {
311                 // ignore exceptions here
312
}
313         }
314         return result;
315     }
316 }
317
Popular Tags