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.spi.project.libraries.support;
042:
043: import java.io.File;
044: import java.net.MalformedURLException;
045: import java.net.URI;
046: import java.net.URISyntaxException;
047: import java.net.URL;
048: import org.netbeans.modules.project.libraries.LibraryTypeRegistry;
049: import org.netbeans.spi.project.libraries.LibraryImplementation;
050: import org.netbeans.modules.project.libraries.DefaultLibraryImplementation;
051: import org.netbeans.spi.project.libraries.LibraryTypeProvider;
052: import org.openide.filesystems.FileObject;
053: import org.openide.filesystems.FileUtil;
054: import org.openide.filesystems.URLMapper;
055: import org.openide.util.Parameters;
056:
057: /**
058: * SPI Support class.
059: * Provides factory method for creating instance of the default LibraryImplementation.
060: */
061: public final class LibrariesSupport {
062:
063: private LibrariesSupport() {
064: }
065:
066: /**
067: * Creates default LibraryImplementation
068: * @param libraryType type of library
069: * @param volumeTypes types of supported volumes
070: * @return LibraryImplementation, never return null
071: */
072: public static LibraryImplementation createLibraryImplementation(
073: String libraryType, String[] volumeTypes) {
074: return new DefaultLibraryImplementation(libraryType,
075: volumeTypes);
076: }
077:
078: /**
079: * Returns registered {@link LibraryTypeProvider} for given library type. This method
080: * is mostly used by {@link org.netbeans.spi.project.libraries.LibraryProvider} implementators.
081: * @param libraryType the type of library for which the provider should be returned.
082: * @return {@link LibraryTypeProvider} for given library type or null, if none is registered.
083: * @since org.netbeans.modules.project.libraries/1 1.14
084: */
085: public static LibraryTypeProvider getLibraryTypeProvider(
086: String libraryType) {
087: return LibraryTypeRegistry.getDefault().getLibraryTypeProvider(
088: libraryType);
089: }
090:
091: /**
092: * Returns all registered {@link LibraryTypeProvider}s. This method
093: * is mostly used by {@link org.netbeans.spi.project.libraries.LibraryProvider} implementators.
094: * @return an array of {@link LibraryTypeProvider}, never returns null.
095: * @since org.netbeans.modules.project.libraries/1 1.14
096: */
097: public static LibraryTypeProvider[] getLibraryTypeProviders() {
098: return LibraryTypeRegistry.getDefault()
099: .getLibraryTypeProviders();
100: }
101:
102: /**
103: * Properly converts possibly relative file to URL.
104: * @param f file to convert; can be relative; cannot be null
105: * @return url
106: * @since org.netbeans.modules.project.libraries/1 1.17
107: */
108: public static URL convertFilePathToURL(String path) {
109: try {
110: File f = new File(path);
111: if (f.isAbsolute()) {
112: return f.toURI().toURL();
113: } else {
114: // create hierarchical relative URI (that is no schema)
115: // to encode OS characters
116: URI uri = new URI(null, null, path.replace('\\', '/'),
117: null);
118: return new URL("file", null, uri.getRawPath());
119: }
120:
121: } catch (URISyntaxException ex) {
122: IllegalArgumentException y = new IllegalArgumentException();
123: y.initCause(ex);
124: throw y;
125: } catch (MalformedURLException ex) {
126: IllegalArgumentException y = new IllegalArgumentException();
127: y.initCause(ex);
128: throw y;
129: }
130: }
131:
132: /**
133: * Properly converts possibly relative URL to file.
134: * @param url file URL to convert; can be relative; cannot be null
135: * @return url
136: * @since org.netbeans.modules.project.libraries/1 1.17
137: */
138: public static String convertURLToFilePath(URL url) {
139: if (!"file".equals(url.getProtocol())) {
140: throw new IllegalArgumentException("not file URL " + url); //NOI18N
141: }
142: try {
143: if (isAbsoluteURL(url)) {
144: return new File(new URI(url.toExternalForm()))
145: .getPath();
146: } else {
147: // workaround to decode URL path - created fake absolute URI
148: // just to construct File instance and properly decoded path:
149: URI uri3 = new URI("file:/" + url.getPath());
150: return new File(uri3).getPath().substring(1);
151: }
152: } catch (URISyntaxException ex) {
153: IllegalArgumentException y = new IllegalArgumentException();
154: y.initCause(ex);
155: throw y;
156: }
157: }
158:
159: /**
160: * Is given URL absolute?
161: *
162: * @param url url to test; cannot be null
163: * @return is absolute
164: * @since org.netbeans.modules.project.libraries/1 1.17
165: */
166: public static boolean isAbsoluteURL(URL url) {
167: if ("jar".equals(url.getProtocol())) { // NOI18N
168: url = FileUtil.getArchiveFile(url);
169: }
170: return url.getPath().startsWith("/");
171: }
172:
173: /**
174: * Helper method to resolve (possibly relative) library content URL to FileObject.
175: *
176: * @param libraryLocation library location file; can be null for global libraries
177: * @param libraryEntry library entry to resolve
178: * @return file object
179: * @since org.netbeans.modules.project.libraries/1 1.17
180: */
181: public static FileObject resolveLibraryEntryFileObject(
182: URL libraryLocation, URL libraryEntry) {
183: URL u = resolveLibraryEntryURL(libraryLocation, libraryEntry);
184: return URLMapper.findFileObject(u);
185: }
186:
187: /**
188: * Helper method to resolve (possibly relative) library content URL.
189: *
190: * @param libraryLocation library location file; can be null for global libraries
191: * @param libraryEntry library entry to resolve
192: * @return absolute URL
193: * @since org.netbeans.modules.project.libraries/1 1.17
194: */
195: public static URL resolveLibraryEntryURL(URL libraryLocation,
196: URL libraryEntry) {
197: Parameters.notNull("libraryEntry", libraryEntry); //NOI18N
198: if (isAbsoluteURL(libraryEntry)) {
199: return libraryEntry;
200: } else {
201: if (libraryLocation == null) {
202: throw new IllegalArgumentException(
203: "cannot resolve relative URL without library location"); //NOI18N
204: }
205: if (!"file".equals(libraryLocation.getProtocol())) { //NOI18N
206: throw new IllegalArgumentException(
207: "not file: protocol - "
208: + libraryLocation.toExternalForm()); //NOI18N
209: }
210: File libLocation = new File(URI.create(libraryLocation
211: .toExternalForm()));
212: if (!libLocation.getName().endsWith(".properties")) { //NOI18N
213: throw new IllegalArgumentException(
214: "library location must be a file - "
215: + libraryLocation.toExternalForm()); //NOI18N
216: }
217: File libBase = libLocation.getParentFile();
218: String jarFolder = null;
219: if ("jar".equals(libraryEntry.getProtocol())) {
220: assert libraryEntry.toExternalForm().indexOf("!/") != -1 : libraryEntry
221: .toExternalForm(); //NOI18N
222: jarFolder = libraryEntry.toExternalForm()
223: .substring(
224: libraryEntry.toExternalForm().indexOf(
225: "!/") + 2); //NOI18N
226: libraryEntry = FileUtil.getArchiveFile(libraryEntry);
227: }
228: String path = convertURLToFilePath(libraryEntry);
229: File f = FileUtil.normalizeFile(new File(libBase, path));
230: URL u;
231: try {
232: u = f.toURI().toURL();
233: } catch (MalformedURLException ex) {
234: IllegalArgumentException y = new IllegalArgumentException();
235: y.initCause(ex);
236: throw y;
237: }
238: if (jarFolder != null) {
239: u = FileUtil.getArchiveRoot(u);
240: try {
241: u = new URL(u + jarFolder.replace('\\', '/')); //NOI18N
242: } catch (MalformedURLException e) {
243: throw new AssertionError(e);
244: }
245: }
246: return u;
247: }
248: }
249:
250: // TODO: add method which compares two libraries: compare content and file sizes and ...
251:
252: // TODO: move some of these methods to openide.FileUtil
253: }
|