KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > help > internal > util > ProductPreferences


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 package org.eclipse.help.internal.util;
12
13 import java.io.IOException JavaDoc;
14 import java.io.InputStream JavaDoc;
15 import java.net.URL JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.Collection JavaDoc;
18 import java.util.HashMap JavaDoc;
19 import java.util.HashSet JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.LinkedHashSet JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Map JavaDoc;
24 import java.util.Properties JavaDoc;
25 import java.util.Set JavaDoc;
26 import java.util.StringTokenizer JavaDoc;
27
28 import org.eclipse.core.runtime.IConfigurationElement;
29 import org.eclipse.core.runtime.IProduct;
30 import org.eclipse.core.runtime.Platform;
31 import org.eclipse.core.runtime.Plugin;
32 import org.eclipse.core.runtime.Preferences;
33 import org.eclipse.help.internal.HelpData;
34 import org.eclipse.help.internal.HelpPlugin;
35 import org.osgi.framework.Bundle;
36
37 /*
38  * Reads and processes product preferences by considering not only the active
39  * product, but all installed products.
40  *
41  * For example, help orders the books in the table of contents in such a way that
42  * satisfies the currently running product's preferred order, and as many other product's
43  * preferred orderings.
44  */

45 public class ProductPreferences {
46
47     private static final String JavaDoc TRUE = String.valueOf(true);
48     private static Properties JavaDoc[] productPreferences;
49     private static SequenceResolver orderResolver;
50     private static Map JavaDoc preferencesToPluginIdMap;
51     private static Map JavaDoc preferencesToProductIdMap;
52     private static List JavaDoc primaryTocOrdering;
53     private static List JavaDoc[] secondaryTocOrderings;
54     
55     /*
56      * Returns the recommended order to display the given toc entries in. Each
57      * toc entry is a String, either the id of the toc contribution or the
58      * id of the category of tocs.
59      */

60     public static List JavaDoc getTocOrder(List JavaDoc itemsToOrder) {
61         return getOrderedList(itemsToOrder, getPrimaryTocOrdering(), getSecondaryTocOrderings());
62     }
63     
64     /*
65      * Returns the primary toc ordering. This is the preferred order for the active
66      * product (either specified via help data xml file or deprecated comma-separated
67      * list in plugin_customization.ini). Help data takes precedence.
68      */

69     public static List JavaDoc getPrimaryTocOrdering() {
70         if (primaryTocOrdering == null) {
71             IProduct product = Platform.getProduct();
72             if (product != null) {
73                 String JavaDoc pluginId = product.getDefiningBundle().getSymbolicName();
74                 Preferences prefs = HelpPlugin.getDefault().getPluginPreferences();
75                 String JavaDoc helpDataFile = prefs.getString(HelpPlugin.HELP_DATA_KEY);
76                 String JavaDoc baseTOCS = prefs.getString(HelpPlugin.BASE_TOCS_KEY);
77                 primaryTocOrdering = getTocOrdering(pluginId, helpDataFile, baseTOCS);
78             }
79             // active product has no preference for toc order
80
if (primaryTocOrdering == null) {
81                 primaryTocOrdering = new ArrayList JavaDoc();
82             }
83         }
84         return primaryTocOrdering;
85     }
86     
87     /*
88      * Returns all secondary toc ordering. These are the preferred toc orders of all
89      * defined products except the active product.
90      */

91     public static List JavaDoc[] getSecondaryTocOrderings() {
92         if (secondaryTocOrderings == null) {
93             List JavaDoc list = new ArrayList JavaDoc();
94             Properties JavaDoc[] productPreferences = getProductPreferences(false);
95             for (int i=0;i<productPreferences.length;++i) {
96                 String JavaDoc pluginId = (String JavaDoc)preferencesToPluginIdMap.get(productPreferences[i]);
97                 String JavaDoc helpDataFile = (String JavaDoc)productPreferences[i].get(HelpPlugin.PLUGIN_ID + '/' + HelpPlugin.HELP_DATA_KEY);
98                 String JavaDoc baseTOCS = (String JavaDoc)productPreferences[i].get(HelpPlugin.PLUGIN_ID + '/' + HelpPlugin.BASE_TOCS_KEY);
99                 List JavaDoc ordering = getTocOrdering(pluginId, helpDataFile, baseTOCS);
100                 if (ordering != null) {
101                     list.add(ordering);
102                 }
103             }
104             secondaryTocOrderings = (List JavaDoc[])list.toArray(new List JavaDoc[list.size()]);
105         }
106         return secondaryTocOrderings;
107     }
108
109     /*
110      * Returns the preferred toc ordering of the product defined by the given
111      * plug-in that has the given helpDataFile and baseTOCS specified (these last
112      * two may be null if not specified).
113      */

114     public static List JavaDoc getTocOrdering(String JavaDoc pluginId, String JavaDoc helpDataFile, String JavaDoc baseTOCS) {
115         if (helpDataFile != null && helpDataFile.length() > 0) {
116             Bundle bundle = Platform.getBundle(pluginId);
117             URL JavaDoc helpDataUrl = bundle.getEntry(helpDataFile);
118             HelpData helpData = new HelpData(helpDataUrl);
119             return helpData.getTocOrder();
120         }
121         else {
122             if (baseTOCS != null) {
123                 return tokenize(baseTOCS);
124             }
125         }
126         return null;
127     }
128     
129     /*
130      * Returns the boolean preference for the given key by consulting every
131      * product's preferences. If any of the products want the preference to
132      * be true (or use the default and the default is true), returns true.
133      * Otherwise returns false (if no products want it true).
134      */

135     public static boolean getBoolean(Plugin plugin, String JavaDoc key) {
136         Properties JavaDoc[] properties = getProductPreferences(true);
137         String JavaDoc defaultValue = plugin.getPluginPreferences().getDefaultString(key);
138         String JavaDoc currentValue = plugin.getPluginPreferences().getString(key);
139         String JavaDoc pluginId = plugin.getBundle().getSymbolicName();
140         if (currentValue != null && currentValue.equalsIgnoreCase(TRUE)) {
141             return true;
142         }
143         for (int i=0;i<properties.length;++i) {
144             String JavaDoc value = (String JavaDoc)properties[i].get(pluginId + '/' + key);
145             if (value == null) {
146                 value = defaultValue;
147             }
148             if (value != null && value.equalsIgnoreCase(TRUE)) {
149                 return true;
150             }
151         }
152         return false;
153     }
154     
155     /*
156      * Returns the given items in an order that satistfies the most products'
157      * preferences. Uses the given key for the preference stored in the given
158      * plugin to order the items. The active product is given precedence, then
159      * other products are considered.
160      */

161     public static List JavaDoc getOrderedList(Plugin plugin, String JavaDoc key, List JavaDoc items) {
162         List JavaDoc primary = tokenize(plugin.getPluginPreferences().getString(key));
163         Properties JavaDoc[] productPreferences = getProductPreferences(false);
164         List JavaDoc secondaryLists = new ArrayList JavaDoc();
165         for (int i=0;i<productPreferences.length;++i) {
166             String JavaDoc value = productPreferences[i].getProperty(plugin.getBundle().getSymbolicName() + '/' + key);
167             if (value != null) {
168                 secondaryLists.add(tokenize(value));
169             }
170         }
171         List JavaDoc[] secondary = (List JavaDoc[])secondaryLists.toArray(new List JavaDoc[secondaryLists.size()]);
172         return getOrderedList(items, primary, secondary);
173     }
174
175     /*
176      * Returns the given items in the order specified. Items listed in the order
177      * but not present are skipped, and items present but not ordered are added
178      * at the end.
179      */

180     public static List JavaDoc getOrderedList(List JavaDoc items, List JavaDoc order) {
181         return getOrderedList(items, order, null);
182     }
183
184     /*
185      * Returns the given items in an order that best satisfies the given orderings.
186      * The primary ordering must be satisfied in all cases. As many secondary orderings
187      * as reasonably possible will be satisfied.
188      */

189     public static List JavaDoc getOrderedList(List JavaDoc items, List JavaDoc primary, List JavaDoc[] secondary) {
190         List JavaDoc result = new ArrayList JavaDoc();
191         LinkedHashSet JavaDoc set = new LinkedHashSet JavaDoc(items);
192         if (orderResolver == null) {
193             orderResolver = new SequenceResolver();
194         }
195         List JavaDoc order = orderResolver.getSequence(primary, secondary);
196         Iterator JavaDoc iter = order.iterator();
197         while (iter.hasNext()) {
198             Object JavaDoc obj = iter.next();
199             if (set.contains(obj)) {
200                 result.add(obj);
201                 set.remove(obj);
202             }
203         }
204         result.addAll(set);
205         return result;
206     }
207
208     public static synchronized String JavaDoc getPluginId(Properties JavaDoc prefs) {
209         return (String JavaDoc)preferencesToPluginIdMap.get(prefs);
210     }
211
212     public static synchronized String JavaDoc getProductId(Properties JavaDoc prefs) {
213         return (String JavaDoc)preferencesToProductIdMap.get(prefs);
214     }
215
216     /*
217      * Returns the preferences for all products in the runtime environment (even if
218      * they are not active).
219      */

220     public static synchronized Properties JavaDoc[] getProductPreferences(boolean includeActiveProduct) {
221         if (productPreferences == null) {
222             String JavaDoc activeProductId = null;
223             IProduct activeProduct = Platform.getProduct();
224             if (activeProduct != null) {
225                 activeProductId = activeProduct.getId();
226             }
227             Collection JavaDoc collection = new ArrayList JavaDoc();
228             IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor("org.eclipse.core.runtime.products"); //$NON-NLS-1$
229
for (int i=0;i<elements.length;++i) {
230                 if (elements[i].getName().equals("product")) { //$NON-NLS-1$
231
String JavaDoc productId = elements[i].getDeclaringExtension().getUniqueIdentifier();
232                     if (includeActiveProduct || activeProductId == null || !activeProductId.equals(productId)) {
233                         String JavaDoc contributor = elements[i].getContributor().getName();
234                         IConfigurationElement[] propertyElements = elements[i].getChildren("property"); //$NON-NLS-1$
235
for (int j=0;j<propertyElements.length;++j) {
236                             String JavaDoc name = propertyElements[j].getAttribute("name"); //$NON-NLS-1$
237
if (name != null && name.equals("preferenceCustomization")) { //$NON-NLS-1$
238
String JavaDoc value = propertyElements[j].getAttribute("value"); //$NON-NLS-1$
239
if (value != null) {
240                                     Properties JavaDoc properties = loadPropertiesFile(contributor, value);
241                                     if (properties != null) {
242                                         collection.add(properties);
243                                     }
244                                     if (preferencesToPluginIdMap == null) {
245                                         preferencesToPluginIdMap = new HashMap JavaDoc();
246                                     }
247                                     preferencesToPluginIdMap.put(properties, contributor);
248                                     if (preferencesToProductIdMap == null) {
249                                         preferencesToProductIdMap = new HashMap JavaDoc();
250                                     }
251                                     preferencesToProductIdMap.put(properties, productId);
252                                 }
253                             }
254                         }
255                     }
256                 }
257             }
258             productPreferences = (Properties JavaDoc[])collection.toArray(new Properties JavaDoc[collection.size()]);
259         }
260         return productPreferences;
261     }
262     
263     /*
264      * Returns all the unique values for the given key in all the properties
265      * provided. For example, if two of them have "true" and one has "false", it
266      * will return "true" and "false".
267      */

268     public static Set JavaDoc getUniqueValues(Plugin plugin, String JavaDoc key, Properties JavaDoc[] properties) {
269         Set JavaDoc set = new HashSet JavaDoc();
270         String JavaDoc defaultValue = plugin.getPluginPreferences().getDefaultString(key);
271         String JavaDoc currentValue = plugin.getPluginPreferences().getString(key);
272         String JavaDoc pluginId = plugin.getBundle().getSymbolicName();
273         for (int i=0;i<properties.length;++i) {
274             String JavaDoc value = (String JavaDoc)properties[i].get(pluginId + '/' + key);
275             set.add(value != null ? value : defaultValue);
276         }
277         set.add(currentValue != null ? currentValue : defaultValue);
278         return set;
279     }
280     
281     /*
282      * Returns the value for the given key by consulting the given properties, but giving
283      * precedence to the primary properties. If the primary properties has the key, it is
284      * returned. Otherwise, it will return the value of the first secondary properties that
285      * has the key, or null if none of them has it.
286      */

287     public static String JavaDoc getValue(String JavaDoc key, Properties JavaDoc primary, Properties JavaDoc[] secondary) {
288         String JavaDoc value = null;
289         if (primary != null) {
290             value = primary.getProperty(key);
291         }
292         if (value == null) {
293             for (int i=0;i<secondary.length;++i) {
294                 if (secondary[i] != primary) {
295                     value = secondary[i].getProperty(key);
296                     if (value != null) {
297                         break;
298                     }
299                 }
300             }
301         }
302         return value;
303     }
304
305     /*
306      * Loads and returns the properties in the given properties file. The path is
307      * relative to the bundle with the given id.
308      */

309     public static Properties JavaDoc loadPropertiesFile(String JavaDoc bundleId, String JavaDoc path) {
310         Bundle bundle = Platform.getBundle(bundleId);
311         if (bundle != null) {
312             URL JavaDoc url = bundle.getEntry(path);
313             if (url != null) {
314                 InputStream JavaDoc in = null;
315                 try {
316                     in = url.openStream();
317                     Properties JavaDoc properties = new Properties JavaDoc();
318                     properties.load(in);
319                     return properties;
320                 }
321                 catch (IOException JavaDoc e) {
322                     // log the fact that it couldn't load it
323
HelpPlugin.logError("Error opening product's plugin customization file: " + bundleId + "/" + path, e); //$NON-NLS-1$ //$NON-NLS-2$
324
}
325                 finally {
326                     if (in != null) {
327                         try {
328                             in.close();
329                         }
330                         catch (IOException JavaDoc e) {
331                             // nothing we can do here
332
}
333                     }
334                 }
335             }
336         }
337         return null;
338     }
339     
340     /*
341      * Tokenizes the given list of items, allowing them to be separated by whitespace, commas,
342      * and/or semicolons.
343      *
344      * e.g. "item1, item2, item3"
345      * would return a list of strings containing "item1", "item2", and "item3".
346      */

347     public static List JavaDoc tokenize(String JavaDoc str) {
348         if (str != null) {
349             StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(str, " \n\r\t;,"); //$NON-NLS-1$
350
List JavaDoc list = new ArrayList JavaDoc();
351             while (tok.hasMoreElements()) {
352                 list.add(tok.nextToken());
353             }
354             return list;
355         }
356         return new ArrayList JavaDoc();
357     }
358 }
359
Popular Tags