1 19 20 package org.netbeans.nbbuild; 21 22 import java.io.File ; 23 import java.io.FileInputStream ; 24 import java.io.FileWriter ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.util.ArrayList ; 28 import java.util.List ; 29 import org.apache.tools.ant.BuildException; 30 import org.apache.tools.ant.FileScanner; 31 import org.apache.tools.ant.Project; 32 import org.apache.tools.ant.Task; 33 import org.apache.tools.ant.taskdefs.Ant; 34 import org.apache.tools.ant.types.FileSet; 35 import org.apache.tools.ant.util.FileUtils; 36 37 41 public class FixDependencies extends Task { 42 43 private List <Replace> replaces = new ArrayList <Replace>(); 44 45 private FileSet set; 46 47 private String target; 48 49 private String clean; 50 51 private String ant; 52 53 private boolean onlyChanged; 54 55 private boolean fail; 56 57 58 59 60 61 public FixDependencies() { 62 } 63 64 65 public Replace createReplace () { 66 Replace r = new Replace (); 67 replaces.add (r); 68 return r; 69 } 70 71 public FileSet createFileset() throws BuildException { 72 if (this.set != null) throw new BuildException ("Only one file set is allowed"); 73 this.set = new FileSet(); 74 return this.set; 75 } 76 77 public void setBuildTarget (String s) { 78 target = s; 79 } 80 81 public void setCleanTarget (String s) { 82 clean = s; 83 } 84 85 public void setAntFile (String r) { 86 ant = r; 87 } 88 89 public void setStripOnlyChanged (boolean b) { 90 onlyChanged = b; 91 } 92 93 public void setFailOnError (boolean b) { 94 fail = b; 95 } 96 97 public void execute () throws org.apache.tools.ant.BuildException { 98 FileScanner scan = this.set.getDirectoryScanner(getProject()); 99 File dir = scan.getBasedir(); 100 for (String kid : scan.getIncludedFiles()) { 101 File xml = new File (dir, kid); 102 if (!xml.exists()) throw new BuildException("File does not exist: " + xml, getLocation()); 103 104 log ("Fixing " + xml, Project.MSG_INFO); 105 106 File script = null; 107 Ant task = null; 108 Ant cleanTask = null; 109 if (ant != null && target != null) { 110 task = (org.apache.tools.ant.taskdefs.Ant)getProject ().createTask ("ant"); 111 script = FileUtils.getFileUtils().resolveFile(xml, ant); 112 if (!script.exists ()) { 113 String msg = "Skipping. Cannot find file " + ant + " from + " + xml; 114 if (fail) { 115 throw new BuildException (msg); 116 } 117 log(msg, Project.MSG_ERR); 118 continue; 119 } 120 task.setAntfile (script.getPath ()); 121 task.setDir (script.getParentFile ()); 122 task.setTarget (target); 123 if (clean != null) { 124 cleanTask = (Ant) getProject().createTask("ant"); 125 cleanTask.setAntfile (script.getPath ()); 126 cleanTask.setDir (script.getParentFile ()); 127 cleanTask.setTarget (clean); 128 } 129 130 try { 131 if (cleanTask != null) { 133 log ("Cleaning " + clean + " in " + script, org.apache.tools.ant.Project.MSG_INFO); 134 cleanTask.execute (); 135 } 136 log ("Sanity check executes " + target + " in " + script, org.apache.tools.ant.Project.MSG_INFO); 137 task.execute (); 138 } catch (BuildException ex) { 139 if (fail) { 140 throw ex; 141 } 142 143 log("Skipping. Could not execute " + target + " in " + script, org.apache.tools.ant.Project.MSG_ERR); 144 continue; 145 } 146 } 147 148 149 150 try { 151 boolean change = fix (xml); 152 if (onlyChanged && !change) { 153 continue; 154 } 155 simplify (xml, script, task, cleanTask); 156 } catch (IOException ex) { 157 throw new BuildException (ex, getLocation ()); 158 } 159 } 160 } 161 162 165 private boolean fix (File file) throws IOException , BuildException { 166 int s = (int)file.length (); 167 byte[] data = new byte[s]; 168 InputStream is = new FileInputStream (file); 169 if (s != is.read (data)) { 170 is.close (); 171 throw new BuildException ("Cannot read " + file); 172 } 173 is.close (); 174 175 String stream = new String (data); 176 String old = stream; 177 data = null; 178 179 for (Replace r : replaces) { 180 int idx = stream.indexOf ("<code-name-base>" + r.codeNameBase + "</code-name-base>"); 181 if (idx == -1) continue; 182 183 int from = stream.lastIndexOf ("<dependency>", idx); 184 if (from == -1) throw new BuildException ("No <dependency> tag before index " + idx); 185 int after = stream.indexOf ("</dependency>", idx); 186 if (after == -1) throw new BuildException ("No </dependency> tag after index " + idx); 187 after = findNonSpace (stream, after + "</dependency>".length ()); 188 189 String remove = stream.substring (from, after); 190 if (r.addCompileTime && remove.indexOf ("compile-dependency") == -1) { 191 int fromAfter = "<dependency>".length(); 192 int nonSpace = findNonSpace (remove, fromAfter); 193 String spaces = remove.substring (fromAfter, nonSpace); 194 remove = remove.substring (0, fromAfter) + spaces + "<compile-dependency/>" + remove.substring (fromAfter); 195 } 196 197 StringBuffer sb = new StringBuffer (); 198 sb.append (stream.substring (0, from)); 199 200 for (Module m : r.modules) { 201 if (stream.indexOf ("<code-name-base>" + m.codeNameBase + "</code-name-base>") != -1) { 202 continue; 203 } 204 205 int beg = remove.indexOf (r.codeNameBase); 206 int aft = beg + r.codeNameBase.length (); 207 sb.append (remove.substring (0, beg)); 208 sb.append (m.codeNameBase); 209 String a = remove.substring (aft); 210 if (m.specVersion != null) { 211 a = a.replaceAll ( 212 "<specification-version>[0-9\\.]*</specification-version>", 213 "<specification-version>" + m.specVersion + "</specification-version>" 214 ); 215 } 216 if (m.releaseVersion == null) { 217 a = a.replaceAll ( 218 "<release-version>[0-9]*</release-version>[\n\r ]*", 219 "" 220 ); 221 } 222 223 sb.append (a); 224 } 225 226 sb.append (stream.substring (after)); 227 228 stream = sb.toString (); 229 } 230 231 if (!old.equals (stream)) { 232 FileWriter fw = new FileWriter (file); 233 fw.write (stream); 234 fw.close (); 235 return true; 236 } else { 237 return false; 238 } 239 } 241 private void simplify ( 242 File file, File script, org.apache.tools.ant.taskdefs.Ant task, org.apache.tools.ant.taskdefs.Ant cleanTask 243 ) throws IOException , BuildException { 244 if (ant == null || target == null) { 245 return; 246 } 247 248 int s = (int)file.length (); 249 byte[] data = new byte[s]; 250 InputStream is = new FileInputStream (file); 251 if (s != is.read (data)) { 252 is.close (); 253 throw new BuildException ("Cannot read " + file); 254 } 255 is.close (); 256 257 String stream = new String (data); 258 String old = stream; 259 260 int first = -1; 261 int last = -1; 262 int begin = -1; 263 StringBuffer success = new StringBuffer (); 264 StringBuffer sb = new StringBuffer (); 265 for (;;) { 266 if (cleanTask != null) { 267 log ("Cleaning " + clean + " in " + script, Project.MSG_INFO); 268 cleanTask.execute (); 269 } 270 271 int from = stream.indexOf ("<dependency>", begin); 272 if (from == -1) { 273 break; 274 } 275 276 if (first == -1) { 277 first = from; 278 } 279 280 int after = stream.indexOf ("</dependency>", from); 281 if (after == -1) throw new BuildException ("No </dependency> tag after index " + from); 282 after = findNonSpace (stream, after + "</dependency>".length ()); 283 284 last = after; 285 begin = last; 286 287 FileWriter fw = new FileWriter (file); 289 fw.write (stream.substring (0, from) + stream.substring (after)); 290 fw.close (); 291 292 String dep = stream.substring (from, after); 293 if (dep.indexOf ("compile-dependency") == -1) { 294 sb.append (stream.substring (from, after)); 296 continue; 297 } 298 299 300 int cnbBeg = dep.indexOf ("<code-name-base>"); 301 int cnbEnd = dep.indexOf ("</code-name-base>"); 302 if (cnbBeg != -1 && cnbEnd != -1) { 303 dep = dep.substring (cnbBeg + "<code-name-base>".length (), cnbEnd); 304 } 305 306 307 String result; 308 try { 309 log ("Executing target " + target + " in " + script, Project.MSG_INFO); 310 task.execute (); 311 result = "Ok"; 312 success.append (dep); 313 success.append ("\n"); 314 } catch (BuildException ex) { 315 result = "Failure"; 316 sb.append (stream.substring (from, after)); 318 } 319 log ("Removing dependency " + dep + ": " + result, Project.MSG_INFO); 320 321 } 322 323 if (first != -1) { 324 FileWriter fw = new FileWriter (file); 326 fw.write (stream.substring (0, first) + sb.toString () + stream.substring (last)); 327 fw.close (); 328 } 329 330 log ("Final verification runs " + target + " in " + script, Project.MSG_INFO); 331 task.execute (); 333 334 if (success.length () == 0) { 335 log ("No dependencies removed from " + script); 336 } else { 337 log ("Removed dependencies from " + script + ":\n" + success); 338 } 339 } 341 private static int findNonSpace (String where, int from) { 342 while (from < where.length () && Character.isWhitespace (where.charAt (from))) { 343 from++; 344 } 345 return from; 346 } 347 348 public static final class Replace extends Object { 349 String codeNameBase; 350 List <Module> modules = new ArrayList <Module>(); 351 boolean addCompileTime; 352 353 public void setCodeNameBase (String s) { 354 codeNameBase = s; 355 } 356 357 public void setAddCompileTime (boolean b) { 358 addCompileTime = b; 359 } 360 361 public Module createModule () { 362 Module m = new Module (); 363 modules.add (m); 364 return m; 365 } 366 367 } 368 369 public static final class Module extends Object { 370 String codeNameBase; 371 String specVersion; 372 String releaseVersion; 373 374 public void setCodeNameBase (String s) { 375 codeNameBase = s; 376 } 377 378 379 public void setSpec (String s) { 380 specVersion = s; 381 } 382 383 public void setRelease (String r) { 384 releaseVersion = r; 385 } 386 } 387 } 388 | Popular Tags |