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 2002 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.settings;
043:
044: import java.io.IOException;
045:
046: import org.openide.filesystems.FileObject;
047: import org.openide.filesystems.FileSystem;
048: import org.openide.filesystems.Repository;
049: import org.openide.loaders.DataObject;
050: import org.openide.loaders.Environment;
051: import org.openide.util.Lookup;
052:
053: /** A provider for .settings files of a certain DTD.
054: * It creates a suitable convertor according to {@link #EA_CONVERTOR}.
055: *
056: * @author Jan Pokorsky
057: */
058: public final class Env implements Environment.Provider {
059: /** file attribute containing convertor object. Usage
060: * <code><attr name="settings.convertor" methodvalue="org.netbeans.modules.settings.XMLPropertiesConvertor.create"/>
061: * </code>
062: */
063: public final static String EA_CONVERTOR = "settings.convertor"; //NOI18N
064: /** file attribute containing path to the provider. Used by
065: * InstanceDataObject.create or upgrade algorithm. Usage
066: * <code><attr name="settings.providerPath" stringvalue="xml/lookups/NetBeans/DTD_XML_Properties_1_0.instance"/>
067: * </code>
068: */
069: public final static String EA_PROVIDER_PATH = "settings.providerPath"; // NOI18N
070: /** file attribute containing PUBLIC attribute of xml header. Usage
071: * <code><attr name="hint.originalPublicID" stringvalue="-//NetBeans//DTD XML Properties 1.0//EN"/>
072: * </code>
073: */
074: public final static String EA_PUBLICID = "hint.originalPublicID"; // NOI18N
075: /** file attribute containnig class name of the setting object. Usage
076: * <code><attr name="settings.instanceClass" stringvalue="org.netbeans.modules.foo.Foo"/>
077: * </code>
078: */
079: public final static String EA_INSTANCE_CLASS_NAME = "settings.instanceClass"; //NOI18N
080: /** file attribute containnig class name and subclass names of the setting object. Use the
081: * attribute for performance reasons. Usage
082: * <code><attr name="settings.instanceOf" stringvalue="org.netbeans.modules.foo.Foo[, ...]"/>
083: * </code>
084: */
085: public final static String EA_INSTANCE_OF = "settings.instanceOf"; //NOI18N
086: /** file attribute containnig the setting object. Usage
087: * <code><attr name="settings.instanceCreate" newvalue="org.netbeans.modules.foo.Foo"/>
088: * </code> or
089: * <code><attr name="settings.instanceCreate" methodvalue="org.netbeans.modules.foo.Foo.create"/>
090: * </code>
091: */
092: public final static String EA_INSTANCE_CREATE = "settings.instanceCreate"; //NOI18N
093: /** file attribute determining whether the registration works also for subclasses of the registering
094: * class. Use of this attribute is optional. The default is false, the value must be boolean, example:
095: * <code><attr name="settings.subclasses" boolvalue="true"/></code>
096: */
097: public static final String EA_SUBCLASSES = "settings.subclasses"; // NOI18N
098:
099: private final FileObject providerFO;
100:
101: /** create Environment.Provider */
102: public static Environment.Provider create(FileObject fo) {
103: return new Env(fo);
104: }
105:
106: private Env(FileObject fo) {
107: providerFO = fo;
108: }
109:
110: public Lookup getEnvironment(DataObject dobj) {
111: if (!(dobj instanceof org.openide.loaders.InstanceDataObject))
112: return Lookup.EMPTY;
113: InstanceProvider icp = new InstanceProvider(dobj, providerFO);
114: return icp.getLookup();
115: }
116:
117: /** parse file attribute
118: * @param attr String value can be null; used delimiter is ","
119: * @return set of items
120: */
121: public static java.util.Set<String> parseAttribute(Object attr) {
122: if (attr != null && attr instanceof String) {
123: java.util.StringTokenizer s = new java.util.StringTokenizer(
124: (String) attr, ","); //NOI18N
125: java.util.Set<String> set = new java.util.HashSet<String>(
126: 10);
127: while (s.hasMoreTokens()) {
128: set.add(s.nextToken().trim());
129: }
130: return set;
131: } else {
132: return java.util.Collections.emptySet();
133: }
134: }
135:
136: /** look up appropriate provider according to clazz */
137: public static FileObject findProvider(Class clazz)
138: throws IOException {
139: String prefix = "xml/memory/"; //NOI18N
140: FileSystem sfs = Repository.getDefault().getDefaultFileSystem();
141: FileObject memContext = sfs.findResource(prefix);
142: if (memContext == null)
143: throw new java.io.FileNotFoundException("SFS/xml/memory/"); //NOI18N
144: Class c = clazz;
145: while (c != null) {
146: String name = c.getName().replace('.', '/');
147: String convertorPath = new StringBuffer(200).append(prefix)
148: .append(name).toString(); // NOI18N
149: FileObject fo = sfs.findResource(convertorPath);
150: if (fo != null) {
151: String providerPath = (String) fo
152: .getAttribute(EA_PROVIDER_PATH);
153: if (providerPath != null) {
154: if (c.equals(clazz)) {
155: return sfs.findResource(providerPath);
156: } else {
157: // check the special subclasses attribute
158: Object inheritAttribute = fo
159: .getAttribute(EA_SUBCLASSES);
160: if (inheritAttribute instanceof Boolean) {
161: boolean subclasses = ((Boolean) inheritAttribute)
162: .booleanValue();
163: if (subclasses) {
164: return sfs.findResource(providerPath);
165: }
166: }
167: }
168: }
169: }
170: c = c.getSuperclass();
171: }
172: return null;
173: }
174:
175: private static String xmlLookupsPrefix = "xml/lookups"; // NOI18N
176: private static String xmlEntitiesPrefix = "xml/entities"; // NOI18N
177:
178: /** find an entity registration according to passed provider
179: * @param provider provider file object
180: * @return entity file object
181: */
182: public static FileObject findEntityRegistration(FileObject provider) {
183: String filename = provider.getPath();
184: int i = filename.lastIndexOf('.');
185: if (i != -1 && i > filename.lastIndexOf('/')) {
186: filename = filename.substring(0, i);
187: }
188: String resource = xmlEntitiesPrefix
189: + filename.substring(xmlLookupsPrefix.length(),
190: filename.length());
191:
192: return Repository.getDefault().getDefaultFileSystem()
193: .findResource(resource);
194: }
195: }
|