001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM - Initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.build.tasks;
011:
012: import java.io.*;
013: import org.apache.tools.ant.BuildException;
014: import org.apache.tools.ant.Task;
015:
016: /**
017: * Internal task.
018: * This task aims at replacing the generic ids used into a plugin.xml by another value.
019: * @since 3.0
020: */
021: public class PluginVersionReplaceTask extends Task {
022: private static final String PLUGIN_START_TAG = "<plugin"; //$NON-NLS-1$
023: private static final String FRAGMENT_START_TAG = "<fragment"; //$NON-NLS-1$
024: private static final String COMMENT_START_TAG = "<!--"; //$NON-NLS-1$
025: private static final String COMMENT_END_TAG = "-->"; //$NON-NLS-1$
026: private static final String VERSION = "version";//$NON-NLS-1$
027: private static final String BACKSLASH = "\""; //$NON-NLS-1$
028:
029: //Path of the file where we are replacing the values
030: private String pluginFilePath;
031: private boolean plugin = true;
032: private String newVersion;
033:
034: /**
035: * The location of a fragment.xml or plugin.xml file
036: * @param path
037: */
038: public void setPluginFilePath(String path) {
039: pluginFilePath = path;
040: }
041:
042: /**
043: * Set the new version.
044: * @param qualifier the version that will be set in the manifest file.
045: */
046: public void setVersionNumber(String qualifier) {
047: newVersion = qualifier;
048: }
049:
050: /**
051: * Set the type of the file.
052: * @param input
053: */
054: public void setInput(String input) {
055: if (input.equalsIgnoreCase("fragment.xml")) //$NON-NLS-1$
056: plugin = false;
057: }
058:
059: public void execute() {
060: StringBuffer buffer = null;
061: try {
062: buffer = readFile(new File(pluginFilePath));
063: } catch (IOException e) {
064: throw new BuildException(e);
065: }
066:
067: //Find the word plugin or fragment
068: int startPlugin = scan(buffer, 0, plugin ? PLUGIN_START_TAG
069: : FRAGMENT_START_TAG);
070: int startComment = scan(buffer, 0, COMMENT_START_TAG);
071: int endComment = startComment > -1 ? scan(buffer, startComment,
072: COMMENT_END_TAG) : -1;
073:
074: while (startComment != -1 && startPlugin > startComment
075: && startPlugin < endComment) {
076: startPlugin = scan(buffer, endComment,
077: plugin ? PLUGIN_START_TAG : FRAGMENT_START_TAG);
078: startComment = scan(buffer, endComment, COMMENT_START_TAG);
079: endComment = startComment > -1 ? scan(buffer, startComment,
080: COMMENT_END_TAG) : -1;
081: }
082:
083: if (startPlugin == -1)
084: return;
085:
086: int endPlugin = scan(buffer, startPlugin + 1, ">"); //$NON-NLS-1$
087:
088: //Find the version tag in the plugin header
089: boolean versionFound = false;
090: while (!versionFound) {
091: int versionAttr = scan(buffer, startPlugin, VERSION);
092: if (versionAttr == -1 || versionAttr > endPlugin)
093: return;
094: if (!Character.isWhitespace(buffer.charAt(versionAttr - 1))) {
095: startPlugin = versionAttr + VERSION.length();
096: continue;
097: }
098: //Verify that the word version found is the actual attribute
099: int endVersionWord = versionAttr + VERSION.length();
100: while (Character
101: .isWhitespace(buffer.charAt(endVersionWord))
102: && endVersionWord < endPlugin) {
103: endVersionWord++;
104: }
105: if (endVersionWord > endPlugin) //version has not been found
106: return;
107:
108: if (buffer.charAt(endVersionWord) != '=') {
109: startPlugin = endVersionWord;
110: continue;
111: }
112:
113: //Version has been found, extract the version id and replace it
114: int startVersionId = scan(buffer, versionAttr + 1,
115: BACKSLASH);
116: int endVersionId = scan(buffer, startVersionId + 1,
117: BACKSLASH);
118:
119: buffer
120: .replace(startVersionId + 1, endVersionId,
121: newVersion);
122: versionFound = true;
123: }
124: try {
125: OutputStreamWriter w = new OutputStreamWriter(
126: new BufferedOutputStream(new FileOutputStream(
127: pluginFilePath)), "UTF-8"); //$NON-NLS-1$
128: w.write(buffer.toString());
129: w.close();
130: } catch (FileNotFoundException e) {
131: // ignore
132: } catch (IOException e) {
133: throw new BuildException(e);
134: }
135: }
136:
137: private int scan(StringBuffer buf, int start, String targetName) {
138: return scan(buf, start, new String[] { targetName });
139: }
140:
141: private int scan(StringBuffer buf, int start, String[] targets) {
142: for (int i = start; i < buf.length(); i++) {
143: for (int j = 0; j < targets.length; j++) {
144: if (i < buf.length() - targets[j].length()) {
145: String match = buf.substring(i, i
146: + targets[j].length());
147: if (targets[j].equalsIgnoreCase(match))
148: return i;
149: }
150: }
151: }
152: return -1;
153: }
154:
155: private StringBuffer readFile(File targetName) throws IOException {
156: InputStreamReader reader = new InputStreamReader(
157: new BufferedInputStream(new FileInputStream(targetName)),
158: "UTF-8"); //$NON-NLS-1$
159: StringBuffer result = new StringBuffer();
160: char[] buf = new char[4096];
161: int count;
162: try {
163: count = reader.read(buf, 0, buf.length);
164: while (count != -1) {
165: result.append(buf, 0, count);
166: count = reader.read(buf, 0, buf.length);
167: }
168: } finally {
169: try {
170: reader.close();
171: } catch (IOException e) {
172: // ignore exceptions here
173: }
174: }
175: return result;
176: }
177: }
|