lookup/src/main/java/org/openide/util/lookup/InstanceContent.java
changeset 972 a2947558c966
parent 971 b3ae88304dd0
child 973 5653a70ebb56
     1.1 --- a/lookup/src/main/java/org/openide/util/lookup/InstanceContent.java	Wed Jan 27 17:46:23 2010 -0500
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,378 +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-2006 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 -package org.openide.util.lookup;
    1.45 -
    1.46 -import org.openide.util.lookup.AbstractLookup.Pair;
    1.47 -
    1.48 -import java.lang.ref.WeakReference;
    1.49 -
    1.50 -import java.util.*;
    1.51 -import java.util.concurrent.Executor;
    1.52 -import org.openide.util.Lookup.Item;
    1.53 -
    1.54 -
    1.55 -/** A special content implementation that can be passed to AbstractLookup
    1.56 - * and provides methods for registration of instances and lazy instances.
    1.57 - * <PRE>
    1.58 - *      InstanceContent ic = new InstanceContent ();
    1.59 - *      AbstractLookup al = new AbstractLookup (ic);
    1.60 - *
    1.61 - *      ic.add (new Object ());
    1.62 - *      ic.add (new Dimension (...));
    1.63 - *
    1.64 - *      Dimension theDim = (Dimension)al.lookup (Dimension.class);
    1.65 - * </PRE>
    1.66 - *
    1.67 - * @author  Jaroslav Tulach
    1.68 - *
    1.69 - * @since 1.25
    1.70 - */
    1.71 -public final class InstanceContent extends AbstractLookup.Content {
    1.72 -    /**
    1.73 -     * Create a new, empty content.
    1.74 -     */
    1.75 -    public InstanceContent() {
    1.76 -    }
    1.77 -
    1.78 -    /** Creates a content associated with an executor to handle dispatch
    1.79 -     * of changes.
    1.80 -     * @param notifyIn the executor to notify changes in
    1.81 -     * @since  7.16
    1.82 -     */
    1.83 -    public InstanceContent(Executor notifyIn) {
    1.84 -        super(notifyIn);
    1.85 -    }
    1.86 -    /** The method to add instance to the lookup with.
    1.87 -     * @param inst instance
    1.88 -     */
    1.89 -    public final void add(Object inst) {
    1.90 -        addPair(new SimpleItem<Object>(inst));
    1.91 -    }
    1.92 -
    1.93 -    /** Adds a convertible instance into the lookup. The <code>inst</code>
    1.94 -     * argument is just a key, not the actual value to appear in the lookup.
    1.95 -     * The value will be created on demand, later when it is really needed
    1.96 -     * by calling <code>convertor</code> methods.
    1.97 -     * <p>
    1.98 -     * This method is useful to delay creation of heavy weight objects.
    1.99 -     * Instead just register lightweight key and a convertor.
   1.100 -     * <p>
   1.101 -     * To remove registered object from lookup use {@link #remove(java.lang.Object, org.openide.util.lookup.InstanceContent.Convertor)}
   1.102 -     * with the same arguments.
   1.103 -     *
   1.104 -     * @param inst instance
   1.105 -     * @param conv convertor which postponing an instantiation,
   1.106 -     * if <code>conv==null</code> then the instance is registered directly.
   1.107 -     */
   1.108 -    public final <T,R> void add(T inst, Convertor<T,R> conv) {
   1.109 -        addPair(new ConvertingItem<T,R>(inst, conv));
   1.110 -    }
   1.111 -
   1.112 -    /** Remove instance.
   1.113 -     * @param inst instance
   1.114 -     */
   1.115 -    public final void remove(Object inst) {
   1.116 -        removePair(new SimpleItem<Object>(inst));
   1.117 -    }
   1.118 -
   1.119 -    /** Remove instance added with a convertor.
   1.120 -     * @param inst instance
   1.121 -     * @param conv convertor, if <code>conv==null</code> it is same like
   1.122 -     * remove(Object)
   1.123 -     */
   1.124 -    public final <T,R> void remove(T inst, Convertor<T,R> conv) {
   1.125 -        removePair(new ConvertingItem<T,R>(inst, conv));
   1.126 -    }
   1.127 -
   1.128 -    /** Changes all pairs in the lookup to new values. Converts collection of
   1.129 -     * instances to collection of pairs.
   1.130 -     * @param col the collection of (Item) objects
   1.131 -     * @param conv the convertor to use or null
   1.132 -     */
   1.133 -    public final <T,R> void set(Collection<T> col, Convertor<T,R> conv) {
   1.134 -        ArrayList<Pair<?>> l = new ArrayList<Pair<?>>(col.size());
   1.135 -        Iterator<T> it = col.iterator();
   1.136 -
   1.137 -        if (conv == null) {
   1.138 -            while (it.hasNext()) {
   1.139 -                l.add(new SimpleItem<T>(it.next()));
   1.140 -            }
   1.141 -        } else {
   1.142 -            while (it.hasNext()) {
   1.143 -                l.add(new ConvertingItem<T,R>(it.next(), conv));
   1.144 -            }
   1.145 -        }
   1.146 -
   1.147 -        setPairs(l);
   1.148 -    }
   1.149 -
   1.150 -    /** Convertor postpones an instantiation of an object.
   1.151 -     * @since 1.25
   1.152 -     */
   1.153 -    public static interface Convertor<T,R> {
   1.154 -        /** Convert obj to other object. There is no need to implement
   1.155 -         * cache mechanism. It is provided by
   1.156 -         * {@link Item#getInstance()} method itself. However the
   1.157 -         * method can be called more than once because instance is held
   1.158 -         * just by weak reference.
   1.159 -         *
   1.160 -         * @param obj the registered object
   1.161 -         * @return the object converted from this object
   1.162 -         */
   1.163 -        public R convert(T obj);
   1.164 -
   1.165 -        /** Return type of converted object. Accessible via
   1.166 -         * {@link Item#getType()}
   1.167 -         * @param obj the registered object
   1.168 -         * @return the class that will be produced from this object (class or
   1.169 -         *      superclass of convert (obj))
   1.170 -         */
   1.171 -        public Class<? extends R> type(T obj);
   1.172 -
   1.173 -        /** Computes the ID of the resulted object. Accessible via
   1.174 -         * {@link Item#getId()}.
   1.175 -         * @param obj the registered object
   1.176 -         * @return the ID for the object
   1.177 -         */
   1.178 -        public String id(T obj);
   1.179 -
   1.180 -        /** The human presentable name for the object. Accessible via
   1.181 -         * {@link Item#getDisplayName()}.
   1.182 -         * @param obj the registered object
   1.183 -         * @return the name representing the object for the user
   1.184 -         */
   1.185 -        public String displayName(T obj);
   1.186 -    }
   1.187 -
   1.188 -    /** Instance of one item representing an object.
   1.189 -     */
   1.190 -    final static class SimpleItem<T> extends Pair<T> {
   1.191 -        private T obj;
   1.192 -
   1.193 -        /** Create an item.
   1.194 -         * @obj object to register
   1.195 -         */
   1.196 -        public SimpleItem(T obj) {
   1.197 -            if (obj == null) {
   1.198 -                throw new NullPointerException();
   1.199 -            }
   1.200 -            this.obj = obj;
   1.201 -        }
   1.202 -
   1.203 -        /** Tests whether this item can produce object
   1.204 -         * of class c.
   1.205 -         */
   1.206 -        public boolean instanceOf(Class<?> c) {
   1.207 -            return c.isInstance(obj);
   1.208 -        }
   1.209 -
   1.210 -        /** Get instance of registered object. If convertor is specified then
   1.211 -         *  method InstanceLookup.Convertor.convertor is used and weak reference
   1.212 -         * to converted object is saved.
   1.213 -         * @return the instance of the object.
   1.214 -         */
   1.215 -        public T getInstance() {
   1.216 -            return obj;
   1.217 -        }
   1.218 -
   1.219 -        @Override
   1.220 -        public boolean equals(Object o) {
   1.221 -            if (o instanceof SimpleItem) {
   1.222 -                return obj.equals(((SimpleItem) o).obj);
   1.223 -            } else {
   1.224 -                return false;
   1.225 -            }
   1.226 -        }
   1.227 -
   1.228 -        @Override
   1.229 -        public int hashCode() {
   1.230 -            return obj.hashCode();
   1.231 -        }
   1.232 -
   1.233 -        /** An identity of the item.
   1.234 -         * @return string representing the item, that can be used for
   1.235 -         *   persistance purposes to locate the same item next time
   1.236 -         */
   1.237 -        public String getId() {
   1.238 -            return "IL[" + obj.toString(); // NOI18N
   1.239 -        }
   1.240 -
   1.241 -        /** Getter for display name of the item.
   1.242 -         */
   1.243 -        public String getDisplayName() {
   1.244 -            return obj.toString();
   1.245 -        }
   1.246 -
   1.247 -        /** Method that can test whether an instance of a class has been created
   1.248 -         * by this item.
   1.249 -         *
   1.250 -         * @param obj the instance
   1.251 -         * @return if the item has already create an instance and it is the same
   1.252 -         *  as obj.
   1.253 -         */
   1.254 -        protected boolean creatorOf(Object obj) {
   1.255 -            return obj == this.obj;
   1.256 -        }
   1.257 -
   1.258 -        /** The class of this item.
   1.259 -         * @return the correct class
   1.260 -         */
   1.261 -        @SuppressWarnings("unchecked")
   1.262 -        public Class<? extends T> getType() {
   1.263 -            return (Class<? extends T>)obj.getClass();
   1.264 -        }
   1.265 -    }
   1.266 -     // end of SimpleItem
   1.267 -
   1.268 -    /** Instance of one item registered in the map.
   1.269 -     */
   1.270 -    final static class ConvertingItem<T,R> extends Pair<R> {
   1.271 -        /** registered object */
   1.272 -        private T obj;
   1.273 -
   1.274 -        /** Reference to converted object. */
   1.275 -        private WeakReference<R> ref;
   1.276 -
   1.277 -        /** convertor to use */
   1.278 -        private Convertor<? super T,R> conv;
   1.279 -
   1.280 -        /** Create an item.
   1.281 -         * @obj object to register
   1.282 -         * @conv a convertor, can be <code>null</code>.
   1.283 -         */
   1.284 -        public ConvertingItem(T obj, Convertor<? super T,R> conv) {
   1.285 -            this.obj = obj;
   1.286 -            this.conv = conv;
   1.287 -        }
   1.288 -
   1.289 -        /** Tests whether this item can produce object
   1.290 -         * of class c.
   1.291 -         */
   1.292 -        public boolean instanceOf(Class<?> c) {
   1.293 -            return c.isAssignableFrom(getType());
   1.294 -        }
   1.295 -
   1.296 -        /** Returns converted object or null if obj has not been converted yet
   1.297 -         * or reference was cleared by garbage collector.
   1.298 -         */
   1.299 -        private R getConverted() {
   1.300 -            if (ref == null) {
   1.301 -                return null;
   1.302 -            }
   1.303 -
   1.304 -            return ref.get();
   1.305 -        }
   1.306 -
   1.307 -        /** Get instance of registered object. If convertor is specified then
   1.308 -         *  method InstanceLookup.Convertor.convertor is used and weak reference
   1.309 -         * to converted object is saved.
   1.310 -         * @return the instance of the object.
   1.311 -         */
   1.312 -        public synchronized R getInstance() {
   1.313 -            R converted = getConverted();
   1.314 -
   1.315 -            if (converted == null) {
   1.316 -                converted = conv.convert(obj);
   1.317 -                ref = new WeakReference<R>(converted);
   1.318 -            }
   1.319 -
   1.320 -            return converted;
   1.321 -        }
   1.322 -
   1.323 -        @Override
   1.324 -        public boolean equals(Object o) {
   1.325 -            if (o instanceof ConvertingItem) {
   1.326 -                return obj.equals(((ConvertingItem) o).obj);
   1.327 -            } else {
   1.328 -                return false;
   1.329 -            }
   1.330 -        }
   1.331 -
   1.332 -        @Override
   1.333 -        public int hashCode() {
   1.334 -            return obj.hashCode();
   1.335 -        }
   1.336 -
   1.337 -        /** An identity of the item.
   1.338 -         * @return string representing the item, that can be used for
   1.339 -         *   persistance purposes to locate the same item next time
   1.340 -         */
   1.341 -        public String getId() {
   1.342 -            return conv.id(obj);
   1.343 -        }
   1.344 -
   1.345 -        /** Getter for display name of the item.
   1.346 -         */
   1.347 -        public String getDisplayName() {
   1.348 -            return conv.displayName(obj);
   1.349 -        }
   1.350 -
   1.351 -        /** Method that can test whether an instance of a class has been created
   1.352 -         * by this item.
   1.353 -         *
   1.354 -         * @param obj the instance
   1.355 -         * @return if the item has already create an instance and it is the same
   1.356 -         *  as obj.
   1.357 -         */
   1.358 -        protected boolean creatorOf(Object obj) {
   1.359 -            if (conv == null) {
   1.360 -                return obj == this.obj;
   1.361 -            } else {
   1.362 -                return obj == getConverted();
   1.363 -            }
   1.364 -        }
   1.365 -
   1.366 -        /** The class of this item.
   1.367 -         * @return the correct class
   1.368 -         */
   1.369 -        @SuppressWarnings("unchecked")
   1.370 -        public Class<? extends R> getType() {
   1.371 -            R converted = getConverted();
   1.372 -
   1.373 -            if (converted == null) {
   1.374 -                return conv.type(obj);
   1.375 -            }
   1.376 -
   1.377 -            return (Class<? extends R>)converted.getClass();
   1.378 -        }
   1.379 -    }
   1.380 -     // end of ConvertingItem
   1.381 -}