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.spi.project.support.ant;
043:
044: import java.beans.PropertyChangeEvent;
045: import java.beans.PropertyChangeListener;
046: import java.io.File;
047: import java.util.ArrayList;
048: import java.util.List;
049: import org.netbeans.api.queries.SharabilityQuery;
050: import org.netbeans.modules.project.ant.ProjectLibraryProvider;
051: import org.netbeans.spi.queries.SharabilityQueryImplementation;
052: import org.openide.util.WeakListeners;
053:
054: /**
055: * Standard impl of {@link SharabilityQueryImplementation}.
056: * @author Jesse Glick
057: */
058: final class SharabilityQueryImpl implements
059: SharabilityQueryImplementation, PropertyChangeListener,
060: AntProjectListener {
061:
062: private final AntProjectHelper h;
063: private final PropertyEvaluator eval;
064: private final String[] includes;
065: private final String[] excludes;
066: /** Absolute paths of directories or files to treat as sharable (except for the excludes). */
067: private String[] includePaths;
068: /** Absolute paths of directories or files to treat as not sharable. */
069: private String[] excludePaths;
070:
071: SharabilityQueryImpl(AntProjectHelper h, PropertyEvaluator eval,
072: String[] includes, String[] excludes) {
073: this .h = h;
074: this .eval = eval;
075: this .includes = includes;
076: this .excludes = excludes;
077: computeFiles();
078: eval.addPropertyChangeListener(WeakListeners.propertyChange(
079: this , eval));
080: h.addAntProjectListener(this );
081: }
082:
083: /** Compute the absolute paths which are and are not sharable. */
084: private void computeFiles() {
085: String[] _includePaths = computeFrom(includes, false);
086: String[] _excludePaths = computeFrom(excludes, true);
087: synchronized (this ) {
088: includePaths = _includePaths;
089: excludePaths = _excludePaths;
090: }
091: }
092:
093: /** Compute a list of absolute paths based on some abstract names. */
094: private String[] computeFrom(String[] list,
095: boolean excludeProjectLibraryPrivate) {
096: List<String> result = new ArrayList<String>(list.length);
097: for (String s : list) {
098: String val = eval.evaluate(s);
099: if (val != null) {
100: File f = h.resolveFile(val);
101: result.add(f.getAbsolutePath());
102: }
103: }
104: if (excludeProjectLibraryPrivate) {
105: result.addAll(ProjectLibraryProvider
106: .getUnsharablePathsWithinProject(h));
107: }
108: // XXX should remove overlaps somehow
109: return result.toArray(new String[result.size()]);
110: }
111:
112: public synchronized int getSharability(File file) {
113: String path = file.getAbsolutePath();
114: if (contains(path, excludePaths, false)) {
115: return SharabilityQuery.NOT_SHARABLE;
116: }
117: return contains(path, includePaths, false) ? (contains(path,
118: excludePaths, true) ? SharabilityQuery.MIXED
119: : SharabilityQuery.SHARABLE) : SharabilityQuery.UNKNOWN;
120: }
121:
122: /**
123: * Check whether a file path matches something in the supplied list.
124: * @param a file path to test
125: * @param list a list of file paths
126: * @param reverse if true, check if the file is an ancestor of some item; if false,
127: * check if some item is an ancestor of the file
128: * @return true if the file matches some item
129: */
130: private static boolean contains(String path, String[] list,
131: boolean reverse) {
132: for (String s : list) {
133: if (path.equals(s)) {
134: return true;
135: } else {
136: if (reverse ? s.startsWith(path + File.separatorChar)
137: : path.startsWith(s + File.separatorChar)) {
138: return true;
139: }
140: }
141: }
142: return false;
143: }
144:
145: public void propertyChange(PropertyChangeEvent evt) {
146: computeFiles();
147: }
148:
149: public void configurationXmlChanged(AntProjectEvent ev) {
150: computeFiles();
151: }
152:
153: public void propertiesChanged(AntProjectEvent ev) {
154: }
155:
156: }
|