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-2007 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.visualweb.complib;
043:
044: import java.beans.BeanDescriptor;
045: import java.beans.BeanInfo;
046: import java.beans.IntrospectionException;
047: import java.io.File;
048: import java.net.URI;
049: import java.net.URISyntaxException;
050: import java.util.ArrayList;
051: import java.util.List;
052:
053: import org.netbeans.modules.visualweb.complib.api.ComplibException;
054:
055: /**
056: * Represents a component library consisting of a collection of components. This is either a
057: * built-in or an extension component library provided by a third party.
058: *
059: *
060: * @author Edwin Goei
061: */
062: public abstract class Complib implements Comparable<Complib> {
063: /**
064: * Represents an identifier for a Component Library.
065: *
066: * @author Edwin Goei
067: */
068: public static class Identifier {
069: private URI uri;
070:
071: private Version version;
072:
073: public Identifier(URI uri, int major, int minor, int micro) {
074: if (uri == null) {
075: throw new IllegalArgumentException(
076: "URI must not be null");
077: }
078: this .uri = uri;
079: this .version = new Version(major, minor, micro);
080: }
081:
082: /**
083: * @param libraryUri
084: * @param libraryVersion
085: */
086: public Identifier(String uriString, String versionString) {
087: try {
088: this .uri = new URI(uriString);
089: } catch (URISyntaxException ex) {
090: throw new IllegalArgumentException(
091: "Invalid library URI", ex);
092: }
093:
094: try {
095: this .version = new Version(versionString);
096: } catch (Exception e) {
097: throw new IllegalArgumentException(
098: "Invalid library version", e);
099: }
100: }
101:
102: /**
103: * Return Namespace URI
104: *
105: * @return namespace URI
106: */
107: public URI getNamespaceUri() {
108: return uri;
109: }
110:
111: /**
112: * Return version
113: *
114: * @return version
115: */
116: public Version getVersion() {
117: return version;
118: }
119:
120: /**
121: * @return The fully escaped version of the URI
122: */
123: public String getNamespaceUriString() {
124: // Expose this method because of URI API bug where toString() does
125: // not escape non-ASCII chars.
126: return uri.toASCIIString();
127: }
128:
129: /**
130: * @return Version info as a String
131: */
132: public String getVersionString() {
133: return version.toString();
134: }
135:
136: /*
137: * For debugging, not necessarily used for persistence so this can change in the future if
138: * desired.
139: */
140: public String toString() {
141: return asString();
142: }
143:
144: /**
145: * Both this URI and version must be non-null and correspondingly equal to that contained in
146: * formal argument.
147: */
148: public boolean equals(Object anObject) {
149: if (this == anObject) {
150: return true;
151: }
152: if (anObject instanceof Identifier) {
153: Identifier anotherId = (Identifier) anObject;
154: if (uri.equals(anotherId.uri)
155: && getVersionString().equals(
156: anotherId.getVersionString())) {
157: return true;
158: }
159: }
160: return false;
161: }
162:
163: public int hashCode() {
164: return uri.hashCode() + version.hashCode();
165: }
166:
167: /**
168: * @return String representation of this identifier object used for persistence
169: */
170: public String asString() {
171: return "(uri=" + getNamespaceUriString() + ", version="
172: + getVersionString() + ")";
173: }
174: }
175:
176: /**
177: * For initial palette, represents a container that can contain InitialPaletteItem children.
178: *
179: * @author Edwin Goei
180: */
181: private static abstract class AbstractParent {
182: private ArrayList<InitialPaletteItem> children = new ArrayList<InitialPaletteItem>();
183:
184: public List<InitialPaletteItem> getChildren() {
185: return children;
186: }
187:
188: public void appendChild(InitialPaletteItem child) {
189: children.add(child);
190: }
191:
192: }
193:
194: /**
195: * For initial palette, represents a container that can contain either InitialPaletteItem-s or
196: * other InitialPaletteFolder-s. Possibly empty. Note: 2005-03-10 restricted to only contain
197: * InitialPaletteItem-s.
198: *
199: * @author Edwin Goei
200: */
201: public static class InitialPaletteFolder extends AbstractParent {
202: private String name;
203:
204: /**
205: * @param name
206: * Localized display name or resource key if not found
207: */
208: InitialPaletteFolder(String name) {
209: this .name = name;
210: }
211:
212: /**
213: * Returns the localized display name of this initial folder or the key if resource is not
214: * found
215: *
216: * @return
217: */
218: public String getName() {
219: return name;
220: }
221:
222: }
223:
224: /**
225: * For initial palette, represents a container that can only contain other InitialPaletteItem-s.
226: * Possibly empty. InitialPaletteItems-s containing other InitialPaletteItems-s may be used to
227: * organize the palette hierarchically.
228: *
229: * @author Edwin Goei
230: */
231: public static class InitialPaletteItem extends AbstractParent {
232: private String className;
233:
234: InitialPaletteItem(String className) {
235: this .className = className;
236: }
237:
238: public String getClassName() {
239: return className;
240: }
241: }
242:
243: /** Complib configuration info */
244: private ComplibManifest compLibManifest;
245:
246: private List<File> runtimePath;
247:
248: private List<File> designTimePath;
249:
250: private List<File> javadocPath;
251:
252: private List<File> sourcePath;
253:
254: private List<File> webResourcePath;
255:
256: private List<File> helpPath;
257:
258: /**
259: * Note: to fully initialize a Complib subclass requires these steps and occur in the following
260: * order: 1) calling the constructor 2) initCompLibManifest() 3) initPaths().
261: *
262: * TODO Figure out how to clean this up
263: */
264: public Complib() {
265: }
266:
267: /**
268: * This method should be called in the constructor of a Complib subclass.
269: *
270: * @param compLibManifest
271: */
272: protected void initCompLibManifest(ComplibManifest compLibManifest) {
273: this .compLibManifest = compLibManifest;
274: }
275:
276: protected ComplibManifest getCompLibManifest() {
277: return compLibManifest;
278: }
279:
280: /**
281: * This method converts relative paths from the compLibConfig and turns them into absolute file
282: * paths in the expanded complib form.
283: *
284: * @throws ComplibException
285: */
286: protected void initPaths() throws ComplibException {
287: this .runtimePath = convertConfigPathToFileList(compLibManifest
288: .getRuntimePath());
289: this .designTimePath = convertConfigPathToFileList(compLibManifest
290: .getDeclaredDesignTimePath());
291: this .javadocPath = convertConfigPathToFileList(compLibManifest
292: .getJavadocPath());
293: this .sourcePath = convertConfigPathToFileList(compLibManifest
294: .getSourcePath());
295: this .webResourcePath = convertConfigPathToFileList(compLibManifest
296: .getWebResourcePath());
297: this .helpPath = convertConfigPathToFileList(compLibManifest
298: .getHelpPath());
299: }
300:
301: /**
302: * Convert from a ComponentLibraryConfiguration path containing relative File-s, ie. a List<String>
303: * each representing a path element within a component library into a List<File> with absolute
304: * File-s.
305: *
306: * @param path
307: * List<String> each String representing a path element. Possibly empty, may not be
308: * null.
309: * @return
310: * @throws ComplibException
311: * if not valid
312: */
313: protected abstract List<File> convertConfigPathToFileList(
314: List<String> path) throws ComplibException;
315:
316: /**
317: * Returns the identifier for this component library
318: *
319: * @return
320: */
321: public Complib.Identifier getIdentifier() {
322: return compLibManifest.getIdentifier();
323: }
324:
325: /**
326: * Returns the localized Title if it has been localized
327: *
328: * @return
329: */
330: public String getTitle() {
331: return compLibManifest.getTitle();
332: }
333:
334: /**
335: * Returns the localized Title if it has been localized appended with a version
336: *
337: * @return
338: */
339: public String getVersionedTitle() {
340: return getTitle() + " (" + getIdentifier().getVersionString()
341: + ")";
342: }
343:
344: /**
345: * Returns the runtime path
346: *
347: * @return List of absolute File-s
348: */
349: public List<File> getRuntimePath() {
350: return runtimePath;
351: }
352:
353: /**
354: * Returns the design-time path
355: *
356: * @return List<File> of absolute File-s
357: */
358: public List<File> getDesignTimePath() {
359: return designTimePath;
360: }
361:
362: /**
363: * Returns the javadoc path
364: *
365: * @return List<File> of absolute File-s
366: */
367: public List<File> getJavadocPath() {
368: return javadocPath;
369: }
370:
371: /**
372: * Returns the java source path
373: *
374: * @return List<File> of absolute File-s
375: */
376: public List<File> getSourcePath() {
377: return sourcePath;
378: }
379:
380: /**
381: * Returns the web resource path
382: *
383: * @return List<File> of absolute File-s
384: */
385: public List<File> getWebResourcePath() {
386: return webResourcePath;
387: }
388:
389: /**
390: * Returns the help path
391: *
392: * @return List<File> of absolute File-s
393: */
394: public List<File> getHelpPath() {
395: return helpPath;
396: }
397:
398: /**
399: * Return the help set file. Null means none found. "/" separated path to HelpSet file relative
400: * to helpPath. eg. "help/my-help.hs"
401: *
402: * @return the help set file. Null means none found.
403: */
404: public String getHelpSetFile() {
405: return compLibManifest.getHelpSetFile();
406: }
407:
408: /**
409: * Return the help prefix. Null means no prefix attribute found.
410: *
411: * @return the help prefix. Null means no prefix attribute found.
412: */
413: public String getHelpPrefix() {
414: // TODO Not used. Remove.
415: return compLibManifest.getHelpPrefix();
416: }
417:
418: /**
419: * Method does not throw a checked exception. Used by UI.
420: *
421: * @return
422: */
423: public List<InitialPaletteFolder> getInitialPaletteFolders() {
424: return compLibManifest.getInitialPalette();
425: }
426:
427: /**
428: * Main entry point to get list of components organized into InitialPaletteFolder-s for this
429: * complib.
430: *
431: * @return
432: * @throws ComplibException
433: */
434: public List<InitialPaletteFolder> getComponentItemsInFolders()
435: throws ComplibException {
436: return compLibManifest.getInitialPalette();
437: }
438:
439: /**
440: * Return the BeanInfo given a class name
441: *
442: * @param className
443: * @return
444: * @throws ClassNotFoundException
445: * @throws IntrospectionException
446: */
447: abstract BeanInfo getBeanInfo(String className)
448: throws ClassNotFoundException, IntrospectionException;
449:
450: /**
451: * Returns true iff this bean should be hidden
452: *
453: * @param itemClassName
454: * @return
455: */
456: boolean isHidden(String itemClassName) {
457: BeanInfo beanInfo;
458: try {
459: beanInfo = getBeanInfo(itemClassName);
460: } catch (Exception e) {
461: IdeUtil.logWarning(e);
462: return false;
463: }
464: BeanDescriptor beanDescriptor = beanInfo.getBeanDescriptor();
465: return beanDescriptor.isHidden();
466: }
467:
468: /**
469: * Returns a ClassLoader that can be used to obtain design-time metadata for a component
470: * library. Typically, both the runtime and design-time classes are accessible as well as
471: * JavaHelp jars.
472: *
473: * @return ClassLoader
474: */
475: public abstract ClassLoader getClassLoader();
476:
477: @Override
478: public boolean equals(Object anObject) {
479: // Two complibs are equal iff their identifiers are
480: if (this == anObject) {
481: return true;
482: }
483: if (anObject instanceof Complib) {
484: Complib aComplib = (Complib) anObject;
485: if (getIdentifier().equals(aComplib.getIdentifier())) {
486: return true;
487: }
488: }
489: return false;
490: }
491:
492: @Override
493: public int hashCode() {
494: return getIdentifier().hashCode();
495: }
496:
497: public int compareTo(Complib aComplib) {
498: URI myNamespace = getIdentifier().getNamespaceUri();
499: URI otherNamespace = aComplib.getIdentifier().getNamespaceUri();
500: if (!myNamespace.equals(otherNamespace)) {
501: return myNamespace.compareTo(otherNamespace);
502: }
503:
504: Version myVersion = getIdentifier().getVersion();
505: Version otherVersion = aComplib.getIdentifier().getVersion();
506: return myVersion.compareTo(otherVersion);
507: }
508: }
|