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.api.project.libraries;
043:
044: import java.beans.PropertyChangeListener;
045: import java.beans.PropertyChangeEvent;
046: import java.net.URL;
047: import java.util.ArrayList;
048: import java.util.List;
049: import java.util.MissingResourceException;
050: import java.util.ResourceBundle;
051: import org.netbeans.modules.project.libraries.LibraryAccessor;
052: import org.netbeans.spi.project.libraries.LibraryImplementation;
053: import org.netbeans.spi.project.libraries.support.LibrariesSupport;
054: import org.openide.ErrorManager;
055: import org.openide.util.NbBundle;
056:
057: /**
058: * Library models typed bundle of typed volumes.
059: * <p>
060: * Library volumes are typed and query-able by their type. The type is
061: * represented by type string. Strictly speaking volumes are
062: * named rather then typed but the name express their type.
063: * The volume is a list of resoruces.
064: * <p>
065: * For more details see <a href="package-summary.html">libraries overview</a>.
066: * @author Petr Kuzel, Tomas Zezula
067: */
068: public final class Library {
069:
070: public static final String PROP_NAME = "name"; //NOI18N
071: public static final String PROP_DESCRIPTION = "description"; //NOI18N
072: public static final String PROP_CONTENT = "content"; //NOI18N
073:
074: // delegating peer
075: private LibraryImplementation impl;
076:
077: private List<PropertyChangeListener> listeners;
078:
079: private final LibraryManager manager;
080:
081: Library(LibraryImplementation impl, LibraryManager manager) {
082: this .impl = impl;
083: this .impl
084: .addPropertyChangeListener(new PropertyChangeListener() {
085: public void propertyChange(PropertyChangeEvent evt) {
086: String propName = evt.getPropertyName();
087: Library.this .fireChange(propName, evt
088: .getOldValue(), evt.getNewValue());
089: }
090: });
091: this .manager = manager;
092: } // end create
093:
094: /**
095: * Gets the associated library manager.
096: * @return the manager (may be the "default" global manager, or a local manager)
097: * @since org.netbeans.modules.project.libraries/1 1.15
098: */
099: public LibraryManager getManager() {
100: return manager;
101: }
102:
103: /**
104: * Access typed library data. Any relative URL provided by SPI is made absolute
105: * before being passed to client. See {@link #getRawContent} if you need raw library data.
106: * <p>
107: * The contents are defined by SPI providers and identified
108: * by the <a href="package-summary.html#volumeType">volume types</a>. For example the j2se library supports the following
109: * volume types: classpath - the library classpath roots, src - the library sources, javadoc - the library javadoc.
110: * Your module must have contract with a particular provider's module to be able to query it effectively.
111: * </p>
112: *
113: * @param volumeType which resources to return.
114: * @return path of URLs of given type (possibly empty but never <code>null</code>)
115: */
116: public List<URL> getContent(final String volumeType) {
117: List<URL> urls = this .impl.getContent(volumeType);
118: List<URL> resolvedUrls = new ArrayList<URL>(urls.size());
119: for (URL u : urls) {
120: resolvedUrls.add(LibrariesSupport.resolveLibraryEntryURL(
121: manager.getLocation(), u));
122: }
123: return resolvedUrls;
124: } // end getContent
125:
126: /**
127: * Access typed but raw library data.
128: * <p>
129: * The contents are defined by SPI providers and identified
130: * by the <a href="package-summary.html#volumeType">volume types</a>. For example the j2se library supports the following
131: * volume types: classpath - the library classpath roots, src - the library sources, javadoc - the library javadoc.
132: * Your module must have contract with a particular provider's module to be able to query it effectively.
133: * </p>
134: *
135: * @param volumeType which resources to return.
136: * @return path of URLs of given type (possibly empty but never <code>null</code>)
137: */
138: public List<URL> getRawContent(final String volumeType) {
139: return this .impl.getContent(volumeType);
140: } // end getContent
141:
142: /**
143: * Get library binding name. The name identifies library
144: * in scope of one libraries storage.
145: * <p>
146: *
147: * @return String with library name
148: */
149: public String getName() {
150: return impl.getName();
151: } // end getName
152:
153: /**
154: * Returns description of the library.
155: * The description provides more detailed information about the library.
156: * @return String the description or null if the description is not available
157: */
158: public String getDescription() {
159: return this .getLocalizedString(this .impl.getLocalizingBundle(),
160: this .impl.getDescription());
161: }
162:
163: /**
164: * Returns the display name of the library.
165: * The display name is either equal to the name or
166: * is a localized version of the name.
167: * @return String the display name, never returns null.
168: */
169: public String getDisplayName() {
170: return this .getLocalizedString(this .impl.getLocalizingBundle(),
171: this .impl.getName());
172: }
173:
174: /**
175: * Gets the type of library. The library type identifies
176: * the provider which has created the library and implies
177: * the volues contained in it.
178: * @return String (e.g. j2se for J2SE library)
179: */
180: public String getType() {
181: return this .impl.getType();
182: }
183:
184: // delegated identity
185: @Override
186: public boolean equals(Object obj) {
187: if (obj == this )
188: return true;
189: if (obj instanceof Library) {
190: Library peer = (Library) obj;
191: return peer.impl.equals(impl);
192: }
193: return false;
194: }
195:
196: // delegated identity
197: @Override
198: public int hashCode() {
199: return impl.hashCode();
200: }
201:
202: /**
203: * Adds PropertyChangeListener
204: * @param listener
205: */
206: public synchronized void addPropertyChangeListener(
207: PropertyChangeListener listener) {
208: if (this .listeners == null)
209: this .listeners = new ArrayList<PropertyChangeListener>();
210: this .listeners.add(listener);
211: }
212:
213: /**
214: * Removes PropertyChangeListener
215: * @param listener
216: */
217: public synchronized void removePropertyChangeListener(
218: PropertyChangeListener listener) {
219: if (this .listeners == null)
220: return;
221: this .listeners.remove(listener);
222: }
223:
224: LibraryImplementation getLibraryImplementation() {
225: return this .impl;
226: }
227:
228: private void fireChange(String propertyName, Object oldValue,
229: Object newValue) {
230: List<PropertyChangeListener> ls;
231: synchronized (this ) {
232: if (this .listeners == null)
233: return;
234: ls = new ArrayList<PropertyChangeListener>(listeners);
235: }
236: PropertyChangeEvent event = new PropertyChangeEvent(this ,
237: propertyName, oldValue, newValue);
238: for (PropertyChangeListener l : ls) {
239: l.propertyChange(event);
240: }
241: }
242:
243: private String getLocalizedString(String bundleName, String key) {
244: if (key == null) {
245: return null;
246: }
247: if (bundleName == null) {
248: return key;
249: }
250: ResourceBundle bundle;
251: try {
252: bundle = NbBundle.getBundle(bundleName);
253: } catch (MissingResourceException mre) {
254: // Bogus bundle.
255: ErrorManager.getDefault().notify(
256: ErrorManager.INFORMATIONAL, mre);
257: return key;
258: }
259: try {
260: return bundle.getString(key);
261: } catch (MissingResourceException mre) {
262: // OK, not required to be there.
263: return key;
264: }
265: }
266:
267: @Override
268: public String toString() {
269: return "Library[" + getName() + "]"; // NOI18N
270: }
271:
272: static {
273: LibraryAccessor.DEFAULT = new LibraryAccessor() {
274: public Library createLibrary(LibraryImplementation impl) {
275: return new Library(impl, LibraryManager.getDefault());
276: }
277: };
278: }
279:
280: } // end Library
|