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.modules.editor.mimelookup;
043:
044: import java.lang.reflect.Method;
045: import java.util.ArrayList;
046: import java.util.Collection;
047: import java.util.Collections;
048: import java.util.List;
049: import java.util.logging.Level;
050: import java.util.logging.Logger;
051: import org.netbeans.api.editor.mimelookup.MimePath;
052: import org.netbeans.spi.editor.mimelookup.MimeDataProvider;
053: import org.netbeans.spi.editor.mimelookup.MimeLookupInitializer;
054: import org.openide.util.Lookup;
055: import org.openide.util.LookupEvent;
056: import org.openide.util.LookupListener;
057: import org.openide.util.WeakListeners;
058: import org.openide.util.lookup.ProxyLookup;
059:
060: /**
061: *
062: * @author vita
063: */
064: @SuppressWarnings("deprecation")
065: public final class MimePathLookup extends ProxyLookup implements
066: LookupListener {
067:
068: private static final Logger LOG = Logger
069: .getLogger(MimePathLookup.class.getName());
070:
071: private MimePath mimePath;
072: private Lookup.Result<MimeDataProvider> dataProviders;
073: private Lookup.Result<MimeLookupInitializer> mimeInitializers; // This is supported for backwards compatibility only.
074:
075: /** Creates a new instance of MimePathLookup */
076: public MimePathLookup(MimePath mimePath) {
077: super ();
078:
079: if (mimePath == null) {
080: throw new NullPointerException("Mime path can't be null."); //NOI18N
081: }
082:
083: this .mimePath = mimePath;
084:
085: dataProviders = Lookup.getDefault().lookup(
086: new Lookup.Template<MimeDataProvider>(
087: MimeDataProvider.class));
088: dataProviders.addLookupListener(WeakListeners.create(
089: LookupListener.class, this , dataProviders));
090:
091: mimeInitializers = Lookup.getDefault().lookup(
092: new Lookup.Template<MimeLookupInitializer>(
093: MimeLookupInitializer.class));
094: mimeInitializers.addLookupListener(WeakListeners.create(
095: LookupListener.class, this , mimeInitializers));
096:
097: rebuild();
098: }
099:
100: public MimePath getMimePath() {
101: return mimePath;
102: }
103:
104: private void rebuild() {
105: ArrayList<Lookup> lookups = new ArrayList<Lookup>();
106:
107: // Add lookups from MimeDataProviders
108: for (MimeDataProvider provider : dataProviders.allInstances()) {
109: Lookup mimePathLookup = provider.getLookup(mimePath);
110: if (mimePathLookup != null) {
111: lookups.add(mimePathLookup);
112: }
113: }
114:
115: // XXX: This hack here is to make GSF and Schliemann frameworks work.
116: // Basically we should somehow enforce the composition of lookups
117: // for MimeDataProviders too. But some providers such as the one from
118: // editor/mimelookup/impl do the composition in their own way. So we
119: // will probably have to extend the SPI somehow to accomodate both simple
120: // providers and the composing ones.
121: // See also http://www.netbeans.org/issues/show_bug.cgi?id=118099
122:
123: // Add lookups from deprecated MimeLookupInitializers
124: List<String> paths;
125: try {
126: Method m = MimePath.class.getDeclaredMethod(
127: "getInheritedPaths", String.class, String.class); //NOI18N
128: m.setAccessible(true);
129: @SuppressWarnings("unchecked")
130: List<String> ret = (List<String>) m.invoke(mimePath, null,
131: null);
132: paths = ret;
133: } catch (Exception e) {
134: LOG
135: .log(
136: Level.WARNING,
137: "Can't call org.netbeans.api.editor.mimelookup.MimePath.getInheritedPaths method.",
138: e); //NOI18N
139: paths = Collections.singletonList(mimePath.getPath());
140: }
141:
142: for (String path : paths) {
143: MimePath mp = MimePath.parse(path);
144: Collection<? extends MimeLookupInitializer> initializers = mimeInitializers
145: .allInstances();
146:
147: for (int i = 0; i < mp.size(); i++) {
148: Collection<MimeLookupInitializer> children = new ArrayList<MimeLookupInitializer>(
149: initializers.size());
150:
151: for (MimeLookupInitializer mli : initializers) {
152: children.addAll(mli.child(mp.getMimeType(i))
153: .allInstances());
154: }
155:
156: initializers = children;
157: }
158:
159: for (MimeLookupInitializer mli : initializers) {
160: Lookup mimePathLookup = mli.lookup();
161: if (mimePathLookup != null) {
162: lookups.add(mimePathLookup);
163: }
164: }
165: }
166:
167: setLookups(lookups.toArray(new Lookup[lookups.size()]));
168: }
169:
170: //-------------------------------------------------------------
171: // LookupListener implementation
172: //-------------------------------------------------------------
173:
174: public void resultChanged(LookupEvent ev) {
175: rebuild();
176: }
177:
178: }
|