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: package org.netbeans.modules.visualweb.web.ui.dt.component.propertyeditors;
042:
043: import com.sun.rave.designtime.DesignProperty;
044: import com.sun.rave.designtime.faces.FacesDesignContext;
045: import com.sun.rave.designtime.faces.FacesDesignProject;
046: import com.sun.rave.propertyeditors.domains.AttachedDomain;
047: import com.sun.rave.propertyeditors.domains.Element;
048: import java.io.IOException;
049: import java.net.URL;
050: import java.util.ArrayList;
051: import java.util.Arrays;
052: import java.util.Enumeration;
053: import java.util.Locale;
054: import java.util.ResourceBundle;
055: import java.util.jar.Attributes;
056: import java.util.jar.Manifest;
057:
058: /**
059: * A custom property editor domain for available theme icons. The editor will
060: * display symbolic names for all images discovered in the current theme. The JAR
061: * that corresponds to the current theme is discovered by first searching the
062: * context loader's class path for all instances of the theme manifest file.
063: * Each of these is in turn searched for a name property that corresponds to the
064: * current theme name. If found, that JAR's image properties file is searched
065: * for images, and a list generated from the images' symbolic names.
066: *
067: * @author gjmurphy
068: */
069: //TODO - Get theme name from faces context, or wherever it is stored when configured
070: public class ThemeIconsDomain extends AttachedDomain {
071:
072: /**
073: * Name of the manifest file that a JAR must contains for it to be a theme JAR.
074: */
075: final static String MANIFEST_FILE = "META-INF/MANIFEST.MF"; //NOI18N
076:
077: /**
078: * Name of the manifest attribute that refers to the theme name.
079: */
080: final static String NAME_ATTRIBUTE = "X-SJWUIC-Theme-Name"; //NOI18N
081:
082: /**
083: * Name of the manifest attribute that refers to the images properties file.
084: */
085: final static String IMAGES_ATTRIBUTE = "X-SJWUIC-Theme-Images"; //NOI18N
086:
087: static ResourceBundle imagesBundle = null;
088:
089: Element[] elements;
090:
091: /**
092: * Return an array of elements that represent the currently available theme
093: * icons. If this domain has not been attached to a design property, an
094: * empty array is returned.
095: */
096: public Element[] getElements() {
097: if (this .elements != null)
098: return this .elements;
099: if (imagesBundle == null) {
100: if (this .getDesignProperty() == null)
101: return Element.EMPTY_ARRAY;
102: FacesDesignContext designContext = (FacesDesignContext) this
103: .getDesignProperty().getDesignBean()
104: .getDesignContext();
105: Locale locale = designContext.getFacesContext()
106: .getExternalContext().getRequestLocale();
107: if (locale == null)
108: locale = Locale.getDefault();
109: imagesBundle = loadImagesBundle("defaulttheme", locale);
110: }
111: if (imagesBundle == null) {
112: this .elements = Element.EMPTY_ARRAY;
113: } else {
114: Enumeration imagesEnum = imagesBundle.getKeys();
115: ArrayList elementList = new ArrayList();
116: while (imagesEnum.hasMoreElements()) {
117: String resourceName = (String) imagesEnum.nextElement();
118: String resourceValue = imagesBundle
119: .getString(resourceName);
120: if (resourceValue.endsWith("gif"))
121: elementList.add(new Element(resourceName));
122: }
123: this .elements = (Element[]) elementList
124: .toArray(new Element[elementList.size()]);
125: Arrays.sort(this .elements);
126: }
127: return this .elements;
128: }
129:
130: /**
131: * Search all theme JARs in context class path for that which has a theme
132: * name corresponding to the name specified. If found, load the properties
133: * for the theme's images, and return it.
134: */
135: private ResourceBundle loadImagesBundle(String themeName,
136: Locale locale) {
137: ResourceBundle bundle = null;
138: try {
139: DesignProperty designProperty = this .getDesignProperty();
140: FacesDesignProject facesDesignProject = (FacesDesignProject) designProperty
141: .getDesignBean().getDesignContext().getProject();
142: ClassLoader loader = facesDesignProject
143: .getContextClassLoader();
144: Enumeration filesEnum = loader.getResources(MANIFEST_FILE);
145: while (filesEnum.hasMoreElements() && bundle == null) {
146: URL url = (URL) filesEnum.nextElement();
147: Manifest manifest = new Manifest(url.openConnection()
148: .getInputStream());
149: Attributes attributes = manifest
150: .getAttributes("com/sun/rave/web/ui/theme/");
151: if (attributes != null
152: && themeName.equals(attributes
153: .getValue(NAME_ATTRIBUTE))) {
154: String imagesBundleName = attributes
155: .getValue(IMAGES_ATTRIBUTE);
156: bundle = ResourceBundle.getBundle(imagesBundleName,
157: locale, loader);
158: }
159: }
160: } catch (IOException e) {
161: e.printStackTrace();
162: }
163: return bundle;
164: }
165:
166: }
|