001: /*
002: * $Header: /cvs/j3dfly/J3dFly/src/org/jdesktop/j3dfly/plugins/PluginPreferenceControl.java,v 1.1 2005/04/20 21:04:41 paulby Exp $
003: *
004: * Sun Public License Notice
005: *
006: * The contents of this file are subject to the Sun Public License Version
007: * 1.0 (the "License"). You may not use this file except in compliance with
008: * the License. A copy of the License is available at http://www.sun.com/
009: *
010: * The Original Code is Java 3D(tm) Fly Through.
011: * The Initial Developer of the Original Code is Paul Byrne.
012: * Portions created by Paul Byrne are Copyright (C) 2002.
013: * All Rights Reserved.
014: *
015: * Contributor(s): Paul Byrne.
016: *
017: **/
018: package org.jdesktop.j3dfly.plugins;
019:
020: import java.io.*;
021: import java.beans.XMLEncoder;
022: import java.beans.XMLDecoder;
023: import java.util.ArrayList;
024: import org.jdesktop.j3dfly.J3dFly;
025: import org.jdesktop.j3dfly.utils.developmenttools.DevelopmentLocale;
026: import org.jdesktop.j3dfly.J3dFlyContext;
027: import org.jdesktop.j3dfly.utils.gui.ErrorHandler;
028: import org.jdesktop.j3dfly.utils.gui.ErrorManager;
029:
030: import java.beans.Introspector;
031: import java.beans.IntrospectionException;
032: import java.beans.PropertyDescriptor;
033: import java.beans.BeanInfo;
034: import java.beans.DefaultPersistenceDelegate;
035:
036: /**
037: *
038: * @author Paul Byrne
039: * @version $Revision: 1.1 $
040: */
041: public class PluginPreferenceControl extends Object {
042:
043: /** Holds value of property plugin. These may or may not be installed.
044: * These plugins generally control the main functions of the tool.*/
045: private ArrayList pluginSystemPrefs = new ArrayList();
046:
047: /** Holds the users preferences for plugins, which may or may not be installed.
048: * THese are user preferences such as default lighting and stereo settings etc.*/
049: private ArrayList pluginUserPrefs = new ArrayList();
050:
051: /**
052: * Holds the preferences for plugins from all the files currently loaded */
053: private ArrayList pluginFilePrefs = new ArrayList();
054:
055: private ArrayList pluginLoaderPrefs = new ArrayList();
056:
057: /**
058: * The installed plugins
059: */
060: private ArrayList plugins = new ArrayList();
061:
062: private java.io.File systemPrefsFile;
063: private java.io.File userPrefsFile;
064:
065: private J3dFlyContext context;
066:
067: /** Creates new PluginPreferenceControl */
068: public PluginPreferenceControl() {
069: }
070:
071: private void createDefaultPluginToolPrefs() {
072: /*
073: pluginToolPrefs.add(new com.sun.j3d.demos.j3dfly.plugins.FileHandlerPlugin.FileHandlerPluginPreference() );
074: pluginToolPrefs.add(new com.sun.j3d.demos.j3dfly.plugins.ViewingPlatformControlPlugin.ViewingPlatformControlPluginPreference() );
075: pluginToolPrefs.add(new com.sun.j3d.demos.j3dfly.plugins.ViewControlPlugin.ViewControlPluginPreference() );
076: pluginToolPrefs.add(new com.sun.j3d.demos.j3dfly.plugins.AppearanceAttributesPlugin.AppearanceAttributesPluginPreference() );
077: pluginToolPrefs.add(new com.sun.j3d.demos.j3dfly.plugins.J3dSkyPlugin.J3dSkyPluginPreference( false, false ));
078: pluginToolPrefs.add(new com.sun.j3d.demos.j3dfly.plugins.DefaultLightingPlugin.DefaultLightingPluginPreference( true, true ) );
079: pluginToolPrefs.add(new com.sun.j3d.demos.j3dfly.plugins.HelpSystemPlugin.HelpSystemPluginPreference( false, false ) );
080: */
081: // new PluginPreference( com.sun.j3d.demos.j3dfly.plugins.AnimationPlugin.class ),
082: }
083:
084: public void test() {
085: createDefaultPluginToolPrefs();
086:
087: savePluginSystemPreferences();
088: }
089:
090: /**
091: * Save the System Preferences into the file used at startup
092: */
093: public void savePluginSystemPreferences() {
094: System.out.println("Saving System Prefs to "
095: + systemPrefsFile.getName());
096: if (systemPrefsFile == null)
097: return;
098:
099: try {
100: savePluginPreferences(new BufferedOutputStream(
101: new FileOutputStream(systemPrefsFile)),
102: pluginSystemPrefs);
103: } catch (IOException e) {
104: ErrorManager.getDefault().notify(e, ErrorHandler.EXCEPTION);
105: }
106: }
107:
108: /**
109: * Save the User Preferences into the file used at startup
110: */
111: public void savePluginUserPreferences() {
112: if (userPrefsFile == null)
113: return;
114:
115: try {
116: savePluginPreferences(new BufferedOutputStream(
117: new FileOutputStream(userPrefsFile)),
118: pluginUserPrefs);
119: } catch (IOException e) {
120: ErrorManager.getDefault().notify(e, ErrorHandler.EXCEPTION);
121: }
122: }
123:
124: /**
125: * Store the file plugin preferences in the PluginJ3fData object. This
126: * will overwrite any existing information in PluginJ3fData
127: */
128: public void savePluginFilePreferences(PluginJ3fData data) {
129: java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
130: savePluginPreferences(out, pluginFilePrefs);
131: data.setData(out.toByteArray());
132: out.reset();
133: }
134:
135: public void loadPluginFilePreferences(PluginJ3fData data) {
136: if (data == null || data.getData() == null)
137: return;
138:
139: java.io.ByteArrayInputStream in = new java.io.ByteArrayInputStream(
140: data.getData());
141:
142: loadPlugins(pluginFilePrefs, in, context,
143: PluginPreference.FILE, null);
144: installPlugins(pluginFilePrefs);
145: }
146:
147: /**
148: * Write the plugin preferences to the supplied output stream
149: */
150: private void savePluginPreferences(java.io.OutputStream out,
151: ArrayList plugins) {
152: BeanInfo info = null;
153: try {
154: info = Introspector.getBeanInfo(PluginPreference.class);
155: } catch (IntrospectionException e) {
156: ErrorManager.getDefault().notify(e, ErrorHandler.ERROR);
157: }
158:
159: // Make these fields of the PluginPreference class transient
160: setTransient(info, "installedFrom");
161: setTransient(info, "plugin");
162: setTransient(info, "context");
163:
164: try {
165: java.beans.XMLEncoder e = new java.beans.XMLEncoder(out);
166: e.setPersistenceDelegate(J3dFlyContext.class,
167: new DefaultPersistenceDelegate());
168: for (int i = 0; i < plugins.size(); i++)
169: e.writeObject(plugins.get(i));
170: e.close();
171: } catch (Exception ex) {
172: ErrorManager.getDefault()
173: .notify(ex, ErrorHandler.EXCEPTION);
174: }
175: }
176:
177: /**
178: * Set the property in the BeanInfo to be transient, this means it will
179: * not be processed by XMLEncode
180: */
181: private void setTransient(BeanInfo info, String property) {
182: PropertyDescriptor[] propertyDescriptors = info
183: .getPropertyDescriptors();
184: for (int i = 0; i < propertyDescriptors.length; i++) {
185: PropertyDescriptor pd = propertyDescriptors[i];
186: if (property.equals(pd.getName())) {
187: pd.setValue("transient", Boolean.TRUE);
188: }
189: }
190: }
191:
192: /**
193: * @return array of PluginPreference
194: */
195: ArrayList getSystemPluginPrefs() {
196: return pluginSystemPrefs;
197: }
198:
199: /**
200: * @return array of PluginPreference
201: */
202: ArrayList getUserPluginPrefs() {
203: return pluginUserPrefs;
204: }
205:
206: /**
207: * @return array of PluginPreference
208: */
209: ArrayList getFilePluginPrefs() {
210: return pluginFilePrefs;
211: }
212:
213: /**
214: * Return the plugins which are actually installed.
215: *
216: * @return array of J3dFlyPlugin
217: */
218: ArrayList getInstalledPlugins() {
219: return plugins;
220: }
221:
222: /**
223: * Add the preference to the system preferences
224: */
225: void addSystemPluginPref(PluginPreference pref) {
226: pluginSystemPrefs.add(pref);
227: }
228:
229: /**
230: * Add the preference to the User preferences
231: */
232: void addUserPluginPref(PluginPreference pref) {
233: pluginUserPrefs.add(pref);
234: }
235:
236: /**
237: * Add the preference to the File preferences
238: */
239: void addFilePluginPref(PluginPreference pref) {
240: pluginFilePrefs.add(pref);
241: }
242:
243: /**
244: * Return true if the systemPrefs file can be written
245: */
246: boolean getSystemPrefsFileCanWrite() {
247: return (systemPrefsFile == null) ? false : true;
248: }
249:
250: /**
251: * Return true if the systemPrefs file can be written
252: */
253: boolean getUserPrefsFileCanWrite() {
254: return (userPrefsFile == null) ? false : true;
255: }
256:
257: /**
258: * Return the first installed plugin who's class equals
259: * pluginClass. Returns null if no matching plugin is
260: * found
261: */
262: public J3dFlyPlugin getPlugin(Class pluginClass) {
263: J3dFlyPlugin ret = null;
264: java.util.Iterator it = plugins.iterator();
265: while (it.hasNext() && ret == null) {
266: ret = (J3dFlyPlugin) it.next();
267: if (ret.getClass() != pluginClass)
268: ret = null;
269: }
270:
271: return ret;
272: }
273:
274: /**
275: * Load the plugin preferences from the Files and
276: * install the plugins.
277: *
278: * This also has the side effect of installing pluginLoaderPrefs if
279: * any have been added using addLoaderPlugins
280: */
281: public void installPlugins(java.io.File systemPrefsFile,
282: java.io.File userPrefsFile, J3dFlyContext context) {
283: this .context = context;
284:
285: if (systemPrefsFile.canWrite())
286: this .systemPrefsFile = systemPrefsFile;
287: else
288: this .systemPrefsFile = null;
289:
290: if (userPrefsFile != null)
291: if (userPrefsFile.canWrite())
292: this .userPrefsFile = userPrefsFile;
293: else
294: this .userPrefsFile = null;
295: else
296: this .userPrefsFile = null;
297:
298: loadPlugins(pluginSystemPrefs, systemPrefsFile, context,
299: PluginPreference.SYSTEM);
300: loadPlugins(pluginUserPrefs, userPrefsFile, context,
301: PluginPreference.USER);
302:
303: installPlugins(pluginSystemPrefs);
304: installPlugins(pluginUserPrefs);
305:
306: installPlugins(pluginLoaderPrefs);
307: }
308:
309: /**
310: * Add loader plugins to the pluginLoaderPrefs set.
311: *
312: * The plugins will not be installed until installPlugins(....) above is called
313: */
314: public void addLoaderPlugins(InputStream in, J3dFlyContext context,
315: ClassLoader classLoader) {
316: if (in == null)
317: ErrorManager.getDefault().notify(null,
318: ErrorHandler.INFORMATIONAL,
319: "Error loading Plugin preferences");
320: else
321: loadPlugins(pluginLoaderPrefs, in, context,
322: PluginPreference.LOADER, classLoader);
323:
324: }
325:
326: /**
327: * Returns the context for this Controller
328: */
329: J3dFlyContext getContext() {
330: return context;
331: }
332:
333: /**
334: * Install this plugin which has been read from a j3f file
335: */
336: public void installFilePlugin(PluginPreference pluginPref,
337: J3dFlyContext context) {
338: pluginPref.setContext(context);
339: pluginPref.setInstalledFrom(PluginPreference.FILE);
340: pluginPref.setInstalled(true);
341: pluginFilePrefs.add(pluginPref);
342: }
343:
344: /**
345: * Load the plugin preferences from URL into the plugins array
346: */
347: private void loadPlugins(ArrayList pluginPrefs, java.io.File file,
348: J3dFlyContext context, int installedFrom) {
349:
350: if (file == null || file.getName().length() == 0)
351: return;
352:
353: try {
354: InputStream in = new BufferedInputStream(
355: new FileInputStream(file));
356: loadPlugins(pluginPrefs, in, context, installedFrom, null);
357: in.close();
358: } catch (java.io.IOException e) {
359: ErrorManager.getDefault().notify(
360: e,
361: ErrorHandler.INFORMATIONAL,
362: "Error loading Plugin preferences from "
363: + file.getName());
364:
365: }
366: }
367:
368: /**
369: *
370: * If classLoader is null then the systemClassLoader is used, otherwise
371: * the XML decode is instantiated from classLoader
372: */
373: private void loadPlugins(ArrayList pluginPrefs, InputStream in,
374: J3dFlyContext context, int installedFrom,
375: ClassLoader classLoader) {
376:
377: java.beans.XMLDecoder decoder = null;
378: try {
379: if (classLoader == null)
380: decoder = new java.beans.XMLDecoder(in);
381: else {
382: try {
383: Class decoderClass = classLoader
384: .loadClass("java.beans.XMLDecoder");
385: java.lang.reflect.Constructor constructor = decoderClass
386: .getConstructor(new Class[] { java.io.InputStream.class });
387: decoder = (java.beans.XMLDecoder) constructor
388: .newInstance(new Object[] { in });
389: } catch (ClassNotFoundException clnfE) {
390: clnfE.printStackTrace();
391: } catch (NoSuchMethodException nsmE) {
392: nsmE.printStackTrace();
393: } catch (InstantiationException iE) {
394: iE.printStackTrace();
395: } catch (IllegalAccessException iaE) {
396: iaE.printStackTrace();
397: } catch (java.lang.reflect.InvocationTargetException itE) {
398: itE.printStackTrace();
399: }
400: }
401:
402: PluginPreference pref;
403: while (true) {
404: pref = (PluginPreference) decoder.readObject();
405: if (pref != null) {
406: pluginPrefs.add(pref);
407: pref.setContext(context);
408: pref.setInstalledFrom(installedFrom);
409: }
410: }
411: } catch (ArrayIndexOutOfBoundsException ex) {
412: // It's horrible, but ArrayIndexOutOfBounds indicates the
413: // end of the stream
414: decoder.close();
415: }
416:
417: }
418:
419: /**
420: * Install the plugins from pluginPrefs into the j3dfly context
421: *
422: * Only plugins with isInstalled==true are installed
423: */
424: private void installPlugins(ArrayList pluginPrefs) {
425: for (int i = 0; i < pluginPrefs.size(); i++) {
426: PluginPreference pref = (PluginPreference) pluginPrefs
427: .get(i);
428: if (pref != null && pref.isInstalled()) {
429: pref.setInstalled(true);
430: }
431: }
432: }
433:
434: /**
435: * Called by the Plugins when they are being uninstalled.
436: *
437: * This method removes the plugin from the list of installed plugins
438: */
439: void removeInstalledPlugin(J3dFlyPlugin plugin) {
440: int index = plugins.indexOf(plugin);
441: if (index == -1) {
442: System.out
443: .println("Failed to removed plugin from active plugins "
444: + plugin);
445: } else
446: plugins.remove(index);
447: }
448:
449: /**
450: * Called by Plugins when they are installed
451: *
452: * Add this plugin to the list of installed plugins
453: */
454: void addInstalledPlugin(J3dFlyPlugin plugin) {
455: plugins.add(plugin);
456: }
457:
458: /**
459: * Uninstall any plugins that have the same PluginPreference class type
460: */
461: void uninstallDuplicatePlugins(PluginPreference pref) {
462: java.util.Iterator it = plugins.iterator();
463: J3dFlyPlugin plugin = null;
464: boolean uninstall = false;
465:
466: while (it.hasNext() && !uninstall) {
467: plugin = (J3dFlyPlugin) it.next();
468: if (plugin.getPluginPreference().getClass() == pref
469: .getClass()) {
470: uninstall = true;
471: }
472: }
473:
474: if (uninstall) {
475: System.out.println("Uninstalling Duplicate Plugin "
476: + pref.getClass());
477: plugin.getPluginPreference().setInstalled(false);
478: }
479: }
480:
481: }
|