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: package org.netbeans.modules.gsfpath.spi.classpath.support;
042:
043: import org.netbeans.modules.gsfpath.spi.classpath.PathResourceImplementation;
044: import org.netbeans.modules.gsfpath.spi.classpath.ClassPathImplementation;
045:
046: import java.net.URL;
047: import java.beans.PropertyChangeListener;
048: import java.beans.PropertyChangeEvent;
049: import java.util.ArrayList;
050: import java.util.Iterator;
051: import java.util.List;
052: import java.util.Arrays;
053:
054: /**
055: * This class provides a base class for PathResource implementations
056: * @since org.netbeans.modules.gsfpath.api/1 1.4
057: */
058: public abstract class CompositePathResourceBase implements
059: PathResourceImplementation {
060:
061: private URL[] roots;
062: private ClassPathImplementation model;
063: private ArrayList<PropertyChangeListener> pListeners;
064:
065: /**
066: * Returns the roots of the PathResource
067: * @return URL[]
068: */
069: public final URL[] getRoots() {
070: if (this .roots == null) {
071: synchronized (this ) {
072: if (this .roots == null) {
073: initContent();
074: List<URL> result = new ArrayList<URL>();
075: for (PathResourceImplementation pri : this .model
076: .getResources()) {
077: result.addAll(Arrays.asList(pri.getRoots()));
078: }
079: this .roots = result.toArray(new URL[result.size()]);
080: }
081: }
082: }
083: return this .roots;
084: }
085:
086: /**
087: * Returns the ClassPathImplementation representing the content of this PathResourceImplementation
088: * @return ClassPathImplementation
089: */
090: public final ClassPathImplementation getContent() {
091: initContent();
092: return this .model;
093: }
094:
095: /**
096: * Adds property change listener.
097: * The listener is notified when the roots of the PathResource are changed.
098: * @param listener
099: */
100: public synchronized final void addPropertyChangeListener(
101: PropertyChangeListener listener) {
102: if (this .pListeners == null)
103: this .pListeners = new ArrayList<PropertyChangeListener>();
104: this .pListeners.add(listener);
105: }
106:
107: /**
108: * Removes PropertyChangeListener
109: * @param listener
110: */
111: public synchronized final void removePropertyChangeListener(
112: PropertyChangeListener listener) {
113: if (this .pListeners == null)
114: return;
115: this .pListeners.remove(listener);
116: }
117:
118: /**
119: * Fires PropertyChangeEvent
120: * @param propName name of property
121: * @param oldValue old property value or null
122: * @param newValue new property value or null
123: */
124: protected final void firePropertyChange(String propName,
125: Object oldValue, Object newValue) {
126: PropertyChangeListener[] _listeners;
127: synchronized (this ) {
128: if (this .pListeners == null)
129: return;
130: _listeners = this .pListeners
131: .toArray(new PropertyChangeListener[this .pListeners
132: .size()]);
133: }
134: PropertyChangeEvent event = new PropertyChangeEvent(this ,
135: propName, oldValue, newValue);
136: for (PropertyChangeListener l : _listeners) {
137: l.propertyChange(event);
138: }
139: }
140:
141: /** Creates the array of the roots of PathResource.
142: * Most PathResource (directory, jar) have single root,
143: * but the PathResource can have more than one root to
144: * represent more complex resources like libraries.
145: * The returned value is cached.
146: * @return ClassPathImplementation
147: */
148: protected abstract ClassPathImplementation createContent();
149:
150: private synchronized void initContent() {
151: if (this .model == null) {
152: ClassPathImplementation cp = createContent();
153: assert cp != null;
154: cp.addPropertyChangeListener(new PropertyChangeListener() {
155: public void propertyChange(PropertyChangeEvent event) {
156: roots = null;
157: firePropertyChange(PROP_ROOTS, null, null);
158: }
159: });
160: this.model = cp;
161: }
162: }
163: }
|