KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > nbbuild > CheckLicense


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.nbbuild;
21
22 import java.io.BufferedReader JavaDoc;
23 import java.io.File JavaDoc;
24 import java.io.FileInputStream JavaDoc;
25 import java.io.FileOutputStream JavaDoc;
26 import java.io.FileReader JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.regex.Matcher JavaDoc;
32 import java.util.regex.Pattern JavaDoc;
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 /** Check source files for a license notice.
41  * @author Jesse Glick
42  */

43 public class CheckLicense extends Task {
44
45     private final List JavaDoc<FileSet> filesets = new ArrayList JavaDoc<FileSet>(1);
46     private String JavaDoc fragment;
47     private List JavaDoc<Convert> fragments;
48     private FailType fail;
49
50     /** Add a file set of source files to check.
51      * @param fs set of files to check licenses of
52      */

53     public void addFileSet (FileSet fs) {
54         filesets.add (fs);
55     }
56     
57     /** Add a file set of CVS-controlled source files to check.
58      * @param fs set of files to check licenses of
59      */

60     public void addCvsFileSet(CvsFileSet fs) {
61         filesets.add(fs);
62     }
63
64     /** Set the fragment of license notice which is expected
65      * to be found in each source file.
66      * @param f the fragment
67      */

68     public void setFragment (String JavaDoc 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 JavaDoc<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 JavaDoc it = filesets.iterator ();
97         String JavaDoc failMsg = null;
98         try {
99             while (it.hasNext ()) {
100                 FileScanner scanner = ((FileSet) it.next()).getDirectoryScanner(getProject());
101                 File JavaDoc baseDir = scanner.getBasedir ();
102                 String JavaDoc[] 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 JavaDoc f = new File JavaDoc (baseDir, files[i]);
106                     //log("Scanning " + f, Project.MSG_VERBOSE);
107
BufferedReader JavaDoc br = new BufferedReader JavaDoc (new FileReader JavaDoc (f));
108                     try {
109                         String JavaDoc line;
110                         while ((line = br.readLine ()) != null) {
111                             if (line.indexOf (fragment) != -1) {
112                                 // Found it.
113
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 JavaDoc 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                                 // Scanned whole file without finding it.
129
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 JavaDoc 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 JavaDoc 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 JavaDoc baseDir = scanner.getBasedir ();
154                 String JavaDoc[] 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 JavaDoc file = new File JavaDoc (baseDir, files[i]);
158                     log("Processing " + file, Project.MSG_VERBOSE);
159                     FileInputStream JavaDoc is = new FileInputStream JavaDoc(file);
160                     int workingLength = is.read(workingArray);
161                     if (workingLength == -1) {
162                         continue;
163                     }
164                     String JavaDoc workingString = new String JavaDoc(workingArray, 0, workingLength);
165                     boolean changed = false;
166                     String JavaDoc prefix = null;
167                     
168                     Iterator JavaDoc frags = fragments.iterator();
169                     while (frags.hasNext()) {
170                         Convert f = (Convert)frags.next();
171                         
172                         Matcher JavaDoc 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 JavaDoc before = workingString.substring(0, matcher.start());
186                             String JavaDoc after = workingString.substring(matcher.end());
187                             String JavaDoc 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 JavaDoc os = new FileOutputStream JavaDoc(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 JavaDoc ioe) {
228             throw new BuildException("Could not open files to check licenses", ioe, getLocation());
229         }
230     }
231
232     private String JavaDoc wrapWithPrefix(String JavaDoc repl, String JavaDoc prefix, boolean startWithPrefix) {
233         if (prefix == null) {
234             return repl;
235         }
236         
237         String JavaDoc[] all = repl.split("\n");
238         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
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 JavaDoc orig;
256         String JavaDoc repl;
257         boolean prefix;
258         boolean all;
259         
260         public void setToken(String JavaDoc orig) {
261             this.orig = Pattern.compile(orig, Pattern.DOTALL | Pattern.MULTILINE);
262         }
263         public void setReplace(String JavaDoc 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 JavaDoc 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 JavaDoc[] getValues () {
288             return new String JavaDoc[] {
289                 "whenmissing",
290                 "whenpresent",
291             };
292         }
293     }
294 }
295
Popular Tags