KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > BasicWorkingSetElementAdapter


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.ui;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.List JavaDoc;
16 import java.util.StringTokenizer JavaDoc;
17
18 import org.eclipse.core.runtime.IAdaptable;
19 import org.eclipse.core.runtime.IAdapterManager;
20 import org.eclipse.core.runtime.IConfigurationElement;
21 import org.eclipse.core.runtime.IExecutableExtension;
22 import org.eclipse.core.runtime.Platform;
23 import org.eclipse.ui.internal.WorkbenchPlugin;
24 import org.osgi.framework.Bundle;
25 import org.osgi.service.packageadmin.ExportedPackage;
26 import org.osgi.service.packageadmin.PackageAdmin;
27 import org.osgi.util.tracker.ServiceTracker;
28
29 /**
30  * Basic IWorkingSetElementAdapter implementation that allows plugins to decribe
31  * simple declarative element adapters.
32  * <p>
33  * The executable extension format for this class is as follows:<br/>
34  * <code>&lt;workingSet
35  * elementAdapterClass="org.eclipse.ui.BasicWorkingSetElementAdapter:class1.to.adapt.to[;option1=value1][;option2=value2],class2.to.adapt.to[;option1=value1][;option2=value2],..."&gt;
36  * ... &lt;/workingSet&gt;</code>
37  * </p>
38  * <p>
39  * The valid options are:<br/>
40  * <dl>
41  * <dt>adapt</dt>
42  * <dd>Values: <code>true</code> or <code>true</code>. Specifies whether
43  * or not the platform {@link org.eclipse.core.runtime.IAdapterManager} and the
44  * {@link org.eclipse.core.runtime.IAdaptable} interface should be consulted.</dd>
45  * </dl>
46  * </p>
47  *
48  * Please see the {@link #adaptElements(IWorkingSet, IAdaptable[])} method for
49  * details on behavior of this implementation.
50  *
51  * @since 3.3
52  */

