1.1 --- a/openide.util/src/org/openide/util/doc-files/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,1233 +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 -
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 -
1.46 -<html>
1.47 -<head>
1.48 -<title>Utility Classes</title>
1.49 -<link rel="Stylesheet" href="../../../../prose.css" type="text/css" title="NetBeans Open APIs Style">
1.50 -</head>
1.51 -<body>
1.52 -
1.53 -<p class="overviewlink"><a href="@TOP@overview-summary.html">Overview</a></p>
1.54 -
1.55 -<h1>Utility Classes</h1>
1.56 -
1.57 -Not all of the classes in this package are of interest for all module
1.58 -writers, but some of them may or even are as they are used through out
1.59 -our sources.
1.60 -
1.61 -<h2>Package <a href="../package-summary.html"><code>org.openide.util</code></a></h2>
1.62 -
1.63 -<ol>
1.64 - <li><a href="@org-openide-util-lookup@/org/openide/util/Lookup.html">Lookup</a> and its associated
1.65 - <a href="@org-openide-util-lookup@/org/openide/util/lookup/package-summary.html">support package</a> as that
1.66 - is the <em>adaptable</em> interface that objects can provide if
1.67 - they wish to offer dynamic capabilities.
1.68 - </li>
1.69 -
1.70 - <li><a href="../NbBundle.html">NbBundle</a> as our specialized support
1.71 - for localization and replacement to
1.72 - <a href="@JDK@/java/util/ResourceBundle.html">ResourceBundle</a>.
1.73 - </li>
1.74 -
1.75 - <li><a href="../Task.html"><code>Task</code></a> and especially
1.76 - <a href="../RequestProcessor.html"><code>RequestProcessor</code></a> which
1.77 - is our way to manage pools of thread workers and execute asynchronous
1.78 - computations.
1.79 - </li>
1.80 -
1.81 - <li>
1.82 - <a href="../HelpCtx.html"><code>HelpCtx</code></a> to specify help ids for
1.83 - various UI components
1.84 - </li>
1.85 -
1.86 - <li>
1.87 - <a href="../Utilities.html"><code>Utilities</code></a> which contain
1.88 - a lot of methods of possible interest. For example
1.89 - <a href="../Utilities.html#actionsGlobalContext()"><code>actionsGlobalContext</code></a>,
1.90 - <a href="../Utilities.html#loadImage(java.lang.String)"><code>loadImage</code></a>,
1.91 - <a href="../Utilities.html#mergeImages(java.awt.Image,%20java.awt.Image,%20int,%20int)"><code>mergeImage</code></a>,
1.92 - <a href="../Utilities.html#topologicalSort(java.util.Collection,%20java.util.Map)"><code>topologicalSort</code></a>,
1.93 - <a href="../Utilities.html#activeReferenceQueue()"><code>activeReferenceQueue</code></a>,
1.94 - <a href="../Utilities.html#translate(java.lang.String)"><code>translate</code></a>.
1.95 - </li>
1.96 -
1.97 - <li>
1.98 - <a href="../Enumerations.html"><code>Enumerations</code></a> provide
1.99 - enhacened support for manipulation with
1.100 - <a href="@JDK@/java/util/Enumeration.html">Enumeration</a>s and especially
1.101 - their on-demand generation.
1.102 - </li>
1.103 -</ol>
1.104 -
1.105 -<!--
1.106 -<li><a href="../io/package-summary.html"><code>org.openide.util.io</code></a>:
1.107 -
1.108 -a few extensions to the Java I/O system.
1.109 -
1.110 -<li><a href="../../xml/package-summary.html"><code>org.openide.xml</code></a>:
1.111 -
1.112 -general XML parsing, entity registration, and so on.
1.113 --->
1.114 -
1.115 -</a><h2>Services Registration and Lookup API</h2>
1.116 -
1.117 -
1.118 -<p>For lookup, this centers around
1.119 -
1.120 -<a href="@org-openide-util-lookup@/org/openide/util/Lookup.html"><code>Lookup</code></a>
1.121 -
1.122 -and helper implementations in
1.123 -
1.124 -<a href="@org-openide-util-lookup@/org/openide/util/lookup/package-summary.html"><code>org.openide.util.lookup</code></a>.
1.125 -
1.126 -
1.127 -
1.128 -<h3>Contents</h3>
1.129 -
1.130 -<ul>
1.131 -
1.132 -<li><a href="#lookup">Lookup</a>
1.133 -<ul>
1.134 -<li><a href="#instances">Working with Instances</a>
1.135 -<li><a href="#instance-folders">Folders of Instances</a>
1.136 -<li><a href="#service-lookup">Lookup and Service Installation</a>
1.137 -<li><a href="#lookup-ids">Persisting Lookup Information</a>
1.138 -<li><a href="#lookup-impl">Creating Lookups</a>
1.139 -<li><a href="#settings">Settings</a>
1.140 -<li><a href="#lookup-ui">UI for Services</a>
1.141 -</ul>
1.142 -
1.143 -</ul>
1.144 -
1.145 -
1.146 -<h2><a name="lookup">Lookup</a></h2>
1.147 -
1.148 -<div class="nonnormative">
1.149 -
1.150 -The whole NetBeans platform is moving toward
1.151 -installation of services via XML layer or (via the <code>@ServiceProvider</code> annotation on classes) <code>META-INF/services</code>.
1.152 -Layer-based installation is more flexible in many ways.
1.153 -
1.154 -<p>The need for having a standard interface to access such
1.155 -registrations
1.156 -gave rise to the <em>lookup</em> system first
1.157 -introduced in NetBeans 3.2 and expanded upon for NetBeans 3.3. The
1.158 -center of this API from the client perspective is very simple - you
1.159 -can look up a class, and get an instance of that class (or a
1.160 -collection of them). The service provider side of it is more complex
1.161 -but useful lookup implementations are already provided in the
1.162 -core system; for common cases you can register an object into lookup just by
1.163 -adding one simple file to an XML layer or <code>META-INF/services/classname</code>
1.164 -in your module JAR file.
1.165 -
1.166 -<p>This section of the Services API will first discuss what
1.167 -<em>instances</em> are and how to create them from files, as this is
1.168 -the core concept for service providers. It will discuss how you can
1.169 -manually retrieve sets of instances as a client, which is not used
1.170 -very frequently in new code but helps to understand what lookup is
1.171 -doing behind the scenes. Then lookup itself is discussed, and how the
1.172 -standard instance lookup works and how it relates to JDK's
1.173 -<a href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#Service%20Provider">
1.174 -standard for service provider registration</a>.
1.175 -Lookup templates, which separate the
1.176 -provision of instances from the provision of categories, will be
1.177 -explained.
1.178 -
1.179 -</div>
1.180 -
1.181 -<h3><a name="instances">Working with Instances</a></h3>
1.182 -
1.183 -Central to the management of services and many other aspects of
1.184 -NetBeans' configuration is the notion of
1.185 -<em>instances</em>. An instance is just any Java object, generally
1.186 -of a particular type appropriate to its use, which is provided from
1.187 -some object (generally, a data object) using
1.188 -
1.189 -<code>InstanceCookie</code>.
1.190 -
1.191 -As an example, menu items may be added by inserting data objects
1.192 -that provide this cookie into the proper folder, and having the
1.193 -instance be a system action (or other things). Or an XML DTD may be
1.194 -registered by placing an object with an instance of
1.195 -<code>org.xml.sax.EntityResolver</code> in the proper folder.
1.196 -
1.197 -<p>Where do these instances come from? Technically, it is up to you
1.198 -to decide how to provide <code>InstanceCookie</code>; you could if
1.199 -really necessary create your own data loader that provides it
1.200 -according to some unusual scheme, and add files recognized by that
1.201 -loader to the right folder. Practically, the APIs provide
1.202 -implementations of this cookie sufficient for normal purposes.
1.203 -
1.204 -<p>The most common way to provide an instance is using
1.205 -
1.206 -<code>InstanceDataObject</code>.
1.207 -
1.208 -This is a type of data object whose sole purpose is to provide the
1.209 -instance cookie. It typically does so based on a class name you
1.210 -supply. There are several styles of instance file; all are empty (i.e.
1.211 -the file contents are of zero length, and just the file name and
1.212 -attributes matter). There are then other ways of providing instances
1.213 -which rely on the file contents. Here are the methods of providing
1.214 -instances defined in the APIs:
1.215 -
1.216 -<dl>
1.217 -
1.218 -<dt><em>Default instance - <code>InstanceDataObject</code></em>
1.219 -
1.220 -<dd><p>If there is a file with the extension <samp>*.instance</samp>, then its
1.221 -name (minus extension) will be converted to a class name by replacing dashes
1.222 -with dots; and a fresh instance of that class will be created and used as the
1.223 -instance. For example, <samp>com-mycom-mymodule-MyAction.instance</samp>
1.224 -produces an instance of the class <code>com.mycom.mymodule.MyAction</code>.</p>
1.225 -
1.226 -<p>Since reflection is used to create the new instance, just as in the
1.227 -realm of JavaBeans, the class must be loadable from your module or
1.228 -otherwise from within NetBeans (technically, via the classloader found
1.229 -by querying Lookup for <code>ClassLoader</code>);
1.230 -public; and have a public no-argument constructor.
1.231 -(Or be a
1.232 -
1.233 -<a href="../SharedClassObject.html"><code>SharedClassObject</code></a>.)
1.234 -
1.235 -This form is often
1.236 -used for <em>singleton</em> classes such as system actions: there is
1.237 -no need to specify any parameters to the constructor, any instance
1.238 -will suffice.</p>
1.239 -
1.240 -
1.241 -<dt><em>Default instance with separate class - <code>InstanceDataObject</code></em>
1.242 -
1.243 -<dd><p>Rather than shoving the class name into
1.244 -the file name, you can name the file more normally and specify the
1.245 -class with a file attribute. Then the class name is specified as
1.246 -a string-valued attribute on the instance named
1.247 -<code>instanceClass</code>. For example, a keyboard shortcut
1.248 -could be registered as follows in an XML layer:</p>
1.249 -
1.250 -<pre>
1.251 -<<font class="function-name">file</font> <font class="variable-name">name</font>=<font class="constant">"C-F6.instance"</font>>
1.252 - <<font class="function-name">attr</font> <font class="variable-name">name</font>=<font class="constant">"instanceClass"</font> <font class="variable-name">stringvalue</font>=<font class="constant">"com.mycom.mymodule.MyAction"</font>/>
1.253 -</<font class="function-name">file</font>>
1.254 -</pre>
1.255 -
1.256 -<p>In addition to <code>instanceClass</code> you may specify an
1.257 -additional attribute <code>instanceOf</code> giving the name of a
1.258 -superclass (or implemented interface) of the instance class. In fact
1.259 -it may be a comma-separated list of superclasses and interfaces. While
1.260 -its purpose is explained more fully
1.261 -
1.262 -<a href="#instance-folders">below</a>,
1.263 -
1.264 -essentially it lets you give the system a hint as to what this
1.265 -instance is for before your instance class is even loaded into the VM.
1.266 -For example:</p>
1.267 -
1.268 -<pre>
1.269 -<<font class="function-name">file</font> <font class="variable-name">name</font>=<font class="constant">"com-me-some-service.instance"</font>>
1.270 - <<font class="function-name">attr</font> <font class="variable-name">name</font>=<font class="constant">"instanceClass"</font> <font class="variable-name">stringvalue</font>=<font class="constant">"com.me.FactoryForEverything"</font>/>
1.271 - <<font class="function-name">attr</font> <font class="variable-name">name</font>=<font class="constant">"instanceOf"</font>
1.272 - <font class="variable-name">stringvalue</font>=<font class="constant">"org.xml.sax.EntityResolver,org.openide.cookies.ExecCookie"</font>/>
1.273 -</<font class="function-name">file</font>>
1.274 -</pre>
1.275 -
1.276 -<dt><a name="ido-methodvalue"></a><em>Non-default instance - <code>InstanceDataObject</code></em>
1.277 -
1.278 -<dd><p>A powerful way of providing instances is to use the expressiveness
1.279 -of the XML layer syntax to handle the instance creation. In this case
1.280 -the file attribute <code>instanceCreate</code> can be defined and the
1.281 -attribute value becomes the instance. Typically the attribute value
1.282 -would be specified using the <code>methodvalue</code> syntax of
1.283 -layers. For example:</p>
1.284 -
1.285 -<pre>
1.286 -<<font class="function-name">file</font> <font class="variable-name">name</font>=<font class="constant">"com-me-some-service.instance"</font>>
1.287 - <<font class="function-name">attr</font> <font class="variable-name">name</font>=<font class="constant">"instanceClass"</font> <font class="variable-name">stringvalue</font>=<font class="constant">"com.me.FactoryForEverything"</font>/>
1.288 - <<font class="function-name">attr</font> <font class="variable-name">name</font>=<font class="constant">"instanceCreate"</font> <font class="variable-name">methodvalue</font>=<font class="constant">"com.me.FactoryForEverything.configure"</font>/>
1.289 - <<font class="function-name">attr</font> <font class="variable-name">name</font>=<font class="constant">"myParam"</font> <font class="variable-name">urlvalue</font>=<font class="constant">"nbres:/com/me/config-1.properties"</font>/>
1.290 - <<font class="function-name">attr</font> <font class="variable-name">name</font>=<font class="constant">"instanceOf"</font>
1.291 - <font class="variable-name">stringvalue</font>=<font class="constant">"org.xml.sax.EntityResolver,org.openide.cookies.ExecCookie"</font>/>
1.292 -</<font class="function-name">file</font>>
1.293 -</pre>
1.294 -
1.295 -<p>According to the general system for
1.296 -
1.297 -<code>XMLFileSystem</code>,
1.298 -
1.299 -you now need a method <code>configure</code> in
1.300 -<code>FactoryForEverything</code> which must be static; the method
1.301 -need not be public (if you do not want other Java code to see it). It
1.302 -may take a file object as argument if you wish - this will be the
1.303 -instance file; typically you use this to pass extra configuration from
1.304 -the layer, useful if you want to create multiple instances with the
1.305 -same creation method. So for example you might implement such a method
1.306 -like this:</p>
1.307 -
1.308 -<pre>
1.309 -<font class="keyword">public</font> <font class="keyword">class</font> <font class="type">FactoryForEverything</font> <font class="keyword">extends</font> <font class="type">SomeBaseFactory</font>
1.310 - <font class="keyword">implements</font> <font class="type">EntityResolver</font>, <font class="type">ExecCookie</font> {
1.311 - <font class="keyword">public</font> <font class="type">FactoryForEverything</font>(<font class="type">Map</font> <font class="variable-name">props</font>) {
1.312 - <font class="comment">// ...
1.313 -</font> }
1.314 - <font class="comment">// ...
1.315 -</font> <font class="comment">// Called directly from XML layer. Pass URL to
1.316 -</font> <font class="comment">// properties file from attr 'myParam'.
1.317 -</font> <font class="keyword">private</font> <font class="keyword">static</font> <font class="type">Object</font> <font class="function-name">configure</font>(<font class="type">FileObject</font> <font class="variable-name">inst</font>) <font class="keyword">throws</font> <font class="type">IOException</font> {
1.318 - <font class="type">URL</font> <font class="variable-name">u</font> = (<font class="type">URL</font>)inst.getAttribute(<font class="string">"myParam"</font>);
1.319 - <font class="type">Properties</font> <font class="variable-name">p</font> = <font class="keyword">new</font> <font class="type">Properties</font>();
1.320 - p.load(u.openStream());
1.321 - <font class="keyword">return</font> <font class="keyword">new</font> <font class="type">FactoryForEverything</font>(p);
1.322 - }
1.323 -}
1.324 -</pre>
1.325 -
1.326 -<dt><em>Serialized beans</em>
1.327 -
1.328 -<dd><p>A simple way to provide an instance is to serialize it as a
1.329 -JavaBean, into a file with the extension <samp>*.ser</samp>. This is
1.330 -not very useful from a layer, because you should avoid putting
1.331 -binary data into a layer, but may be useful in some circumstances.</p>
1.332 -
1.333 -<dt><a name="xml-instances"><em>XML-based instances</em></a></dt>
1.334 -
1.335 -
1.336 -<a href="../../xml/EntityCatalog.html"><code>EntityCatalog</code></a>
1.337 -
1.338 -
1.339 -<div class="nonnormative">
1.340 -
1.341 -<p>Again, modules may also have additional ways of providing instances
1.342 -from files. For example, currently the <code>utilities</code> module
1.343 -enables any URL file (<samp>*.url</samp>) to be used directly in a
1.344 -menu, as the URL file provides an instance of
1.345 -<code>Presenter.Menu</code>.</p>
1.346 -
1.347 -<p>As an interactive demonstration of these things, first go into
1.348 -<b>Filesystem Settings</b> and make the system filesystem (first in
1.349 -the list) visible; then explore its contents in <b>Filesystems</b>,
1.350 -going into some subdirectory of <samp>Menu</samp>. Note the various
1.351 -actions and menu separators; these are all by default instance data
1.352 -objects.
1.353 -You may find some of these on disk in your installation directory
1.354 -under <samp>system/</samp> if you have customized them, but by default
1.355 -they live in memory only.
1.356 -You may copy-and-paste these instances from one place to another;
1.357 -create new ones on disk and watch them be recognized and inserted
1.358 -into the menus after a few seconds; and you may also choose
1.359 -Customize Bean (which really customizes the provided instance) on
1.360 -(say) a toolbar separator (under <code>Toolbars</code>) to change
1.361 -the separator size, and serialize the result to a new
1.362 -<code>*.ser</code> file which should then create a toolbar
1.363 -separator.
1.364 -
1.365 -</div>
1.366 -
1.367 -<h3><a name="instance-folders">Folders of Instances</a></h3>
1.368 -
1.369 -
1.370 -<h4><a name="instancecookie-of"><code>InstanceCookie.Of</code> and lazy class loading</a></h4>
1.371 -
1.372 -Now it is time to mention the purpose of
1.373 -<code>InstanceCookie.Of</code>. Suppose that there are two generic
1.374 -interfaces under consideration: e.g. <code>javax.swing.Action</code>
1.375 -and <code>org.xml.sax.EntityResolver</code>. For each interface, there
1.376 -is code to find registered instances, all under the
1.377 -<samp>Services/</samp> folder. Furthermore, using either of these
1.378 -interfaces is relatively rare, and might not happen at all during a
1.379 -NetBeans session; and the implementations of the instances are complicated
1.380 -and involve a lot of code, so it is undesirable (for performance
1.381 -reasons) to load these implementations unless and until they are
1.382 -really needed. If you write the layers simply like this:
1.383 -
1.384 -<pre>
1.385 -<<font class="function-name">filesystem</font>>
1.386 - <<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"Services"</font>>
1.387 - <<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"Hidden"</font>>
1.388 - <<font class="function-name">file</font> <font class="variable-name">name</font>=<font class="string">"com-me-MyAction.instance"</font>/>
1.389 - <<font class="function-name">file</font> <font class="variable-name">name</font>=<font class="string">"com-me-MyResolver.instance"</font>/>
1.390 - </<font class="function-name">folder</font>>
1.391 - </<font class="function-name">folder</font>>
1.392 -</<font class="function-name">filesystem</font>>
1.393 -</pre>
1.394 -
1.395 -everything will work, <em>but</em> this is inefficient. Consider some
1.396 -piece of code asking for all actions. The search through the services
1.397 -folder for actions would ask each of these files if it provides an
1.398 -instance cookie assignable to <code>javax.swing.Action</code>. For
1.399 -<samp>com-me-MyAction.instance</samp>, this will load the class
1.400 -<code>com.me.MyAction</code>, determine that it implements
1.401 -<code>Action</code>, and thus create a <code>MyAction</code> instance
1.402 -and return it; so far so good. But when
1.403 -<samp>com-me-MyResolver.instance</samp> is encountered, it will again
1.404 -load <code>com.me.MyResolver</code>, only to find that this does not
1.405 -implement <code>Action</code> and skip the instance. The behavior is
1.406 -correct, but now the <code>MyResolver</code> class has been loaded
1.407 -into the VM even though no one will ever use it (unless a resolver
1.408 -search is made). This will degrade startup time and memory usage (and
1.409 -thus performance).
1.410 -
1.411 -<p>So the better solution is to mark each file in advance, saying what
1.412 -interfaces it is intended to provide in its instance:
1.413 -
1.414 -<pre>
1.415 -<<font class="function-name">filesystem</font>>
1.416 - <<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"Services"</font>>
1.417 - <<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"Hidden"</font>>
1.418 - <<font class="function-name">file</font> <font class="variable-name">name</font>=<font class="string">"com-me-MyAction.instance"</font>>
1.419 - <<font class="function-name">attr</font> <font class="variable-name">name</font>=<font class="string">"instanceOf"</font> <font class="variable-name">stringvalue</font>=<font class="string">"javax.swing.Action"</font>/>
1.420 - </<font class="function-name">file</font>>
1.421 - <<font class="function-name">file</font> <font class="variable-name">name</font>=<font class="string">"com-me-MyResolver.instance"</font>>
1.422 - <<font class="function-name">attr</font> <font class="variable-name">name</font>=<font class="string">"instanceOf"</font> <font class="variable-name">stringvalue</font>=<font class="string">"org.xml.sax.EntityResolver"</font>/>
1.423 - </<font class="function-name">file</font>>
1.424 - </<font class="function-name">folder</font>>
1.425 - </<font class="function-name">folder</font>>
1.426 -</<font class="function-name">filesystem</font>>
1.427 -</pre>
1.428 -
1.429 -<p>
1.430 -Now the folder instance processor for <code>Action</code> will pass
1.431 -over <samp>com-me-MyResolver.instance</samp> without needing to load
1.432 -<code>com.me.MyResolver</code>, since it sees that its interfaces are
1.433 -declared, and <code>Action</code> is not among them. Of course, the
1.434 -interface classes - <code>Action</code> and
1.435 -<code>EntityResolver</code> - need to be loaded right away, but they
1.436 -were probably already loaded anyway, so this is acceptable.
1.437 -</p>
1.438 -
1.439 -<p><strong>Caution:</strong> if you do supply an
1.440 -<code>instanceOf</code> attribute, but it does <em>not</em> list all
1.441 -of the implemented interfaces and superclasses of the actual
1.442 -implementation class (including that implementation class itself,
1.443 -which is not implied), a lookup query on one of the missing
1.444 -superclasses <em>may or may not</em> succeed. So you should include in
1.445 -<code>instanceOf</code> any superclasses and interfaces that you think
1.446 -someone might use in a lookup query, possibly including the actual
1.447 -implementation class.</p>
1.448 -
1.449 -<h3><a name="service-lookup">Lookup and Service Installation</a></h3>
1.450 -
1.451 -The client side of the lookup system centers around one class,
1.452 -
1.453 -<a href="@org-openide-util-lookup@/org/openide/util/Lookup.html"><code>Lookup</code></a>.
1.454 -
1.455 -In the simplest usage, all that is needed is to get some single
1.456 -instance of a given class (or subclass). For example, if some kind of
1.457 -service has been defined as an interface or abstract class, and you
1.458 -wish to find the implementation of it, you
1.459 -may simply use:
1.460 -
1.461 -<pre>
1.462 -<font class="type">MyService</font> <font class="variable-name">impl</font> = (<font class="type">MyService</font>)Lookup.getDefault().<a href="@org-openide-util-lookup@/org/openide/util/Lookup.html#lookup(java.lang.Class)">lookup</a>(MyService.<font class="keyword">class</font>);
1.463 -<font class="keyword">if</font> (impl == <font class="constant">null</font>) <font class="comment">/* nothing registered */</font> ...
1.464 -impl.useIt();
1.465 -</pre>
1.466 -
1.467 -Such implementation has to be registered by some module to the system.
1.468 -Either via layer as described above or as a JDK's
1.469 -<a href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#Service%20Provider">
1.470 -service provider</a>. If some module wants to register for example
1.471 -<font class="type">org.me.MyService</font> it shall provide file name
1.472 -<font class="function-name">META-INF/services/org.me.MyService</FONT> in its own JAR
1.473 -with single line containing name of the implementation class (for example
1.474 -<font class="type">org.you.MyServiceImpl</FONT>).
1.475 -This is normally done more easily by using the <code>@ServiceProvider</code> annotation in <code>MyService.java</code>.
1.476 -The lookup infrastructure
1.477 -will then load the implementation class and call its default constructor
1.478 -to answer the query in the above example.
1.479 -<P>
1.480 -
1.481 -<div class="nonnormative">
1.482 - The Lookup supports two small extensions to the
1.483 - <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#Service%20Provider">JDK's
1.484 - standard</a>. It allows a module to remove class registered by
1.485 - another one. That is why it is possible to write a module that
1.486 - disables the <font class="type">org.you.MyServiceImpl</font> implementation
1.487 - and provides its own. This the expected content of its
1.488 - <font class="function-name">META-INF/services/org.me.MyService</FONT> file:
1.489 - <PRE>
1.490 - # remove the other implementation (by prefixing the line with <em>#-</EM>)
1.491 - #-<font class="type">org.you.MyServiceImpl</FONT>
1.492 -
1.493 - # provide my own
1.494 - org.alien.MyServiceAlienImpl
1.495 - </PRE>
1.496 - The reason why the removal line starts with <em>#-</em> is to keep
1.497 - compatibility with JDK's implementation. The <em>#</em> means comment
1.498 - and thus JDK will not interpret the line and will not get confused by
1.499 - the <em>-</em> before class name.
1.500 -
1.501 - <p>Second extension allows ordering of items. The class implementing
1.502 - the interface can be followed by advisory position attribute. If
1.503 - multiple implementations are defined in one file then each can be
1.504 - followed by its own positioning attribute. When querying
1.505 - on an interface, items with a smaller position are guaranteed
1.506 - to be returned before items with a larger position. Items with no defined
1.507 - position are returned last. Example of content of
1.508 - <font class="function-name">META-INF/services/org.me.MyService</font>
1.509 - file could be:
1.510 - <pre>
1.511 - <font class="type">org.you.MyServiceImpl</font>
1.512 - #position=20
1.513 - <font class="type">org.you.MyMoreImportantServiceImpl</font>
1.514 - #position=10
1.515 - </pre>
1.516 - The <font class="function-name">MyMoreImportantServiceImpl</font>
1.517 - will be returned in lookup before the
1.518 - <font class="function-name">MyServiceImpl</font>.
1.519 - It is recommended to pick up larger numbers so that there is
1.520 - gap for other modules if they need to get in front of your item. And,
1.521 - again, to keep compatibility the position attribute must starts with
1.522 - comment delimiter.</p>
1.523 -<p>Both extensions are supported by <code>@ServiceProvider</code>.</p>
1.524 -</DIV>
1.525 -
1.526 -<P>
1.527 -If more than one implementation has been registered, the "first" will
1.528 -be returned. For example, if the implementations were present in the
1.529 -<samp>Services</samp> folder as <samp>*.instance</samp> files, then
1.530 -folder order would control this.
1.531 -
1.532 -<p>As mentioned above, the NetBeans default lookup searches in the
1.533 -<samp>Services</samp> folder and its subfolders for instances whose
1.534 -class matches the requested class. Technically, it looks for data
1.535 -objects with <code>InstanceCookie.Of</code> claiming to match the
1.536 -requested superclass, or plain <code>InstanceCookie</code> whose
1.537 -<code>instanceClass</code> is assignable to it.
1.538 -
1.539 -<p>Note that you may use this method to find singleton instances of
1.540 -subclasses of
1.541 -
1.542 -<a href="../SharedClassObject.html"><code>SharedClassObject</code></a>
1.543 -
1.544 -that have been registered in lookup (as is normally the case for
1.545 -
1.546 -system options).
1.547 -
1.548 -However for this purpose it is simpler to use the static finder method
1.549 -
1.550 -<a href="../SharedClassObject.html#findObject(java.lang.Class,%20boolean)"><code>SharedClassObject.findObject(Class, true)</code></a>
1.551 -
1.552 -which is guaranteed to find the singleton whether it was registered in
1.553 -lookup or not (if necessary it will first
1.554 -
1.555 -<a href="#settings">initialize</a>
1.556 -
1.557 -the object according to saved state).
1.558 -
1.559 -<p>In many situations it is normal for there to be more than one
1.560 -registered implementation of a service. In such a case you use a more
1.561 -general method:
1.562 -
1.563 -<pre>
1.564 -<font class="type"><a href="@org-openide-util-lookup@/org/openide/util/Lookup.Template.html">Lookup.Template</a></font> <font class="variable-name">templ</font> = <font class="keyword">new</font> <font class="type">Lookup.Template</font>(MyService.<font class="keyword">class</font>);
1.565 -<font class="keyword">final</font> <font class="type"><a href="@org-openide-util-lookup@/org/openide/util/Lookup.Result.html">Lookup.Result</a></font> <font class="variable-name">result</font> = Lookup.getDefault().lookup(templ);
1.566 -<font class="type">Collection</font> <font class="variable-name">impls</font> = result.allInstances(); <font class="comment">// Collection<MyService>
1.567 -// use Java Collections API to get iterator, ...
1.568 -// Pay attention to subsequent changes in the result.
1.569 -</font>result.addLookupListener(<font class="keyword">new</font> <font class="type"><a href="@org-openide-util-lookup@/org/openide/util/LookupListener.html">LookupListener</a></font>() {
1.570 - <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">ev</font>) {
1.571 - <font class="comment">// Now it is different.
1.572 -</font> <font class="type">Collection</font> <font class="variable-name">impls2</font> = result.allInstances();
1.573 - <font class="comment">// use the new list of instances...
1.574 -</font> }
1.575 -});
1.576 -</pre>
1.577 -
1.578 -Here you receive a collection of all instances matching your query,
1.579 -again in the order found if this matters. You can also listen to
1.580 -changes in the list (additions, deletions, and reorderings). It is
1.581 -fine to keep a <code>Lookup.Result</code> for a long period of time as
1.582 -it may implement its own caching scheme and only really compute the
1.583 -instances when <code>allInstances</code> is called; in fact it may be
1.584 -more efficient to keep a result, and listen for changes in it, than to
1.585 -repeatedly call <code>lookup</code> and create fresh result objects.
1.586 -
1.587 -<p>When a lookup query is finished - for example when
1.588 -<code>Lookup.Result.allInstances()</code> returns some
1.589 -<code>Collection</code> of instances - it is guaranteed that all
1.590 -objects registered in the same thread prior to the call to
1.591 -<code>lookup()</code> or prior to some change notification on the
1.592 -<code>Lookup.Result</code>, will be returned. Specifically, lookup
1.593 -instances registered via module layer will be available by the time
1.594 -<code>ModuleInstall.restored()</code> (or <code>.installed()</code>)
1.595 -is called. There are two situations in which lookup results may be
1.596 -incomplete: when you are currently inside the dynamic scope of some
1.597 -method providing a lookup instance itself; and when you are
1.598 -dynamically inside a <code>DataLoader</code> method involved in
1.599 -recognizing data objects.
1.600 -
1.601 -<h3><a name="lookup-ids">Persisting Lookup Information</a></h3>
1.602 -
1.603 -In some circumstances it is necessary to not only find registered
1.604 -objects, but to select some of them and make this selection
1.605 -persistent. For example, some setting may have as its value a choice
1.606 -among available services matching some interface; the value needs to
1.607 -be persisted, but it is the identity of the choice, rather than the
1.608 -full state of the instance itself, which must be stored.
1.609 -
1.610 -<p>In such cases it is possible to use code like this:
1.611 -
1.612 -<pre>
1.613 -<font class="type">Lookup.Template</font> <font class="variable-name">templ</font> = <font class="keyword">new</font> <font class="type">Lookup.Template</font>(MyService.<font class="keyword">class</font>);
1.614 -<font class="type">Lookup.Result</font> <font class="variable-name">result</font> = Lookup.getDefault().lookup(templ);
1.615 -<font class="type">Iterator</font> <font class="variable-name">it</font> = result.allItems().iterator();
1.616 -<font class="keyword">while</font> (it.hasNext()) {
1.617 - <font class="type"><a href="@org-openide-util-lookup@/org/openide/util/Lookup.Item.html">Lookup.Item</a></font> <font class="variable-name">item</font> = (<font class="type">Lookup.Item</font>)it.next();
1.618 - <font class="type">String</font> <font class="variable-name">displayName</font> = item.getDisplayName();
1.619 - <font class="keyword">if</font> (<font class="comment">/* user accepts displayName as the right one */</font>) {
1.620 - <font class="type">MyService</font> <font class="variable-name">instance</font> = (<font class="type">MyService</font>)item.getInstance();
1.621 - <font class="comment">// use instance for now, and ...
1.622 -</font> <font class="type">String</font> <font class="variable-name">id</font> = item.getId();
1.623 - someSettings.setChosenService(id);
1.624 - <font class="keyword">break</font>;
1.625 - }
1.626 -}
1.627 -<font class="comment">// later...
1.628 -</font><font class="type">String</font> <font class="variable-name">storedID</font> = someSettings.getChosenService();
1.629 -<font class="type">Lookup.Template</font> <font class="variable-name">templ</font> = <font class="keyword">new</font> <font class="type"><a href="@org-openide-util-lookup@/org/openide/util/Lookup.Template.html#Lookup.Template(java.lang.Class,java.lang.String,java.lang.Object)">Lookup.Template</a></font>(MyService.<font class="keyword">class</font>, storedID, <font class="constant">null</font>);
1.630 -<font class="type">Iterator</font> <font class="variable-name">it</font> = Lookup.getDefault().lookup(templ).allInstances().iterator();
1.631 -<font class="keyword">if</font> (! it.hasNext()) <font class="comment">/* failed to find it... */</font>
1.632 -<font class="type">MyService</font> <font class="variable-name">instance</font> = (<font class="type">MyService</font>)it.next();
1.633 -<font class="comment">// use instance again
1.634 -</font></pre>
1.635 -
1.636 -The ID permits you to track which instance from all those available in
1.637 -the lookup result was last selected by the user, and find the "same"
1.638 -instance later, perhaps after a restart of NetBeans. The exact form of
1.639 -the ID is the private knowledge of the implementor of the lookup, but
1.640 -typically if the instance has been provided via layer the ID will
1.641 -mention the name of the file from which it was derived.
1.642 -
1.643 -<h3><a name="lookup-impl">Creating Lookups</a></h3>
1.644 -
1.645 -There are a number of reasons to create your own lookup
1.646 -implementation. For one thing, the lookup system which scans the
1.647 -<samp>Services/</samp> folder will recognize instances of subclasses
1.648 -of <code>Lookup</code> specially by <em>proxying</em> to them. This
1.649 -can be very powerful because you may register just one layer file
1.650 -which points to your custom lookup, which in turn may provide an
1.651 -unlimited number of actual instances/items for queries (and compute
1.652 -them in a manner other than registration by files). Another reason is
1.653 -to associate a context with a data object using
1.654 -
1.655 -<code>Environment.Provider</code>;
1.656 -
1.657 -for example the data object might be an XML file and this provider
1.658 -might be registered with the file by means of the public ID of the
1.659 -doctype (informally, the DTD). Here the provider has an associated
1.660 -lookup which can serve requests for cookies and such things.
1.661 -See more information about <a href="#xml-instances">associating lookups
1.662 -with XML files</a>.
1.663 -
1.664 -<p>The simplest way to create a fresh lookup is to base it on other
1.665 -existing ones.
1.666 -
1.667 -<a href="@org-openide-util-lookup@/org/openide/util/lookup/ProxyLookup.html"><code>ProxyLookup</code></a>
1.668 -
1.669 -accepts a list of other lookup implementations (in the constructor and
1.670 -also changeable later). The results it provides are constructed by
1.671 -merging together the results of the delegate lookups.
1.672 -
1.673 -<p>
1.674 -<a name="folderlookup"></a>
1.675 -
1.676 -If you want to use the common mechanism of finding instances in
1.677 -folders (or subfolders) and serving these as the results,
1.678 -
1.679 -<a href="@org-openide-util-lookup@/org/openide/util/lookup/Lookups.html#forPath(java.lang.String)">Lookups.forPath(String)</a>
1.680 -
1.681 -makes this possible: you need only provide a name of a folder to look in, and
1.682 -use
1.683 -
1.684 -<code>Lookups.forPath(theFolderName)</code>
1.685 -
1.686 -to retrieve a lookup implementation which will scan this folder and
1.687 -its subfolders for data objects with <code>InstanceCookie</code>
1.688 -matching the lookup template. Furthermore, any instance cookies whose
1.689 -instance class is assignable to <code>Lookup</code> will be treated
1.690 -specially: they will be proxied to, so these sub-lookups may provide
1.691 -additional instances if they match the lookup template. In order to
1.692 -get the full functionality associated with such a lookup it is wise
1.693 -to request presence of <code>org.netbeans.modules.settings > 1.13</code>
1.694 -as that is the module that does most of the work behind <code>Lookups.forPath</code>.
1.695 -To register <code>javax.xml.parsers.DocumentBuilderFactory</code> into
1.696 -<code>Lookups.forName("my/xml/app/data")</code> add the above described dependency
1.697 -and put following code in your layer file:
1.698 -<pre>
1.699 -<folder name="my">
1.700 - <folder name="xml">
1.701 - <folder name="app">
1.702 - <folder name="data">
1.703 - <file name="ThisIsMyRegistration.instance>
1.704 - <attr name="instanceCreate" newvalue="pkg.ClassNameOfYourImpl"/>
1.705 - </file>
1.706 - </folder>
1.707 - </folder>
1.708 - </folder>
1.709 -</folder>
1.710 -</pre>
1.711 -
1.712 -<p>
1.713 -In fact the <code>Lookups.forPath</code> can be used in completely
1.714 -standalone mode. This is not very recommended in the NetBeans IDE, but
1.715 -can be found pretty useful when using this library in standalone applications:
1.716 -<code>Lookups.forPath(path)</code> scans all instances registered in the
1.717 -<a href="#service-lookup">META-INF/services style</a> just it uses
1.718 -<code>META-INF/namedservices/path</code> prefix instead.
1.719 -(<code>@ServiceProvider</code> supports this mode.)
1.720 -As a result to
1.721 -perform a successfull search for all <code>javax.xml.parsers.DocumentBuilderFactory</code>
1.722 -inside <code>Lookups.forName("my/xml/app/data")</code> one can register the
1.723 -implementation into <code>META-INF/namedservices/my/xml/app/data/javax.xml.parsers.DocumentBuilderFactory</code>.
1.724 -</p>
1.725 -
1.726 -<p>The most powerful way to provide a lookup is to directly define
1.727 -what instances and items it should provide, by subclassing. For this,
1.728 -
1.729 -<a href="@org-openide-util-lookup@/org/openide/util/lookup/AbstractLookup.html"><code>AbstractLookup</code></a>
1.730 -
1.731 -is recommended as it is easiest to use.
1.732 -
1.733 -<p>The simplest way to use <code>AbstractLookup</code> is to use its
1.734 -public constructor (in which case you need not subclass it). Here you
1.735 -provide an
1.736 -
1.737 -<a href="@org-openide-util-lookup@/org/openide/util/lookup/AbstractLookup.Content.html"><code>AbstractLookup.Content</code></a>
1.738 -
1.739 -object which you have created and hold on to privately, and which
1.740 -keeps track of instances and permits them to be registered and
1.741 -deregistered. Often
1.742 -
1.743 -<a href="@org-openide-util-lookup@/org/openide/util/lookup/InstanceContent.html"><code>InstanceContent</code></a>
1.744 -
1.745 -is used as the content implementation. To add something to the lookup,
1.746 -simply use
1.747 -
1.748 -<a href="@org-openide-util-lookup@/org/openide/util/lookup/InstanceContent.html#add(java.lang.Object)"><code>add(Object)</code></a>
1.749 -
1.750 -(and <code>remove(Object)</code> for the reverse). These may be called
1.751 -at any time and will update the set of registered instances (firing
1.752 -result changes as needed).
1.753 -
1.754 -<p>In case it is expensive to actually compute the object in the
1.755 -lookup, but there is some cheap "key" which can easily generate it,
1.756 -you may instead register the key by passing in an
1.757 -
1.758 -<a href="@org-openide-util-lookup@/org/openide/util/lookup/InstanceContent.Convertor.html"><code>InstanceContent.Convertor</code></a>.
1.759 -
1.760 -This convertor translates the key to the real instance that the lookup
1.761 -client sees, if and when needed. For example, if you have a long list
1.762 -of class names and wish to register default instances of each class,
1.763 -you might actually register the class name as the key, and supply a
1.764 -convertor which really loads the class and instantiates it. This makes
1.765 -it easy to set up the lookup, but nothing is really loaded until
1.766 -someone asks for it.
1.767 -
1.768 -<h3><a name="settings">Settings</a></h3>
1.769 -
1.770 -<em>Settings</em> require special support in the lookup system: these
1.771 -are objects (perhaps singletons but not necessarily) which should be
1.772 -made available to lookup, yet whose content can be changed and stored
1.773 -to disk (typically as a result of user interaction with the GUI).
1.774 -<samp>*.instance</samp> files and similar constructions are fine for
1.775 -registering fixed objects from layer - "fixed" in the sense that while
1.776 -the user might copy, delete, move, or reorder them, the actual object
1.777 -they provide is statically determined and does not generally have a
1.778 -means of being modified. In contrast, settings have nontrivial
1.779 -content. A typical setting is a system options,
1.780 -simply a singleton bean with a set of properties and a structured GUI
1.781 -presentation driven by <code>BeanInfo</code>.
1.782 -
1.783 -<p>In order to save such settings, an XML file is normally used, and
1.784 -the APIs provide a convenient
1.785 -
1.786 -<a href="http://www.netbeans.org/dtds/sessionsettings-1_0.dtd">DTD</a>
1.787 -
1.788 -for settings which can be represented as a single bean. In typical
1.789 -usage, the module layer declares an initial settings file which
1.790 -instructs lookup to create a <em>default instance</em> of the settings
1.791 -class. This might look like the following:
1.792 -
1.793 -<pre>
1.794 -<?<font class="keyword">xml</font> <font class="variable-name">version</font>=<font class="string">"1.0"</font>?>
1.795 -<!<font class="keyword">DOCTYPE</font> <font class="type">settings</font> <font class="keyword">PUBLIC</font> <font class="string">"-//NetBeans//DTD Session settings 1.0//EN"</font> <font class="string">"http://www.netbeans.org/dtds/sessionsettings-1_0.dtd"</font>>
1.796 -<<font class="function-name">settings</font> <font class="variable-name">version</font>=<font class="string">"1.0"</font>>
1.797 - <<font class="function-name">module</font> <font class="variable-name">name</font>=<font class="string">"com.foo/1"</font> <font class="variable-name">spec</font>=<font class="string">"1.0"</font>/>
1.798 - <<font class="function-name">instanceof</font> <font class="variable-name">class</font>=<font class="string">"org.openide.options.SystemOption"</font>/>
1.799 - <<font class="function-name">instanceof</font> <font class="variable-name">class</font>=<font class="string">"com.foo.MyOption"</font>/>
1.800 - <<font class="function-name">instance</font> <font class="variable-name">class</font>=<font class="string">"com.foo.MyOption"</font>/>
1.801 -</<font class="function-name">settings</font>>
1.802 -</pre>
1.803 -
1.804 -Such a file might be placed in
1.805 -<samp>Services/com-foo-my-settings.xml</samp> (the exact name inside
1.806 -the <samp>Services</samp> folder is not important but ought to be
1.807 -globally unique to avoid conflicts with other modules). It provides
1.808 -an <code>InstanceCookie</code> with the settings object as instance.
1.809 -
1.810 -<p>The interesting parts of this file are:
1.811 -
1.812 -<ul>
1.813 -
1.814 -<li>The <samp><instance/></samp> element which declares that the
1.815 -actual object will be a default instance of the class
1.816 -<samp>com.foo.MyOption</samp>, i.e. created via default public
1.817 -constructor.
1.818 -
1.819 -<li>Various <samp><instanceof/></samp> elements which specify
1.820 -what lookup templates will find this instance. Giving these elements
1.821 -permits the system to defer creating the setting instance until it is
1.822 -actually requested (that is, using
1.823 -
1.824 -<a href="#instancecookie-of"><code>InstanceCookie.Of</code></a>).
1.825 -
1.826 -It is only necessary to indicate superclasses and interfaces that you
1.827 -actually expect someone to look up when searching for this setting,
1.828 -but be careful that you know what these might be. The actual class
1.829 -of the instance itself should be listed as well.
1.830 -
1.831 -<li>An optional but recommended <samp><module/></samp> element
1.832 -that declares which module provides this setting. You give the full
1.833 -code name (including a slash followed by the major release version, if applicable)
1.834 -of the module and its specification version. The purpose of
1.835 -this element becomes apparent if the user ever customizes the setting
1.836 -file, thus writing the changes to disk (for example in the
1.837 -<samp>system/Services/</samp> folder), and then uninstalls the module:
1.838 -keeping the name of the declaring module in the file ensures that with
1.839 -the module uninstalled, the system will quietly ignore the stale
1.840 -setting rather than trying to blithely load the settings class and
1.841 -failing with a <code>ClassNotFoundException</code>. If the module is
1.842 -subsequently reinstalled, the setting will automatically become active
1.843 -again (regain its <code>InstanceCookie</code>). Similarly, settings will
1.844 -not be loaded if they were written by a newer version of the module than
1.845 -the one currently installed - module-supplied settings should be readable
1.846 -by newer versions of the module, but generally not older ones.
1.847 -
1.848 -</ul>
1.849 -
1.850 -<p>There are actually three ways that the instance may be declared:</p>
1.851 -
1.852 -<ol>
1.853 -
1.854 -<li><p>Using <samp><instance/></samp> as above to generate a
1.855 -default instance. This is most common.</p>
1.856 -
1.857 -<li><p>You may pass an additional attribute <code>method</code>
1.858 -indicating a static method to call to produce
1.859 -the instance, rather than using a default constructor.
1.860 -The method may either be a simple name, in which case it is assumed
1.861 -to be a method in the class given by <code>class</code>, or you
1.862 -may give a full class name followed by a dot and method name to invoke
1.863 -a static method from some other class.
1.864 -The method may
1.865 -optionally take a <code>FileObject</code> argument which will be the
1.866 -settings file itself. This is analogous to the mechanism used for
1.867 -creating complex <samp>*.instance</samp> files. For example:</p>
1.868 -
1.869 -<pre>
1.870 -<<font class="function-name">file</font> <font class="variable-name">name</font>=<font class="string">"some-difficult-to-make-instance.settings"</font>>
1.871 - <![<font class="keyword">CDATA</font>[<?<font class="keyword">xml</font> <font class="variable-name">version</font>=<font class="string">"1.0"</font> <font class="variable-name">encoding</font>=<font class="string">"UTF-8"</font>?>
1.872 -<!<font class="keyword">DOCTYPE</font> <font class="type">settings</font> <font class="keyword">PUBLIC</font>
1.873 - <font class="string">"-//NetBeans//DTD Session settings 1.0//EN"</font>
1.874 - <font class="string">"http://www.netbeans.org/dtds/sessionsettings-1_0.dtd"</font>>
1.875 -<<font class="function-name">settings</font> <font class="variable-name">version</font>=<font class="string">"1.0"</font>>
1.876 - <<font class="function-name">module</font> <font class="variable-name">name</font>=<font class="string">"my.module/1"</font> <font class="variable-name">spec</font>=<font class="string">"1.0"</font>/>
1.877 - <<font class="function-name">instanceof</font> <font class="variable-name">class</font>=<font class="string">"javax.swing.Action"</font>/>
1.878 - <<font class="function-name">instanceof</font> <font class="variable-name">class</font>=<font class="string">"my.module.MyAction"</font>/>
1.879 - <<font class="function-name">instance</font> <font class="variable-name">class</font>=<font class="string">"my.module.MyAction"</font> <font class="variable-name">method</font>=<font class="string">"createAction"</font>/>
1.880 -</<font class="function-name">settings</font>>
1.881 -]]>
1.882 - <<font class="function-name">attr</font> <font class="variable-name">name</font>=<font class="string">"param"</font> <font class="variable-name">stringvalue</font>=<font class="string">"someval"</font>/>
1.883 -</<font class="function-name">file</font>>
1.884 -</pre>
1.885 -
1.886 -<pre>
1.887 -<font class="keyword">package</font> <font class="constant">my</font>.<font class="constant">module</font>;
1.888 -<font class="keyword">public</font> <font class="keyword">class</font> <font class="type">MyAction</font> <font class="keyword">extends</font> <font class="type">javax.swing.AbstractAction</font> {
1.889 - <font class="keyword">public</font> <font class="type">MyAction</font>(<font class="type">String</font> <font class="variable-name">name</font>) {<font class="comment">/* ... */</font>}
1.890 - <font class="comment">// ...
1.891 -</font> <font class="keyword">public</font> <font class="keyword">static</font> <font class="type">MyAction</font> <font class="function-name">createAction</font>(<font class="type">FileObject</font> <font class="variable-name">fo</font>) {
1.892 - <font class="keyword">return</font> <font class="keyword">new</font> <font class="type">MyAction</font>((<font class="type">String</font>)fo.getAttribute(<font class="string">"param"</font>));
1.893 - }
1.894 -}
1.895 -</pre>
1.896 -
1.897 -<p>This will result in an instance of <code>MyAction</code> being
1.898 -created with name <samp>someval</samp>.</p>
1.899 -
1.900 -<li><p>You may use the <samp><serialdata></samp> element. Its
1.901 -textual contents are a hexadecimal dump (whitespace ignored) of the
1.902 -raw serialized bytes of an object to serve as the instance. Naturally
1.903 -this is the least preferred mechanism as it is not human-readable.</p>
1.904 -
1.905 -</ol>
1.906 -
1.907 -<p class="nonnormative">(You can configure your persistance style by using
1.908 -<a href="@org-netbeans-modules-settings@/org/netbeans/api/settings/ConvertAsProperties.html">@ConvertAsProperties</a> or
1.909 -<a href="@org-netbeans-modules-settings@/org/netbeans/api/settings/ConvertAsJavaBean.html">@ConvertAsJavaBean</a>
1.910 -instead).</p>
1.911 -
1.912 -<p>A client can find the current setting in a couple of ways:
1.913 -
1.914 -<ul>
1.915 -
1.916 -<li>In the common case of <code>SystemOption</code>, you may simply
1.917 -call
1.918 -
1.919 -<a href="../SharedClassObject.html#findObject(java.lang.Class,%20boolean)"><code>SharedClassObject.findObject(Class, true)</code></a>
1.920 -
1.921 -which will either provide a previously initialized singleton, or find
1.922 -the setting in lookup if possible and read any customized state before
1.923 -returning it. You may then use property change listeners as needed to
1.924 -listen for changes.
1.925 -
1.926 -<li>Just ask the system lookup for the settings class (or a relevant
1.927 -superclass). This can be used to retrieve non-singleton settings; use
1.928 -the lookup result to track changes in the list of setting instances,
1.929 -and some ad-hoc method to track runtime changes in individual
1.930 -instances.
1.931 -
1.932 -</ul>
1.933 -
1.934 -<p>How does the customization of setting instances work? After finding a
1.935 -setting instance via this DTD, the system will automatically look for
1.936 -a beans-style event set of type <code>PropertyChangeListener</code>,
1.937 -and add its own listener. If the bean changes state (either
1.938 -programmatically or as a result of user manipulation), the property
1.939 -change will cause the new state to be written out to the original XML
1.940 -file, keeping the same name. (Normally this would mean the XML would
1.941 -be written to disk in the user directory.)</p>
1.942 -
1.943 -<p class="nonnormative">(Historically the state of an object is simply
1.944 - serialized into
1.945 -the XML file using <samp><serialdata></samp>, meaning the class
1.946 -must be <code>Serializable</code>, but you can choose different form
1.947 -of persistance by using
1.948 -<a href="@org-netbeans-modules-settings@/org/netbeans/api/settings/ConvertAsProperties.html">@ConvertAsProperties</a> or
1.949 -<a href="@org-netbeans-modules-settings@/org/netbeans/api/settings/ConvertAsJavaBean.html">@ConvertAsJavaBean</a>
1.950 -instead).</p>
1.951 -
1.952 -<p>Conversely, changes to the setting file on disk should trigger a
1.953 -reload of the state and modification of the in-memory bean (or
1.954 -creation of a new instance cookie with a new bean).</p>
1.955 -
1.956 -<h3><a name="lookup-ui">UI for Services</a></h3>
1.957 -
1.958 -<p>There are several things you can do to not only have services and
1.959 -lookup function programmatically but also look good and behave nicely
1.960 -within the user's view of configuration options and settings.</p>
1.961 -
1.962 -<h4><a name="service-templates">Service Templates</a></h4>
1.963 -
1.964 -<p>For many kinds of services, especially <code>ServiceType</code>s
1.965 -but also others, it is necessary to permit the user to create new
1.966 -instances of the service. Generally two criteria should be met for
1.967 -such services:</p>
1.968 -
1.969 -<ol>
1.970 -
1.971 -<li>The service is not a singleton, so it is meaningful to have more
1.972 -than one instance.
1.973 -
1.974 -<li>The service has some user-configurable properties, so it is useful
1.975 -to have more than one instance.
1.976 -
1.977 -</ol>
1.978 -
1.979 -<p>Creation of new service instances may be supported simply by
1.980 -producing a template residing beneath
1.981 -<samp>Templates/Services/</samp>. If the service normally resides in a
1.982 -subfolder of services, for example <samp>Services/Executor/</samp>,
1.983 -then the template should correspondingly be placed in
1.984 -<samp>Templates/Services/Executor/</samp>.</p>
1.985 -
1.986 -<div class="nonnormative">
1.987 -
1.988 -<p>The template should work like regular source code templates do: a
1.989 -file giving the initial structure of the service (typically a
1.990 -<samp>*.settings</samp> file), with the file attribute
1.991 -<code>template</code> set to <samp>true</samp>, and optionally a
1.992 -<code>templateWizardDescription</code> and
1.993 -<code>templateWizardURL</code>. For example:</p>
1.994 -
1.995 -<pre>
1.996 -<<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"Templates"</font>>
1.997 - <<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"Services"</font>>
1.998 - <<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"Executor"</font>>
1.999 - <<font class="function-name">file</font> <font class="variable-name">name</font>=<font class="string">"my-module-executor.settings"</font> <font class="variable-name">url</font>=<font class="string">"executor.settings"</font>>
1.1000 - <<font class="function-name">attr</font> <font class="variable-name">name</font>=<font class="string">"template"</font> <font class="variable-name">boolvalue</font>=<font class="string">"true"</font>/>
1.1001 - <font class="comment"><!-- SystemFileSystem.localizedName and SystemFileSystem.icon as usual --></font>
1.1002 - </<font class="function-name">file</font>>
1.1003 - </<font class="function-name">folder</font>>
1.1004 - </<font class="function-name">folder</font>>
1.1005 -</<font class="function-name">folder</font>>
1.1006 -</pre>
1.1007 -
1.1008 -<p>If the user selects <b>New From Template</b> on the
1.1009 -corresponding options folder, the template will be available.</p>
1.1010 -
1.1011 -</div>
1.1012 -
1.1013 -<!-- XXX is the file attribute 'simple'=false supported? Yarda says it was a hack only -->
1.1014 -
1.1015 -<h4><a name="service-mirroring">Services display area and mirroring</a></h4>
1.1016 -
1.1017 -<p>In addition to providing services, it is desirable to display them
1.1018 -to the user as well. This is done, as is customary in other aspects of
1.1019 -NetBeans configuration, by displaying customized variants of the data
1.1020 -nodes coming from the system filesystem. The root folder for
1.1021 -displaying options is called <samp>UI/Services/</samp>. Its subfolders
1.1022 -govern the display of the options available in the system.</p>
1.1023 -
1.1024 -<p>As a rule, it is undesirable to place any actual settings in this
1.1025 -folder (nor would they be recognized by the default lookup anyway).
1.1026 -That is because the organization of this folder is driven by UI needs,
1.1027 -without regards to API maintenance or compatibility of persisted user
1.1028 -settings. So this folder solely <em>mirrors</em> configuration
1.1029 -available elsewhere. You may freely reorganize the mirror according to
1.1030 -current UI needs: existing modules plugging into services areas will
1.1031 -continue to work unmodified, and existing user customizations stored
1.1032 -to disk will continue to apply, since both of these act on the
1.1033 -original files (which should <em>not</em> be moved frivolously).</p>
1.1034 -
1.1035 -<div class="nonnormative">
1.1036 -
1.1037 -<p>While technically you could place anything you wish in the UI
1.1038 -folder, in practice a few types of things are used:</p>
1.1039 -
1.1040 -<ul>
1.1041 -
1.1042 -<li><p>Symbolic links to settings files displayed elsewhere. In
1.1043 -NetBeans' old-style options, these will appear as the real setting. For example:</p>
1.1044 -
1.1045 -<pre>
1.1046 -<<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"UI"</font>>
1.1047 - <<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"Services"</font>>
1.1048 - <<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"Editing"</font>>
1.1049 - <<font class="function-name">file</font> <font class="variable-name">name</font>=<font class="string">"my-module-config.shadow"</font>>
1.1050 - <<font class="function-name">attr</font> <font class="variable-name">name</font>=<font class="string">"originalFile"</font> <font class="variable-name">stringvalue</font>=<font class="string">"Services/my-module-Config.settings"</font>/>
1.1051 - <<font class="function-name">attr</font> <font class="variable-name">name</font>=<font class="string">"originalFileSystem"</font> <font class="variable-name">stringvalue</font>=<font class="string">"SystemFileSystem"</font>/>
1.1052 - </<font class="function-name">file</font>>
1.1053 - </<font class="function-name">folder</font>>
1.1054 - </<font class="function-name">folder</font>>
1.1055 -</<font class="function-name">folder</font>>
1.1056 -</pre>
1.1057 -
1.1058 -<!-- XXX this info should be in a normative section -->
1.1059 -<p>The attribute "originalFileSystem" can be omitted. In this case the search for the
1.1060 -linked file will be done on the Filesystem on which the link resides, which
1.1061 -is wanted for the usages on SystemFileSystem. The link file should have zero length.<BR>
1.1062 -Note that any localized display name
1.1063 -and icon should be set on the original settings file; they will be
1.1064 -picked up automatically by the shadow.</p>
1.1065 -
1.1066 -The older style of linking using the CDATA section is still supported:
1.1067 -
1.1068 -<pre>
1.1069 -<<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"UI"</font>>
1.1070 - <<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"Services"</font>>
1.1071 - <<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"Editing"</font>>
1.1072 - <<font class="function-name">file</font> <font class="variable-name">name</font>=<font class="string">"my-module-config.shadow"</font>>
1.1073 - <![<font class="keyword">CDATA</font>[Services/my-module-Config.settings
1.1074 -SystemFileSystem
1.1075 -]]>
1.1076 - </<font class="function-name">file</font>>
1.1077 - </<font class="function-name">folder</font>>
1.1078 - </<font class="function-name">folder</font>>
1.1079 -</<font class="function-name">folder</font>>
1.1080 -</pre>
1.1081 -
1.1082 -<p>Here the shadow file consists of two lines, the first being the
1.1083 -path to the real settings, the second always being
1.1084 -<samp>SystemFileSystem</samp>.
1.1085 -
1.1086 -<li><p>Links to other kinds of files, such as folders, whether part of
1.1087 -the services lookup area or not. For example:</p>
1.1088 -
1.1089 -<pre>
1.1090 -<<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"UI"</font>>
1.1091 - <<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"Services"</font>>
1.1092 - <<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"IDEConfiguration"</font>>
1.1093 - <<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"LookAndFeel"</font>>
1.1094 - <<font class="function-name">file</font> <font class="variable-name">name</font>=<font class="string">"my-module-stuff.shadow"</font>>
1.1095 - <<font class="function-name">attr</font> <font class="variable-name">name</font>=<font class="string">"originalFile"</font> <font class="variable-name">stringvalue</font>=<font class="string">"Stuff"</font>/>
1.1096 - </<font class="function-name">file</font>>
1.1097 - </<font class="function-name">folder</font>>
1.1098 - </<font class="function-name">folder</font>>
1.1099 - </<font class="function-name">folder</font>>
1.1100 -</<font class="function-name">folder</font>>
1.1101 -<<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"Stuff"</font>>
1.1102 - <<font class="function-name">attr</font> <font class="variable-name">name</font>=<font class="string">"SystemFileSystem.localizingBundle"</font> <font class="variable-name">stringvalue</font>=<font class="string">"my.module.Bundle"</font>/>
1.1103 - <<font class="function-name">attr</font> <font class="variable-name">name</font>=<font class="string">"SystemFileSystem.icon"</font> <font class="variable-name">urlvalue</font>=<font class="string">"nbresloc:/my/module/stuff.gif"</font>/>
1.1104 - <font class="comment"><!-- perhaps some files to display here, perhaps not --></font>
1.1105 -</<font class="function-name">folder</font>>
1.1106 -</pre>
1.1107 -
1.1108 -<p>This defines a folder <samp>Stuff</samp> in the system filesystem
1.1109 -which may be used for some kind of special configuration, and displays
1.1110 -it in options.</p>
1.1111 -
1.1112 -<li><p>Specialized nodes. In some cases you do not wish to display a
1.1113 -particular folder but want to have complete control over the literal
1.1114 -display of the option. In such a case you need only include a
1.1115 -<samp>*.instance</samp> file with an instance of the node (or its
1.1116 -handle, if you prefer), as the node delegate of this object will be (a
1.1117 -clone of) the node you provide. For example:</p>
1.1118 -
1.1119 -<pre>
1.1120 -<<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"UI"</font>>
1.1121 - <<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"Services"</font>>
1.1122 - <<font class="function-name">folder</font> <font class="variable-name">name</font>=<font class="string">"Building"</font>>
1.1123 - <font class="comment"><!-- Some subclass of org.openide.nodes.Node: --></font>
1.1124 - <<font class="function-name">file</font> <font class="variable-name">name</font>=<font class="string">"my-module-ConfigurationNode.instance"</font>/>
1.1125 - </<font class="function-name">folder</font>>
1.1126 - </<font class="function-name">folder</font>>
1.1127 -</<font class="function-name">folder</font>>
1.1128 -</pre>
1.1129 -
1.1130 -</ul>
1.1131 -
1.1132 -</div>
1.1133 -
1.1134 -<p>No particular substructure of <samp>UI/Services/</samp> is defined
1.1135 -by the APIs. For optimal UI integration you may wish to examine the
1.1136 -categories used by other modules and try to reuse an existing category
1.1137 -appropriate to your needs.</p>
1.1138 -
1.1139 -<p>In some cases it is necessary to <em>hide</em> a service file, or a
1.1140 -whole folder of services. While you can place files into
1.1141 -<samp>Services/</samp> and simply not make any corresponding mirror in
1.1142 -<samp>UI/Services/</samp>, you may wish to create services or
1.1143 -subfolders inside existing displayable folders (for purposes of
1.1144 -lookup, generally) yet not have them be visible in the UI. In this
1.1145 -case you should mark the file or subfolder with the file attribute
1.1146 -<code>hidden</code> (set to boolean <samp>true</samp>).</p>
1.1147 -
1.1148 -<h4><a name="services-proped">Property editor for services</a></h4>
1.1149 -
1.1150 -<p>If you wish to permit the user to select a service as part of the
1.1151 -Property Sheet (from a node property, or as a
1.1152 -<code>PropertyPanel</code>, providing general GUI embeddability), this
1.1153 -is supported. You should use the property editor assigned to
1.1154 -<code>java.lang.Object</code> (<em>not</em> your desired service
1.1155 -interface). Various hints defined in the Explorer API
1.1156 -permit you to control the result.</p>
1.1157 -
1.1158 -<div class="nonnormative">
1.1159 -
1.1160 -<p>As an example, here is a node property permitting you to ask the
1.1161 -user to select a value of type <code>my.module.Thing</code>, being
1.1162 -some interface or abstract superclass, where some instances are
1.1163 -registered to lookup, conventionally in the
1.1164 -<samp>Services/Things/</samp> folder which the module has provided:</p>
1.1165 -
1.1166 -<pre>
1.1167 -<font class="keyword">public</font> <font class="keyword">abstract</font> <font class="keyword">class</font> <font class="type">ThingProperty</font> <font class="keyword">extends</font> <font class="type">PropertySupport.ReadWrite</font> {
1.1168 - <font class="keyword">protected</font> <font class="type">ThingProperty</font>(<font class="type">String</font> <font class="variable-name">name</font>, <font class="type">String</font> <font class="variable-name">displayName</font>, <font class="type">String</font> <font class="variable-name">shortDescription</font>) <font class="keyword">throws</font> <font class="type">IOException</font> {
1.1169 - <font class="keyword">super</font>(name, Object.<font class="keyword">class</font>, displayName, shortDescription);
1.1170 - setValue(<font class="string">"superClass"</font>, Thing.<font class="keyword">class</font>); <font class="comment">// NOI18N
1.1171 -</font> setValue(<font class="string">"nullValue"</font>, NbBundle.getMessage(ThingProperty.<font class="keyword">class</font>, <font class="string">"LBL_no_thing"</font>)); <font class="comment">// NOI18N
1.1172 -</font> <font class="type">DataFolder</font> <font class="variable-name">thingsFolder</font> = DataFolder.create(
1.1173 - DataFolder.findFolder(Repository.getDefault().getDefaultFileSystem().getRoot()),
1.1174 - <font class="string">"Services/Things"</font> <font class="comment">// NOI18N
1.1175 -</font> );
1.1176 - setValue(<font class="string">"node"</font>, thingsFolder.getNodeDelegate()); <font class="comment">// NOI18N
1.1177 -</font> }
1.1178 - <font class="keyword">public</font> <font class="keyword">final</font> <font class="type">Object</font> <font class="function-name">getValue</font>() {
1.1179 - <font class="keyword">return</font> getThing();
1.1180 - }
1.1181 - <font class="keyword">public</font> <font class="keyword">final</font> <font class="type">void</font> <font class="function-name">setValue</font>(<font class="type">Object</font> <font class="variable-name">o</font>) {
1.1182 - <font class="keyword">if</font> (o != <font class="constant">null</font>) {
1.1183 - <font class="type">Lookup.Template</font> <font class="variable-name">templ</font> = <font class="keyword">new</font> <font class="type">Lookup.Template</font>(Thing.<font class="keyword">class</font>, o, <font class="constant">null</font>);
1.1184 - <font class="type">Iterator</font> <font class="variable-name">it</font> = Lookup.getDefault().lookup(templ).allItems().iterator();
1.1185 - <font class="keyword">if</font> (it.hasNext()) {
1.1186 - setThingID(((<font class="type">Lookup.Item</font>)it.next()).getId());
1.1187 - } <font class="keyword">else</font> {
1.1188 - <font class="comment">// Thing was registered but is not persistable.
1.1189 -</font> setThingID(<font class="constant">null</font>);
1.1190 - }
1.1191 - } <font class="keyword">else</font> {
1.1192 - setThingID(<font class="constant">null</font>);
1.1193 - }
1.1194 - }
1.1195 - <font class="keyword">public</font> <font class="keyword">final</font> <font class="type">boolean</font> <font class="function-name">supportsDefaultValue</font>() {
1.1196 - <font class="keyword">return</font> <font class="constant">true</font>;
1.1197 - }
1.1198 - <font class="keyword">public</font> <font class="keyword">final</font> <font class="type">void</font> <font class="function-name">restoreDefaultValue</font>() {
1.1199 - setValue(<font class="constant">null</font>);
1.1200 - }
1.1201 - <font class="comment">// May be used by code wishing to get the actual Thing (or null):
1.1202 -</font> <font class="keyword">public</font> <font class="keyword">final</font> <font class="type">Thing</font> <font class="function-name">getThing</font>() {
1.1203 - <font class="type">String</font> <font class="variable-name">id</font> = getThingID();
1.1204 - <font class="keyword">if</font> (id != <font class="constant">null</font>) {
1.1205 - <font class="type">Lookup.Template</font> <font class="variable-name">templ</font> = <font class="keyword">new</font> <font class="type">Lookup.Template</font>(Thing.<font class="keyword">class</font>, <font class="constant">null</font>, id);
1.1206 - <font class="type">Iterator</font> <font class="variable-name">it</font> = Lookup.getDefault().lookup(templ).allInstances().iterator();
1.1207 - <font class="keyword">if</font> (it.hasNext()) {
1.1208 - <font class="keyword">return</font> (<font class="type">Thing</font>)it.next();
1.1209 - } <font class="keyword">else</font> {
1.1210 - <font class="comment">// Invalid ID.
1.1211 -</font> <font class="keyword">return</font> <font class="constant">null</font>;
1.1212 - }
1.1213 - } <font class="keyword">else</font> {
1.1214 - <font class="keyword">return</font> <font class="constant">null</font>;
1.1215 - }
1.1216 - }
1.1217 - <font class="comment">// Subclasses implement to actually read/write Thing persistent IDs (or null):
1.1218 -</font> <font class="keyword">protected</font> <font class="keyword">abstract</font> <font class="type">String</font> <font class="function-name">getThingID</font>();
1.1219 - <font class="keyword">protected</font> <font class="keyword">abstract</font> <font class="type">void</font> <font class="function-name">setThingID</font>(<font class="type">String</font> <font class="variable-name">id</font>);
1.1220 -}
1.1221 -</pre>
1.1222 -
1.1223 -<p>A property extending this class would in the current UI display a
1.1224 -pull-down list of all <code>Thing</code> implementations available in
1.1225 -lookup; the custom property editor dialog would display the
1.1226 -<samp>Things</samp> folder with anything contained inside it for the
1.1227 -user to select from, provided it in fact had an instance assignable to
1.1228 -<code>Thing</code>. The special null value is explicitly permitted
1.1229 -here and would be displayed with the label given in the bundle.</p>
1.1230 -
1.1231 -</div>
1.1232 -
1.1233 -
1.1234 -<hr>@FOOTER@
1.1235 -</body>
1.1236 -</html>