lookup/src/main/java/org/openide/util/lookup/Lookups.java
changeset 972 a2947558c966
parent 971 b3ae88304dd0
child 973 5653a70ebb56
     1.1 --- a/lookup/src/main/java/org/openide/util/lookup/Lookups.java	Wed Jan 27 17:46:23 2010 -0500
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,317 +0,0 @@
     1.4 -/*
     1.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     1.6 - *
     1.7 - * Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
     1.8 - *
     1.9 - * The contents of this file are subject to the terms of either the GNU
    1.10 - * General Public License Version 2 only ("GPL") or the Common
    1.11 - * Development and Distribution License("CDDL") (collectively, the
    1.12 - * "License"). You may not use this file except in compliance with the
    1.13 - * License. You can obtain a copy of the License at
    1.14 - * http://www.netbeans.org/cddl-gplv2.html
    1.15 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    1.16 - * specific language governing permissions and limitations under the
    1.17 - * License.  When distributing the software, include this License Header
    1.18 - * Notice in each file and include the License file at
    1.19 - * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    1.20 - * particular file as subject to the "Classpath" exception as provided
    1.21 - * by Sun in the GPL Version 2 section of the License file that
    1.22 - * accompanied this code. If applicable, add the following below the
    1.23 - * License Header, with the fields enclosed by brackets [] replaced by
    1.24 - * your own identifying information:
    1.25 - * "Portions Copyrighted [year] [name of copyright owner]"
    1.26 - *
    1.27 - * Contributor(s):
    1.28 - *
    1.29 - * The Original Software is NetBeans. The Initial Developer of the Original
    1.30 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2009 Sun
    1.31 - * Microsystems, Inc. All Rights Reserved.
    1.32 - *
    1.33 - * If you wish your version of this file to be governed by only the CDDL
    1.34 - * or only the GPL Version 2, indicate your decision by adding
    1.35 - * "[Contributor] elects to include this software in this distribution
    1.36 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
    1.37 - * single choice of license, a recipient has the option to distribute
    1.38 - * your version of this file under either the CDDL, the GPL Version 2 or
    1.39 - * to extend the choice of license to its licensees as provided above.
    1.40 - * However, if you add GPL Version 2 code and therefore, elected the GPL
    1.41 - * Version 2 license, then the option applies only if the new code is
    1.42 - * made subject to such option by the copyright holder.
    1.43 - */
    1.44 -
    1.45 -package org.openide.util.lookup;
    1.46 -
    1.47 -import java.util.Arrays;
    1.48 -import org.netbeans.modules.openide.util.NamedServicesProvider;
    1.49 -import org.openide.util.Lookup;
    1.50 -
    1.51 -/**
    1.52 - * Static factory methods for creating common lookup implementations.
    1.53 - *
    1.54 - * @author David Strupl
    1.55 - * @since 2.21
    1.56 - */
    1.57 -public class Lookups {
    1.58 -
    1.59 -    /** static methods only */
    1.60 -    private Lookups() {}
    1.61 -
    1.62 -    /**
    1.63 -     * Creates a singleton lookup. It means lookup that contains only
    1.64 -     * one object specified via the supplied parameter. The lookup will
    1.65 -     * either return the object or null if the supplied template does
    1.66 -     * not match the class. If the specified argument is null the method
    1.67 -     * will end with NullPointerException.
    1.68 -     * @return Fully initialized lookup object ready to use
    1.69 -     * @throws NullPointerException if the supplied argument is null
    1.70 -     * @since 2.21
    1.71 -     */
    1.72 -    public static Lookup singleton(Object objectToLookup) {
    1.73 -        if (objectToLookup == null) {
    1.74 -            throw new NullPointerException();
    1.75 -        }
    1.76 -
    1.77 -        return new SingletonLookup(objectToLookup);
    1.78 -    }
    1.79 -
    1.80 -    /**
    1.81 -     * Creates a lookup that contains an array of objects specified via the
    1.82 -     * parameter. The resulting lookup is fixed in the following sense: it
    1.83 -     * contains only fixed set of objects passed in by the array parameter.
    1.84 -     * Its contents never changes so registering listeners on such lookup
    1.85 -     * does not have any observable effect (the listeners are never called).
    1.86 -     *
    1.87 -     * @param objectsToLookup list of objects to include
    1.88 -     * @return Fully initialized lookup object ready to use
    1.89 -     * @throws NullPointerException if the supplied argument is null
    1.90 -     * @since 2.21
    1.91 -     *
    1.92 -     */
    1.93 -    public static Lookup fixed(Object... objectsToLookup) {
    1.94 -        if (objectsToLookup == null) {
    1.95 -            throw new NullPointerException();
    1.96 -        }
    1.97 -
    1.98 -        if (objectsToLookup.length == 0) {
    1.99 -            return Lookup.EMPTY;
   1.100 -        }
   1.101 -
   1.102 -        if (objectsToLookup.length == 1) {
   1.103 -            return singleton(objectsToLookup[0]);
   1.104 -        }
   1.105 -
   1.106 -        return new SimpleLookup(Arrays.asList(objectsToLookup));
   1.107 -    }
   1.108 -
   1.109 -    /**
   1.110 -     * Creates a lookup that contains an array of objects specified via the
   1.111 -     * parameter. The resulting lookup is fixed in the following sense: it
   1.112 -     * contains only fixed set of objects passed in by the array parameter.
   1.113 -     * The objects returned from this lookup are converted to real objects
   1.114 -     * before they are returned by the lookup.
   1.115 -     * Its contents never changes so registering listeners on such lookup
   1.116 -     * does not have any observable effect (the listeners are never called).
   1.117 -     *
   1.118 -     * @return Fully initialized lookup object ready to use
   1.119 -     * @throws NullPointerException if the any of the arguments is null
   1.120 -     * @since 2.21
   1.121 -     *
   1.122 -     */
   1.123 -    public static <T,R> Lookup fixed(T[] keys, InstanceContent.Convertor<? super T,R> convertor) {
   1.124 -        if (keys == null) {
   1.125 -            throw new NullPointerException();
   1.126 -        }
   1.127 -
   1.128 -        if (convertor == null) {
   1.129 -            throw new NullPointerException();
   1.130 -        }
   1.131 -
   1.132 -        return new SimpleLookup(Arrays.asList(keys), convertor);
   1.133 -    }
   1.134 -
   1.135 -    /** Creates a lookup that delegates to another one but that one can change
   1.136 -     * from time to time. The returned lookup checks every time somebody calls
   1.137 -     * <code>lookup</code> or <code>lookupItem</code> method whether the
   1.138 -     * provider still returns the same lookup. If not, it updates state of
   1.139 -     * all {@link org.openide.util.Lookup.Result}s 
   1.140 -     * that it created (and that still exists).
   1.141 -     * <P>
   1.142 -     * The user of this method has to implement its provider's <code>getLookup</code>
   1.143 -     * method (must be thread safe and fast, will be called often and from any thread)
   1.144 -     * pass it to this method and use the returned lookup. Whenever the user
   1.145 -     * changes the return value from the <code>getLookup</code> method and wants
   1.146 -     * to notify listeners on the lookup about that it should trigger the event
   1.147 -     * firing, for example by calling <code>lookup.lookup (Object.class)</code>
   1.148 -     * directly on the lookup returned by this method
   1.149 -     * that forces a check of the return value of {@link org.openide.util.Lookup.Provider#getLookup}</code>.
   1.150 -     *
   1.151 -     * @param provider the provider that returns a lookup to delegate to
   1.152 -     * @return lookup delegating to the lookup returned by the provider
   1.153 -     * @since 3.9
   1.154 -     */
   1.155 -    public static Lookup proxy(Lookup.Provider provider) {
   1.156 -        return new SimpleProxyLookup(provider);
   1.157 -    }
   1.158 -
   1.159 -    /** Returns a lookup that implements the JDK1.3 JAR services mechanism and delegates
   1.160 -     * to META-INF/services/name.of.class files.
   1.161 -     * <p>Some extensions to the JAR services specification are implemented:
   1.162 -     * <ol>
   1.163 -     * <li>An entry may be followed by a line of the form <code>#position=<i>integer</i></code>
   1.164 -     *     to specify ordering. (Smaller numbers first, entries with unspecified position last.)
   1.165 -     * <li>A line of the form <code>#-<i>classname</i></code> suppresses an entry registered
   1.166 -     *     in another file, so can be used to supersede one implementation with another.
   1.167 -     * </ol>
   1.168 -     * <p>Note: It is not dynamic - so if you need to change the classloader or JARs,
   1.169 -     * wrap it in a {@link ProxyLookup} and change the delegate when necessary.
   1.170 -     * Existing instances will be kept if the implementation classes are unchanged,
   1.171 -     * so there is "stability" in doing this provided some parent loaders are the same
   1.172 -     * as the previous ones.
   1.173 -     * @since 3.35
   1.174 -     * @see ServiceProvider
   1.175 -     */
   1.176 -    public static Lookup metaInfServices(ClassLoader classLoader) {
   1.177 -        return new MetaInfServicesLookup(classLoader, "META-INF/services/"); // NOI18N
   1.178 -    }
   1.179 -
   1.180 -    /** Returns a lookup that behaves exactly like {@link #metaInfServices(ClassLoader)}
   1.181 -     * except that it does not read data from <code>META-INF/services/</code>, but instead
   1.182 -     * from the specified prefix.
   1.183 -     * @param classLoader class loader to use for loading
   1.184 -     * @param prefix prefix to prepend to the class name when searching
   1.185 -     * @since 7.9
   1.186 -     */
   1.187 -    public static Lookup metaInfServices(ClassLoader classLoader, String prefix) {
   1.188 -        return new MetaInfServicesLookup(classLoader, prefix);
   1.189 -    }
   1.190 -    
   1.191 -    /** Creates a <q>named</q> lookup.
   1.192 -     * It is a lookup identified by a given path.
   1.193 -     * Two lookups with the same path should have the same content.
   1.194 -     * <p>It is expected that each <q>named</q> lookup
   1.195 -     * will contain a superset of what would be created by:
   1.196 -     * <code>{@linkplain #metaInfServices(ClassLoader,String) metaInfServices}(theRightLoader, "META-INF/namedservices/" + path + "/")</code>
   1.197 -     *
   1.198 -     * <p class="nonnormative">Various environments can add their own
   1.199 -     * extensions to its content. As such
   1.200 -     * {@link Lookups#forPath(java.lang.String)} can combine lookups
   1.201 -     * from several sources. In current NetBeans Runtime Container, two lookups are used:
   1.202 -     * </p>
   1.203 -     * <ul class="nonnormative">
   1.204 -     * <li><code>Lookups.metaInfServices("META-INF/namedservices/" + path)</code></li>
   1.205 -     * <li><code>org.openide.loaders.FolderLookup(path)</code></li>
   1.206 -     * </ul>
   1.207 -     * <p class="nonnormative">
   1.208 -     * Please note that these lookups differ in the way they inspect sub-folders.
   1.209 -     * The first lookup just returns instances from the given path, ignoring
   1.210 -     * sub-folders, the second one retrieves instances from the whole sub-tree.
   1.211 -     * </p>
   1.212 -     * <p>
   1.213 -     * Read more about the <a href="@org-openide-util@/org/openide/util/doc-files/api.html#folderlookup">usage of this method</a>.
   1.214 -     * 
   1.215 -     * @param path the path identifying the lookup, e.g. <code>Projects/Actions</code>
   1.216 -     * @return lookup associated with this path
   1.217 -     * @since 7.9
   1.218 -     */
   1.219 -    public static Lookup forPath(String path) {
   1.220 -        return NamedServicesProvider.find(path);
   1.221 -    }
   1.222 -    
   1.223 -    /** Creates a lookup that wraps another one and filters out instances
   1.224 -     * of specified classes. If you have a lookup and
   1.225 -     * you want to remove all instances of ActionMap you can use:
   1.226 -     * <pre>
   1.227 -     * l = Lookups.exclude(lookup, ActionMap.class);
   1.228 -     * </pre>
   1.229 -     * Then anybody who asks for <code>l.lookup(ActionMap.class)</code> or
   1.230 -     * subclass will get <code>null</code>. Even if the original lookup contains the
   1.231 -     * value.
   1.232 -     * To create empty lookup (well, just an example, otherwise use {@link Lookup#EMPTY}) one could use:
   1.233 -     * <pre>
   1.234 -     * Lookup.exclude(anyLookup, Object.class);
   1.235 -     * </pre>
   1.236 -     * as any instance in any lookup is of type Object and thus would be excluded.
   1.237 -     * <p>
   1.238 -     * The complete behavior can be described as <code>classes</code> being
   1.239 -     * a barrier. For an object not to be excluded, there has to be an inheritance
   1.240 -     * path between the queried class and the actual class of the instance,
   1.241 -     * that is not blocked by any of the excluded classes:
   1.242 -     * <pre>
   1.243 -     * interface A {}
   1.244 -     * interface B {}
   1.245 -     * class C implements A, B {}
   1.246 -     * Object c = new C();
   1.247 -     * Lookup l1 = Lookups.singleton(c);
   1.248 -     * Lookup l2 = Lookups.exclude(l1, A.class);
   1.249 -     * assertNull("A is directly excluded", l2.lookup(A.class));
   1.250 -     * assertEquals("Returns C as A.class is not between B and C", c, l2.lookup(B.class));
   1.251 -     * </pre>
   1.252 -     * For more info check the
   1.253 -     * <a href="http://hg.netbeans.org/main-golden/annotate/4883eaeda744/openide.util/test/unit/src/org/openide/util/lookup/ExcludingLookupTest.java">
   1.254 -     * excluding lookup tests</a> and the discussion in issue
   1.255 -     * <a href="http://openide.netbeans.org/issues/show_bug.cgi?id=53058">53058</a>.
   1.256 -     *
   1.257 -     * @param lookup the original lookup that should be filtered
   1.258 -     * @param classes array of classes those instances should be excluded
   1.259 -     * @since 5.4
   1.260 -     */
   1.261 -    public static Lookup exclude(Lookup lookup, Class... classes) {
   1.262 -        return new ExcludingLookup(lookup, classes);
   1.263 -    }
   1.264 -
   1.265 -    /** Creates <code>Lookup.Item</code> representing the instance passed in.
   1.266 -     *
   1.267 -     * @param instance the object for which Lookup.Item should be creted
   1.268 -     * @param id unique identification of the object, for details see {@link org.openide.util.Lookup.Item#getId},
   1.269 -     * can be <code>null</code>
   1.270 -     * @return lookup item representing instance
   1.271 -     * @since 4.8
   1.272 -     */
   1.273 -    public static <T> Lookup.Item<T> lookupItem(T instance, String id) {
   1.274 -        return new LookupItem<T>(instance, id);
   1.275 -    }
   1.276 -
   1.277 -    private static class LookupItem<T> extends Lookup.Item<T> {
   1.278 -        private String id;
   1.279 -        private T instance;
   1.280 -
   1.281 -        public LookupItem(T instance) {
   1.282 -            this(instance, null);
   1.283 -        }
   1.284 -
   1.285 -        public LookupItem(T instance, String id) {
   1.286 -            this.id = id;
   1.287 -            this.instance = instance;
   1.288 -        }
   1.289 -
   1.290 -        public String getDisplayName() {
   1.291 -            return getId();
   1.292 -        }
   1.293 -
   1.294 -        public String getId() {
   1.295 -            return (id == null) ? instance.toString() : id;
   1.296 -        }
   1.297 -
   1.298 -        public T getInstance() {
   1.299 -            return instance;
   1.300 -        }
   1.301 -
   1.302 -        @SuppressWarnings("unchecked")
   1.303 -        public Class<? extends T> getType() {
   1.304 -            return (Class<? extends T>)instance.getClass();
   1.305 -        }
   1.306 -
   1.307 -        public @Override boolean equals(Object object) {
   1.308 -            if (object instanceof LookupItem) {
   1.309 -                return instance == ((LookupItem) object).getInstance();
   1.310 -            }
   1.311 -
   1.312 -            return false;
   1.313 -        }
   1.314 -
   1.315 -        public @Override int hashCode() {
   1.316 -            return instance.hashCode();
   1.317 -        }
   1.318 -    }
   1.319 -     // End of LookupItem class
   1.320 -}