53 public final class BasicWorkingSetElementAdapter implements
54         IWorkingSetElementAdapter, IExecutableExtension {
55
56     private class Type {
57         private static final int NONE = 0;
58         private static final int ADAPT = 1;
59         String JavaDoc className;
60         int flags;
61     }
62
63     private Type[] preferredTypes = new Type[0];
64
65     private ServiceTracker packageTracker;
66
67     /**
68      * When invoked this method will iterate over all classes specified as
69      * IExecutableExtension arguements to this class in order and compare with
70      * the elements. If the element is directly assignable to the provided class
71      * then it is added to the result array as is. If the class has specified
72      * "adapt=true" as an argument and there is an available adapter in the
73      * platform IAdapterManager then it is returned. Finally, if "adapt=true"
74      * and the class is already loaded (determined by inspecting exported
75      * bundles via the platform PackageAdmin) a direct query for the adapter is
76      * made on the object and if it is not <code>null</code> then it is
77      * returned.
78      * <p>
79      * A consequence of the above is that it is possible for this method to
80      * return differing results based on the state of bundles loaded within the
81      * system.
82      * </p>
83      *
84      * @see org.eclipse.ui.IWorkingSetElementAdapter#adaptElements(org.eclipse.ui.IWorkingSet,
85      * org.eclipse.core.runtime.IAdaptable[])
86      * @see org.eclipse.core.runtime.IAdapterManager#getAdapter(Object, String)
87      * @see org.osgi.service.packageadmin.PackageAdmin#getExportedPackage(String)
88      */

89     public IAdaptable[] adaptElements(IWorkingSet ws, IAdaptable[] elements) {
90         List JavaDoc adaptedElements = new ArrayList JavaDoc();
91         for (int i = 0; i < elements.length; i++) {
92             IAdaptable adaptable = adapt(elements[i]);
93             if (adaptable != null)
94                 adaptedElements.add(adaptable);
95         }
96
97         return (IAdaptable[]) adaptedElements
98                 .toArray(new IAdaptable[adaptedElements.size()]);
99     }
100
101     /**
102      * Adapt the given adaptable. Compares the given adaptable against the list
103      * of desired types and returns the first type that generates a match.
104      *
105      * @param adaptable
106      * the adaptable to adapt
107      * @return the resultant adaptable. May be the same adaptable, a new
108      * adaptable, or <code>null</code>.
109      */

110     private IAdaptable adapt(IAdaptable adaptable) {
111         for (int i = 0; i < preferredTypes.length; i++) {
112             IAdaptable adaptedAdaptable = adapt(preferredTypes[i], adaptable);
113             if (adaptedAdaptable != null)
114                 return adaptedAdaptable;
115         }
116         return null;
117     }
118
119     /**
120      * Adapt the given adaptable given the reference type.
121      *
122      * @param type
123      * the reference type
124      * @param adaptable
125      * the adaptable to adapt
126      * @return the resultant adaptable. May be the same adaptable, a new
127      * adaptable, or <code>null</code>.
128      */

129     private IAdaptable adapt(Type type, IAdaptable adaptable) {
130         IAdapterManager adapterManager = Platform.getAdapterManager();
131         Class JavaDoc[] directClasses = adapterManager.computeClassOrder(adaptable
132                 .getClass());
133         for (int i = 0; i < directClasses.length; i++) {
134             Class JavaDoc clazz = directClasses[i];
135             if (clazz.getName().equals(type.className))
136                 return adaptable;
137         }
138
139         if ((type.flags & Type.ADAPT) != 0) {
140             Object JavaDoc adapted = adapterManager.getAdapter(adaptable,
141                     type.className);
142             if (adapted instanceof IAdaptable)
143                 return (IAdaptable) adapted;
144
145             PackageAdmin admin = getPackageAdmin();
146             if (admin != null) {
147                 int lastDot = type.className.lastIndexOf('.');
148                 if (lastDot > 0) { // this lives in a package
149
String JavaDoc packageName = type.className.substring(0, lastDot);
150                     ExportedPackage[] packages = admin
151                             .getExportedPackages(packageName);
152                     if (packages != null && packages.length == 1) {
153                         // if there is exactly one exporter of this
154
// package
155
// we can go further
156
if (packages[0].getExportingBundle().getState() == Bundle.ACTIVE) {
157                             try {
158                                 // if the bundle is loaded we can safely get the
159
// class object and check for an adapter on the
160
// object directly
161
adapted = adaptable.getAdapter(packages[0]
162                                         .getExportingBundle().loadClass(
163                                                 type.className));
164                                 if (adapted instanceof IAdaptable)
165                                     return (IAdaptable) adapted;
166
167                             } catch (ClassNotFoundException JavaDoc e) {
168                                 WorkbenchPlugin.log(e);
169                             }
170                         }
171                     }
172                 }
173             }
174         }
175         return null;
176     }
177
178     /*
179      * (non-Javadoc)
180      *
181      * @see org.eclipse.ui.IWorkingSetElementAdapter#dispose()
182      */

183     public void dispose() {
184         if (packageTracker != null)
185             packageTracker.close();
186     }
187
188     /*
189      * (non-Javadoc)
190      *
191      * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement,
192      * java.lang.String, java.lang.Object)
193      */

194     public void setInitializationData(IConfigurationElement config,
195             String JavaDoc propertyName, Object JavaDoc data) {
196
197         if (data instanceof String JavaDoc) {
198             List JavaDoc preferredTypes = new ArrayList JavaDoc(0);
199             for (StringTokenizer JavaDoc toker = new StringTokenizer JavaDoc((String JavaDoc) data, ","); toker.hasMoreTokens();) {//$NON-NLS-1$
200
String JavaDoc classNameAndOptions = toker.nextToken();
201                 Type record = new Type();
202                 parseOptions(classNameAndOptions, record);
203                 preferredTypes.add(record);
204             }
205             this.preferredTypes = (Type[]) preferredTypes
206                     .toArray(new Type[preferredTypes.size()]);
207         }
208     }
209
210     /**
211      * Parse classname/option strings in the form:<br/>
212      * <code>some.package.Class[:option1=value1][:option2=value2]...
213      *
214      * @param classNameAndOptions the class name and possibly options to parse
215      * @param record the record to fill
216      */

217     private void parseOptions(String JavaDoc classNameAndOptions, Type record) {
218         for (StringTokenizer JavaDoc toker = new StringTokenizer JavaDoc(classNameAndOptions,
219                 ";"); toker.hasMoreTokens();) { //$NON-NLS-1$
220
String JavaDoc token = toker.nextToken();
221             if (record.className == null)
222                 record.className = token;
223             else {
224                 for (StringTokenizer JavaDoc pair = new StringTokenizer JavaDoc(token, "="); pair.hasMoreTokens();) {//$NON-NLS-1$
225
if (pair.countTokens() == 2) {
226                         String JavaDoc param = pair.nextToken();
227                         String JavaDoc value = pair.nextToken();
228                         if ("adapt".equals(param)) { //$NON-NLS-1$
229
record.flags ^= "true".equals(value) ? Type.ADAPT : Type.NONE; //$NON-NLS-1$
230
}
231                     }
232                 }
233             }
234         }
235     }
236
237     /**
238      * Prime the PackageAdmin service tracker and return the service (if
239      * available).
240      *
241      * @return the PackageAdmin service or null if it is not available
242      */

243     private PackageAdmin getPackageAdmin() {
244         if (packageTracker == null) {
245             packageTracker = new ServiceTracker(WorkbenchPlugin.getDefault()
246                     .getBundleContext(), PackageAdmin.class.getName(), null);
247             packageTracker.open();
248         }
249
250         return (PackageAdmin) packageTracker.getService();
251     }
252 }
253
Popular Tags