1.1 --- a/lookup/src/main/java/org/openide/util/lookup/doc-files/lookup-api.html Wed Jan 27 17:46:23 2010 -0500
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,188 +0,0 @@
1.4 -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
1.5 -<!--
1.6 - - DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
1.7 - -
1.8 - - Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
1.9 - -
1.10 - - The contents of this file are subject to the terms of either the GNU
1.11 - - General Public License Version 2 only ("GPL") or the Common
1.12 - - Development and Distribution License("CDDL") (collectively, the
1.13 - - "License"). You may not use this file except in compliance with the
1.14 - - License. You can obtain a copy of the License at
1.15 - - http://www.netbeans.org/cddl-gplv2.html
1.16 - - or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
1.17 - - specific language governing permissions and limitations under the
1.18 - - License. When distributing the software, include this License Header
1.19 - - Notice in each file and include the License file at
1.20 - - nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
1.21 - - particular file as subject to the "Classpath" exception as provided
1.22 - - by Sun in the GPL Version 2 section of the License file that
1.23 - - accompanied this code. If applicable, add the following below the
1.24 - - License Header, with the fields enclosed by brackets [] replaced by
1.25 - - your own identifying information:
1.26 - - "Portions Copyrighted [year] [name of copyright owner]"
1.27 - -
1.28 - - Contributor(s):
1.29 - -
1.30 - - The Original Software is NetBeans. The Initial Developer of the Original
1.31 - - Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
1.32 - - Microsystems, Inc. All Rights Reserved.
1.33 - -
1.34 - - If you wish your version of this file to be governed by only the CDDL
1.35 - - or only the GPL Version 2, indicate your decision by adding
1.36 - - "[Contributor] elects to include this software in this distribution
1.37 - - under the [CDDL or GPL Version 2] license." If you do not indicate a
1.38 - - single choice of license, a recipient has the option to distribute
1.39 - - your version of this file under either the CDDL, the GPL Version 2 or
1.40 - - to extend the choice of license to its licensees as provided above.
1.41 - - However, if you add GPL Version 2 code and therefore, elected the GPL
1.42 - - Version 2 license, then the option applies only if the new code is
1.43 - - made subject to such option by the copyright holder.
1.44 - -->
1.45 -<HTML>
1.46 -<HEAD>
1.47 -<TITLE>Lookup Library API</TITLE>
1.48 -<link rel="Stylesheet" href="@TOP@/prose.css" type="text/css" title="NetBeans Open APIs Style">
1.49 -</HEAD>
1.50 -<BODY>
1.51 -<H1>Lookup library API</H1>
1.52 -<p>
1.53 -This document describes usage of the API provided by the Lookup Library. In this
1.54 -document we assume that someone has already provided us with a lookup
1.55 -implementation (for those seeking how to write a lookup implementation please
1.56 -check <A href="lookup-spi.html">the SPI document</A>).
1.57 -
1.58 -<H2> Getting the lookup </H2>
1.59 -
1.60 -The first question you might ask is this: how can I get hold of a
1.61 -lookup instance? There are basically two ways how you can get it.
1.62 -
1.63 -<H3> Global lookup </H3>
1.64 -As you can see in the
1.65 -
1.66 -<a href="@TOP@org/openide/util/Lookup.html">Lookup</a>
1.67 -
1.68 -Javadoc there is a static method
1.69 -
1.70 -<pre><a href="@TOP@org/openide/util/Lookup.html#getDefault()">public static Lookup getDefault()</a></pre>
1.71 -
1.72 -The object returned from this method is
1.73 -a global lookup that can serve as a central place for registering services.
1.74 -The default implementation is a lookup that implements
1.75 -<a href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#Service%20Provider">
1.76 -the JDK JAR services</A>
1.77 -mechanism and delegates to <samp>META-INF/services/name.of.Class</samp> files.
1.78 -<P>
1.79 -If you want to add your class to this lookup just create a file in your
1.80 -jar file under the <code>META-INF</code> directory (e.g. <samp>META-INF/services/com.my.APIClass</samp>)
1.81 -and let the file contain only one line of text
1.82 -
1.83 -<pre>com.foo.impl.ImplOfTheAPI</pre>
1.84 -
1.85 -<p>(This is more easily done using the <code>@ServiceProvider</code> annotation.)</p>
1.86 -
1.87 -The following code will return you a newly created instance of
1.88 -<code>com.foo.impl.ImplOfTheAPI</code>:
1.89 -
1.90 -<PRE>
1.91 - <font class="keyword">import</FONT> org.openide.util.Lookup;
1.92 - return Lookup.getDefault().lookup(com.my.APIClass.class);
1.93 -</PRE>
1.94 -
1.95 -<H3> Local lookup </H3>
1.96 -
1.97 -This is just a reminder that whenever you find a method called getLookup
1.98 -or similar returning a lookup instance, the provided lookup is <EM>not</EM> the
1.99 -general lookup described in the previous paragraph. Rather, it is a private lookup
1.100 -implementation that is usually bound to the object you invoked the method on.
1.101 -
1.102 -<H2> Use of Lookup.Template and Lookup.Result </H2>
1.103 -
1.104 -There are more ways how you can ask lookup besides the variant with one class
1.105 -parameter. If you want more functionality, you have to implement the interface
1.106 -Lookup.Template and pass an instance of such object to the lookup call.
1.107 -<p>
1.108 -<EM>Note:</EM> If you use Lookup.Template, the object returned from the lookup is
1.109 -<EM>not</EM> the object you are looking for but rather a result object
1.110 -(Lookup.Result). You can call methods on such a result object to get the actual
1.111 -results.
1.112 -<p>
1.113 -Let's examine following example:
1.114 -
1.115 -<pre>
1.116 - <font class="keyword">import</FONT> org.openide.util.Lookup;
1.117 -
1.118 - <font class="type">Lookup</font> <font class="variable-name">lookup</font> = ...;
1.119 - Lookup.<font class="type">Template</font> <font class="variable-name">template</font> = <font class="keyword">new</font> Lookup.<font class="type">Template</font>(MyService.<font class="keyword">class</font>);
1.120 - Lookup.<font class="type">Result</font> <font class="variable-name">result</font> = lookup.lookup(template);
1.121 - <font class="type">Collection</font> <font class="variable-name">c</font> = result.allInstances();
1.122 - <font class="keyword">for</font> (<font class="type">Iterator</font> <font class="variable-name">i</font> = c.iterator(); i.hasNext(); ) {
1.123 - <font class="type">MyService</font> <font class="variable-name">s</font> = (<font class="type">MyService</font>)i.next();
1.124 - s.callMyService();
1.125 - }
1.126 -</pre>
1.127 -
1.128 -In this example the call to method lookup(...) returns immediately because the
1.129 -result object can be constructed even without real results. The first time you
1.130 -ask for the result object by calling r.allInstances(), the lookup has to supply you
1.131 -the real results and this method can block until the required data are really
1.132 -available.
1.133 -<p>
1.134 -If you are not interested in all objects as in the previous example, you can use the
1.135 -template to ask for one resulting object (wrapped in special Item instance):
1.136 -<pre>
1.137 - <font class="keyword">import</FONT> org.openide.util.Lookup;
1.138 -
1.139 - <font class="type">Lookup</font> <font class="variable-name">lookup</font> = ...;
1.140 - Lookup.<font class="type">Template</font> <font class="variable-name">template</font> = <font class="keyword">new</font> Lookup.<font class="type">Template</font>(MyService.<font class="keyword">class</font>);
1.141 - Lookup.<font class="type">Item</font> <font class="variable-name">item</font> = lookup.lookupItem(template);
1.142 - <font class="type">MyService</font> <font class="variable-name">s</font> = (<font class="type">MyService</font>)item.getInstance();
1.143 - s.callMyService();
1.144 -</pre>
1.145 -
1.146 -Again, the Item object can construct the real instance only if you call
1.147 -getInstance. The item can be useful even without calling getInstance - you can get
1.148 -its display name or an unique id. You can use this information, for example, for
1.149 -constructing menu items without the need to instantiate (or even load!)
1.150 -the class implementing the functionality. Only when the real functionality is
1.151 -needed (e.g. the user has selected the menu item) you can call getInstance
1.152 -and call the real meat of the implementation.
1.153 -
1.154 -<H2> Listenning on lookup changes </H2>
1.155 -There is one additional piece of functionality bound to the Lookup.Result object worth
1.156 -mentioning: you can attach a listener to it and be informed about any changes in
1.157 -the lookup. This might be extremly usefull when the lookup dynamically changes
1.158 -(from other threads). The listener can keep state of your object up-to-date even
1.159 -in cases where the lookup changes asynchronously.
1.160 -<p>
1.161 -So here is some sample code using the listenner:
1.162 -
1.163 -<pre>
1.164 - <font class="keyword">import</FONT> org.openide.util.Lookup;
1.165 - <font class="keyword">import</FONT> org.openide.util.LookupListener;
1.166 - <font class="keyword">import</FONT> org.openide.util.LookupEvent;
1.167 -
1.168 - <font class="type">Lookup</font> <font class="variable-name">lookup</font> = ...;
1.169 - Lookup.<font class="type">Template</font> <font class="variable-name">template</font> = <font class="keyword">new</font> Lookup.<font class="type">Template</font>(MyService.<font class="keyword">class</font>);
1.170 - <font class="keyword">final</font> <font class="variable-name">Lookup</font>.<font class="type">Result</font> <font class="variable-name">result</font> = lookup.lookup(template);
1.171 - result.addLookupListener(<font class="keyword">new</font> <font class="type">LookupListener</font>() {
1.172 - <font class="keyword">public</font> <font class="type">void</font> <font class="function-name">resultChanged</font>(<font class="type">LookupEvent</font> <font class="variable-name">e</font>) {
1.173 - reaction(result);
1.174 - }
1.175 - });
1.176 - reaction(result);
1.177 - }
1.178 - <font class="keyword">private</font> <font class="keyword">static</font> <font class="type">void</font> <font class="function-name">reaction</font>(Lookup.<font class="type">Result</font> <font class="variable-name">r</font>) {
1.179 - <font class="keyword">for</font> (<font class="type">Iterator</font> <font class="variable-name">i</font> = r.allInstances().iterator(); i.hasNext(); ) {
1.180 - <font class="type">MyService</font> <font class="variable-name">s</font> = (<font class="type">MyService</font>)i.next();
1.181 - s.callMyService();
1.182 - }
1.183 - }
1.184 -</pre>
1.185 -
1.186 -Please note that we first attach a listener and then call the reaction method.
1.187 -This ensures that we always get the newest possible state. Also you must be
1.188 -careful in the reaction method since it can be called from two different
1.189 -threads simultaneously (your code has to be prepared for this).
1.190 -</BODY>
1.191 -</HTML>