1 19 20 package org.netbeans.nbbuild; 21 22 import java.io.BufferedReader ; 23 import java.io.File ; 24 import java.io.FileInputStream ; 25 import java.io.FileOutputStream ; 26 import java.io.FileReader ; 27 import java.io.IOException ; 28 import java.util.ArrayList ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 import java.util.regex.Matcher ; 32 import java.util.regex.Pattern ; 33 34 import org.apache.tools.ant.BuildException; 35 import org.apache.tools.ant.FileScanner; 36 import org.apache.tools.ant.Project; 37 import org.apache.tools.ant.Task; 38 import org.apache.tools.ant.types.FileSet; 39 40 43 public class CheckLicense extends Task { 44 45 private final List <FileSet> filesets = new ArrayList <FileSet>(1); 46 private String fragment; 47 private List <Convert> fragments; 48 private FailType fail; 49 50 53 public void addFileSet (FileSet fs) { 54 filesets.add (fs); 55 } 56 57 60 public void addCvsFileSet(CvsFileSet fs) { 61 filesets.add(fs); 62 } 63 64 68 public void setFragment (String f) { 69 fragment = f; 70 } 71 72 public void setFail(FailType t) { 73 fail = t; 74 } 75 76 public Convert createConvert() { 77 Convert f = new Convert(); 78 if (fragments == null) { 79 fragments = new ArrayList <Convert>(); 80 } 81 82 fragments.add(f); 83 return f; 84 } 85 86 public void execute () throws BuildException { 87 if (fragment == null) { 88 if (fragments == null) { 89 throw new BuildException("You must supply a fragment", getLocation()); 90 } 91 92 executeReplace(); 93 return; 94 } 95 if (filesets.isEmpty ()) throw new BuildException("You must supply at least one fileset", getLocation()); 96 Iterator it = filesets.iterator (); 97 String failMsg = null; 98 try { 99 while (it.hasNext ()) { 100 FileScanner scanner = ((FileSet) it.next()).getDirectoryScanner(getProject()); 101 File baseDir = scanner.getBasedir (); 102 String [] files = scanner.getIncludedFiles (); 103 log ("Looking for " + fragment + " in " + files.length + " files in " + baseDir.getAbsolutePath ()); 104 for (int i = 0; i < files.length; i++) { 105 File f = new File (baseDir, files[i]); 106 BufferedReader br = new BufferedReader (new FileReader (f)); 108 try { 109 String line; 110 while ((line = br.readLine ()) != null) { 111 if (line.indexOf (fragment) != -1) { 112 if (fail != null && "whenpresent".equals(fail.getValue())) { 114 if (failMsg != null) { 115 log(failMsg, Project.MSG_ERR); 116 } 117 failMsg = "License found in " + f; 118 } 119 break; 120 } 121 } 122 if (line == null) { 123 String msg = f.getAbsolutePath () + ":1: no license notice found"; 124 if (fail != null && "whenmissing".equals(fail.getValue())) { 125 throw new BuildException(msg); 126 } 127 if (fail == null) { 128 log (msg, Project.MSG_ERR); 130 } 131 } 132 } finally { 133 br.close (); 134 } 135 } 136 } 137 138 if (failMsg != null) { 139 throw new BuildException(failMsg); 140 } 141 142 } catch (IOException ioe) { 143 throw new BuildException("Could not open files to check licenses", ioe, getLocation()); 144 } 145 } 146 147 private void executeReplace() throws BuildException { 148 Iterator it = filesets.iterator (); 149 try { 150 byte[] workingArray = new byte[1024]; 151 while (it.hasNext ()) { 152 FileScanner scanner = ((FileSet) it.next()).getDirectoryScanner(getProject()); 153 File baseDir = scanner.getBasedir (); 154 String [] files = scanner.getIncludedFiles (); 155 log ("Replacing code in " + files.length + " files in " + baseDir.getAbsolutePath ()); 156 for (int i = 0; i < files.length; i++) { 157 File file = new File (baseDir, files[i]); 158 log("Processing " + file, Project.MSG_VERBOSE); 159 FileInputStream is = new FileInputStream (file); 160 int workingLength = is.read(workingArray); 161 if (workingLength == -1) { 162 continue; 163 } 164 String workingString = new String (workingArray, 0, workingLength); 165 boolean changed = false; 166 String prefix = null; 167 168 Iterator frags = fragments.iterator(); 169 while (frags.hasNext()) { 170 Convert f = (Convert)frags.next(); 171 172 Matcher matcher = f.orig.matcher(workingString); 173 174 while (matcher.find()) { 175 if (f.prefix) { 176 if (prefix != null) { 177 throw new BuildException("Only one convert element can be prefix!"); 178 } 179 if (matcher.groupCount() != 1) { 180 throw new BuildException("There should be one group for the prefix element. Was: " + matcher.groupCount()); 181 } 182 prefix = matcher.group(1); 183 } 184 185 String before = workingString.substring(0, matcher.start()); 186 String after = workingString.substring(matcher.end()); 187 String middle = wrapWithPrefix(f.repl, prefix, before.length() == 0 || before.endsWith("\n")); 188 189 if (!middle.equals(matcher.group(0))) { 190 workingString = before + middle + after; 191 log("Matched " + middle, Project.MSG_VERBOSE); 192 changed = true; 193 } else { 194 log("Matched, but no change: " + middle, Project.MSG_VERBOSE); 195 } 196 197 if (!f.all) { 198 break; 199 } else { 200 matcher = f.orig.matcher(workingString); 201 } 202 } 203 } 204 205 byte[] rest = null; 206 if (is.available() > 0 && changed) { 207 rest = new byte[is.available()]; 208 int read = is.read(rest); 209 assert read == rest.length; 210 } 211 212 is.close(); 213 214 215 if (changed) { 216 log ("Rewriting " + file); 217 FileOutputStream os = new FileOutputStream (file); 218 workingString = Pattern.compile(" +$", Pattern.MULTILINE).matcher(workingString+"X").replaceAll(""); 219 os.write(workingString.substring(0, workingString.length() - 1).getBytes()); 220 if (rest != null) { 221 os.write(rest); 222 } 223 os.close(); 224 } 225 } 226 } 227 } catch (IOException ioe) { 228 throw new BuildException("Could not open files to check licenses", ioe, getLocation()); 229 } 230 } 231 232 private String wrapWithPrefix(String repl, String prefix, boolean startWithPrefix) { 233 if (prefix == null) { 234 return repl; 235 } 236 237 String [] all = repl.split("\n"); 238 StringBuffer sb = new StringBuffer (); 239 for (int i = 0; i < all.length; i++) { 240 if (startWithPrefix) { 241 sb.append(prefix); 242 } 243 sb.append(all[i]); 244 if (i < all.length - 1) { 245 sb.append('\n'); 246 } 247 startWithPrefix = true; 248 } 249 250 return sb.toString(); 251 } 252 253 254 public static final class Convert { 255 Pattern orig; 256 String repl; 257 boolean prefix; 258 boolean all; 259 260 public void setToken(String orig) { 261 this.orig = Pattern.compile(orig, Pattern.DOTALL | Pattern.MULTILINE); 262 } 263 public void setReplace(String repl) { 264 this.repl = repl.replace("\\n", "\n").replace("\\t", "\t"); 265 } 266 public void setPrefix(boolean b) { 267 prefix = b; 268 } 269 public void setReplaceAll(boolean b) { 270 all = b; 271 } 272 public Line createLine() { 273 return new Line(); 274 } 275 276 public final class Line { 277 public void setText(String t) { 278 if (repl == null) { 279 repl = t; 280 } else { 281 repl = repl + "\n" + t; 282 } 283 } 284 } 285 } 286 public static final class FailType extends org.apache.tools.ant.types.EnumeratedAttribute { 287 public String [] getValues () { 288 return new String [] { 289 "whenmissing", 290 "whenpresent", 291 }; 292 } 293 } 294 } 295 | Popular Tags |