1 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 23 public class IdReplaceTask extends Task { 24 private static final String UTF_8 = "UTF-8"; private static final String FEATURE_START_TAG = "<feature"; private static final String ID = "id"; private static final String VERSION = "version"; private static final String COMMA = ","; private static final String BACKSLASH = "\""; private static final String EMPTY = ""; private static final String PLUGIN_START_TAG = "<plugin"; private static final String INCLUDES_START_TAG = "<includes"; private static final String COMMENT_START_TAG = "<!--"; private static final String COMMENT_END_TAG = "-->"; 36 private String featureFilePath; 38 private Map pluginIds = new HashMap(10); 42 private Map featureIds = new HashMap(4); 46 private String selfVersion; 48 49 private boolean contentChanged = false; 50 51 private final static String GENERIC_VERSION_NUMBER = "0.0.0"; private final static String QUALIFIER = "qualifier"; 54 58 public void setFeatureFilePath(String path) { 59 featureFilePath = path; 60 } 61 62 66 public void setSelfVersion(String version) { 67 selfVersion = version; 68 } 69 70 77 public void setPluginIds(String values) { 78 pluginIds = new HashMap(10); 79 for (StringTokenizer tokens = new StringTokenizer(values, COMMA); tokens.hasMoreTokens();) { 80 String token = tokens.nextToken().trim(); 81 String id = EMPTY; 82 if (!token.equals(EMPTY)) 83 id = token; 84 85 String version = EMPTY; 86 token = tokens.nextToken().trim(); 87 if (!token.equals(EMPTY)) 88 version = token; 89 pluginIds.put(id, version); 90 } 91 } 92 93 99 public void setFeatureIds(String values) { 100 featureIds = new HashMap(10); 101 for (StringTokenizer tokens = new StringTokenizer(values, COMMA); tokens.hasMoreTokens();) { 102 String token = tokens.nextToken().trim(); 103 String id = EMPTY; 104 if (!token.equals(EMPTY)) 105 id = token; 106 107 String 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 buffer = null; 117 try { 118 buffer = readFile(new File(featureFilePath)); 119 } catch (IOException e) { 120 throw new BuildException(e); 121 } 122 123 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, ">"); 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 int endVersionWord = startVersionWord + VERSION.length(); 151 while (Character.isWhitespace(buffer.charAt(endVersionWord)) && endVersionWord < endFeature) { 152 endVersionWord++; 153 } 154 if (endVersionWord > endFeature) { System.err.println("Could not find the tag 'version' in the feature header, file: " + featureFilePath); 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 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 if (startId < startVersionWord) { 214 startElementId = scan(buffer, startId + 1, BACKSLASH); 215 endElementId = scan(buffer, startElementId + 1, BACKSLASH); 216 217 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 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 (versionId).equals(GENERIC_VERSION_NUMBER) && !new String (versionId).endsWith(QUALIFIER)) { 241 startElement = startVersionId; 242 continue; 243 } 244 245 startVersionId++; 246 String replacementVersion = null; 247 Version v = new Version(new String (versionId)); 248 String lookupKey = new String (elementId) + ':' + v.getMajor() + '.' + v.getMinor() + '.' + v.getMicro(); 249 if (isPlugin) { 250 replacementVersion = (String ) pluginIds.get(lookupKey); 251 } else { 252 replacementVersion = (String ) featureIds.get(lookupKey); 253 } 254 int change = 0; 255 if (replacementVersion == null) { 256 System.err.println("Could not find " + new String (elementId)); } 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 } catch (IOException e) { 275 throw new BuildException(e); 276 } 277 } 278 279 private int scan(StringBuffer buf, int start, String targetName) { 280 return scan(buf, start, new String [] {targetName}); 281 } 282 283 private int scan(StringBuffer buf, int start, String [] 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 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 readFile(File targetName) throws IOException { 297 InputStreamReader reader = new InputStreamReader(new BufferedInputStream(new FileInputStream(targetName)), UTF_8); 298 StringBuffer result = new StringBuffer (); 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 } 313 } 314 return result; 315 } 316 } 317 | Popular Tags |