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-2006 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.modules.versioning.system.cvss.util;
043:
044: import org.netbeans.modules.versioning.spi.VersioningSupport;
045:
046: import java.io.File;
047: import java.io.Serializable;
048: import java.util.*;
049:
050: /**
051: * Encapsulates context of an action. There are two ways in which context may be defined:
052: * - list of files (f/b.txt, f/c.txt, f/e.txt)
053: * - list of roots (top folders) plus list of exclusions (f),(a.txt, d.txt)
054: *
055: * @author Maros Sandor
056: */
057: public class Context implements Serializable {
058:
059: public static final Context Empty = new Context(
060: Collections.EMPTY_SET, Collections.EMPTY_SET,
061: Collections.EMPTY_SET);
062:
063: private static final long serialVersionUID = 1L;
064:
065: private final Set filteredFiles;
066: private final Set rootFiles;
067: private final Set exclusions;
068:
069: public Context(Set filteredFiles, Set rootFiles, Set exclusions) {
070: this .filteredFiles = filteredFiles;
071: this .rootFiles = rootFiles;
072: this .exclusions = exclusions;
073: while (normalize())
074: ;
075: }
076:
077: private boolean normalize() {
078: for (Iterator i = rootFiles.iterator(); i.hasNext();) {
079: File root = (File) i.next();
080: for (Iterator j = exclusions.iterator(); j.hasNext();) {
081: File exclusion = (File) j.next();
082: if (Utils.isParentOrEqual(exclusion, root)) {
083: j.remove();
084: exclusionRemoved(exclusion, root);
085: return true;
086: }
087: }
088: }
089: removeDuplicates(rootFiles);
090: removeDuplicates(exclusions);
091: return false;
092: }
093:
094: private void removeDuplicates(Set files) {
095: List newFiles = new ArrayList();
096: outter: for (Iterator i = files.iterator(); i.hasNext();) {
097: File file = (File) i.next();
098: for (Iterator j = newFiles.iterator(); j.hasNext();) {
099: File includedFile = (File) j.next();
100: if (Utils.isParentOrEqual(includedFile, file)
101: && (file.isFile() || !VersioningSupport
102: .isFlat(includedFile)))
103: continue outter;
104: if (Utils.isParentOrEqual(file, includedFile)
105: && (includedFile.isFile() || !VersioningSupport
106: .isFlat(file))) {
107: j.remove();
108: }
109: }
110: newFiles.add(file);
111: }
112: files.clear();
113: files.addAll(newFiles);
114: }
115:
116: private void exclusionRemoved(File exclusion, File root) {
117: File[] exclusionChildren = exclusion.listFiles();
118: if (exclusionChildren == null)
119: return;
120: for (int i = 0; i < exclusionChildren.length; i++) {
121: File child = exclusionChildren[i];
122: if (!Utils.isParentOrEqual(root, child)) {
123: exclusions.add(child);
124: }
125: }
126: }
127:
128: public Set<File> getExclusions() {
129: return exclusions;
130: }
131:
132: /**
133: * Gets exact set of files to operate on, it is effectively defined as (rootFiles - exclusions). This set
134: * is NOT suitable for Update command because Update should operate on all rootFiles and just exclude some subfolders.
135: * Otherwise update misses new files and folders directly in rootFiles folders.
136: *
137: * @return files to operate on
138: */
139: public File[] getFiles() {
140: return (File[]) filteredFiles.toArray(new File[filteredFiles
141: .size()]);
142: }
143:
144: public File[] getRootFiles() {
145: return (File[]) rootFiles.toArray(new File[rootFiles.size()]);
146: }
147:
148: public boolean contains(File file) {
149: outter: for (Iterator i = rootFiles.iterator(); i.hasNext();) {
150: File root = (File) i.next();
151: if (Utils.isParentOrEqual(root, file)) {
152: for (Iterator j = exclusions.iterator(); j.hasNext();) {
153: File excluded = (File) j.next();
154: if (Utils.isParentOrEqual(excluded, file)) {
155: continue outter;
156: }
157: }
158: return true;
159: }
160: }
161: return false;
162: }
163:
164: /**
165: * Joins this context and the parameter context.
166: *
167: * @param ctx
168: * @return
169: */
170: public Context union(Context ctx) {
171: Set<File> newfilteredFiles = new HashSet<File>(filteredFiles);
172: Set<File> newrootFiles = new HashSet<File>(rootFiles);
173: Set<File> newexclusions = new HashSet<File>(exclusions);
174:
175: // TODO: postprocess filetered file list? it may be larger than necessary
176: newfilteredFiles.addAll(ctx.filteredFiles);
177: newrootFiles.addAll(ctx.rootFiles);
178: newexclusions.addAll(ctx.exclusions);
179:
180: Context nc = new Context(newfilteredFiles, newrootFiles,
181: newexclusions);
182: return nc;
183: }
184: }
|