001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.nbbuild;
043:
044: import java.io.File;
045: import java.util.HashMap;
046: import java.util.LinkedHashMap;
047: import java.util.Map;
048: import java.util.Set;
049: import org.apache.tools.ant.BuildException;
050: import org.apache.tools.ant.Task;
051: import org.apache.tools.ant.types.DirSet;
052: import org.apache.tools.ant.types.PatternSet;
053: import org.apache.tools.ant.types.selectors.SelectorUtils;
054: import org.w3c.dom.Document;
055: import org.w3c.dom.Element;
056: import org.w3c.dom.NodeList;
057: import org.xml.sax.InputSource;
058:
059: /**
060: * Removes files from clusters which are not listed as belonging to any NBM.
061: * @see <a href="http://www.netbeans.org/nonav/issues/show_bug.cgi?id=111946">issue #111946</a>
062: */
063: public class DeleteUnreferencedClusterFiles extends Task {
064:
065: private DirSet clusters;
066:
067: /**
068: * Set of cluster directories to scan.
069: * Any dir lacking an update_tracking subdir is automatically ignored.
070: */
071: public void addConfiguredClusters(DirSet clusters) {
072: this .clusters = clusters;
073: }
074:
075: private PatternSet patterns;
076:
077: /**
078: * Option to remove files from those checks
079: */
080: public void addConfiguredSelection(PatternSet p) {
081: patterns = p;
082: }
083:
084: private File report;
085:
086: /** Write any errors to a JUnit report rather than halting build. */
087: public void setReport(File report) {
088: this .report = report;
089: }
090:
091: public @Override
092: void execute() throws BuildException {
093: StringBuilder missingFiles = new StringBuilder();
094: StringBuilder extraFiles = new StringBuilder();
095: StringBuilder duplicatedFiles = new StringBuilder();
096: for (String incl : clusters.getDirectoryScanner()
097: .getIncludedDirectories()) {
098: File cluster = new File(clusters.getDir(), incl);
099: File updateTracking = new File(cluster, "update_tracking");
100: if (!updateTracking.isDirectory()) {
101: continue;
102: }
103: Map</*path*/String, /*CNB*/String> files = new HashMap<String, String>();
104: for (File module : updateTracking.listFiles()) {
105: if (!module.getName().endsWith(".xml")) {
106: continue;
107: }
108: try {
109: Document doc = XMLUtil.parse(new InputSource(module
110: .toURI().toString()), false, false, null,
111: null);
112: String cnb = doc.getDocumentElement().getAttribute(
113: "codename").replaceFirst("/[0-9]+$", "");
114: NodeList nl = doc.getElementsByTagName("file");
115: for (int i = 0; i < nl.getLength(); i++) {
116: String file = ((Element) nl.item(i))
117: .getAttribute("name");
118: if (new File(cluster, file).isFile()) {
119: String prev = files.put(file, cnb);
120: if (prev != null) {
121: duplicatedFiles
122: .append("\ntwo registrations of the same file: "
123: + file
124: + " (from "
125: + prev
126: + " and "
127: + cnb
128: + ")");
129: }
130: } else {
131: missingFiles.append("\n" + cnb
132: + ": missing " + file);
133: }
134: }
135: } catch (Exception x) {
136: throw new BuildException("Parsing " + module + ": "
137: + x, x, getLocation());
138: }
139: }
140: scanForExtraFiles(cluster, "", files.keySet(), cluster
141: .getName(), extraFiles);
142: }
143: Map<String, String> pseudoTests = new LinkedHashMap<String, String>();
144: pseudoTests.put("testMissingFiles",
145: missingFiles.length() > 0 ? "Some files were missing"
146: + missingFiles : null);
147: pseudoTests
148: .put(
149: "testExtraFiles",
150: extraFiles.length() > 0 ? "Some extra files were present"
151: + extraFiles
152: : null);
153: pseudoTests
154: .put(
155: "testDuplicatedFiles",
156: duplicatedFiles.length() > 0 ? "Some files were registered in two or more NBMs"
157: + duplicatedFiles
158: : null);
159: JUnitReportWriter.writeReport(this , report, pseudoTests);
160: }
161:
162: private void scanForExtraFiles(File d, String prefix,
163: Set<String> files, String cluster, StringBuilder extraFiles) {
164: if (prefix.equals("update_tracking/")) {
165: return;
166: }
167: for (String n : d.list()) {
168: File f = new File(d, n);
169: if (f.getName().equals(".lastModified")) {
170: continue;
171: }
172: if (f.isDirectory()) {
173: scanForExtraFiles(f, prefix + n + "/", files, cluster,
174: extraFiles);
175: } else {
176: String path = prefix + n;
177: if (patterns != null)
178: for (String p : patterns
179: .getExcludePatterns(getProject()))
180: if (SelectorUtils.matchPath(p, path))
181: return;
182:
183: if (!files.contains(path)) {
184: extraFiles.append("\n" + cluster
185: + ": untracked file " + path);
186: f.delete();
187: }
188: }
189: }
190: }
191:
192: }
|