KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > planetamessenger > mos > engine > JPluginEngine


1 /*
2     =========================================================================
3     Package engine - Implements the engine package.
4
5     This module is developed and maintained by PlanetaMessenger.org.
6     Specs, New and updated versions can be found in
7     http://www.planetamessenger.org
8     If you want contact the Team please send a email to Project Manager
9     Leidson Campos Alves Ferreira at leidson@planetamessenger.org
10
11     Copyright (C) since 2001 by PlanetaMessenger.org
12
13     This program is free software; you can redistribute it and/or modify
14     it under the terms of the GNU General Public License as published by
15     the Free Software Foundation; either version 2 of the License, or
16     (at your option) any later version.
17
18     This program is distributed in the hope that it will be useful,
19     but WITHOUT ANY WARRANTY; without even the implied warranty of
20     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21     GNU General Public License for more details.
22
23     You should have received a copy of the GNU General Public License
24     along with this program; if not, write to the Free Software
25     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
27     =========================================================================
28 */

29 /**
30  *
31  * $Id: JPluginEngine.java,v 1.40 2007/02/11 13:52:36 popolony2k Exp $
32  * $Author: popolony2k $
33  * $Name: $
34  * $Revision: 1.40 $
35  * $State: Exp $
36  *
37  */

38
39 package org.planetamessenger.mos.engine;
40
41 import org.planetamessenger.security.*;
42 import org.planetamessenger.plugin.*;
43 import org.planetamessenger.io.*;
44 import org.planetamessenger.mos.forms.*;
45 import java.util.*;
46 import java.util.jar.*;
47 import java.io.*;
48
49
50 public class JPluginEngine {
51
52   public static final int NULL_PLUGIN_OBJECT = -1;
53   public static final int INCOMPATIBLE_PLUGIN_SPECIFICATION = -2;
54
55   JPluginEngineListener pluginEngineListener = null;
56   JKernelAPIListener kernelAPIListener = null;
57   HashMap<Integer JavaDoc, JPlugin> hPluginList = null;
58   HashMap<Integer JavaDoc,JMOSSendMessageDlg> hMessageWindowList = null;
59
60   
61
62  /**
63    * Constructor. Initialize all class data.
64    */

65   public JPluginEngine() {
66    
67     hPluginList = new HashMap<Integer JavaDoc, JPlugin>();
68     hMessageWindowList = new HashMap<Integer JavaDoc, JMOSSendMessageDlg>();
69   }
70
71   /**
72    * Add the bridge between plugin engine
73    * and user interface
74    * @param listener The new listener to add;
75    */

76   public void addPluginEngineListener( JPluginEngineListener listener ) {
77     
78     pluginEngineListener = listener;
79   }
80
81   /**
82    * Remove the bridge between plugin engine
83    * and user interface
84    * @param listener The new listener to remove;
85    */

86   public void removePluginEngineListener( JPluginEngineListener listener ) {
87     
88     pluginEngineListener = null;
89   }
90   
91   /**
92    * Add the bridge between plugin engine and Kernel;
93    * @param listener The new listener to add;
94    */

95   public void addKernelAPIListener( JKernelAPIListener listener ) {
96     
97     kernelAPIListener = listener;
98   }
99
100   /**
101    * Remove the bridge between plugin engine and Kernel;
102    * @param listener The new listener to remove;
103    */

104   public void removeKernelAPIListener( JKernelAPIListener listener ) {
105     
106     kernelAPIListener = null;
107   }
108
109   /**
110    * Add a plugin to PluginList.
111    * This method will verify if the Plugin is already in list.
112    * @param plugin The Plugin that will be inserted in the
113    * PluginList;
114    */

115   public int add( JPlugin plugin ) {
116   
117     if( plugin != null ) {
118       if( plugin.getPluginProperties().getLibrarySpecificationMajorVersion() != JKernelConstants.MAJOR_LIBRARY_VERSION )
119         return INCOMPATIBLE_PLUGIN_SPECIFICATION;
120       else {
121         boolean bIsPluginAvailable = JSharedObjects.getProfileManager().checkPluginInstall( plugin.getPluginProperties().getPluginId() );
122
123         if( bIsPluginAvailable ) {
124           Integer JavaDoc iPluginId = new Integer JavaDoc( plugin.getPluginProperties().getPluginId() );
125           int nPluginListSize = hPluginList.values().toArray().length;
126           JPluginPreferencesContainer prefs = null;
127
128           // Searches for the Plugin in PluginList
129
for( int nCount = 0; nCount < nPluginListSize; nCount++ )
130             if( hPluginList.values().toArray()[nCount].getClass().getName().compareTo( plugin.getClass().getName() ) == 0 )
131               return -1;
132
133           plugin.addPluginEngineListener( JSharedObjects.getPluginEngineListener() );
134           plugin.addKernelAPIListener( JSharedObjects.getKernelManager() );
135           prefs = ( JPluginPreferencesContainer ) plugin.getPreferencesContainer();
136           hPluginList.put( iPluginId, plugin );
137           hMessageWindowList.put( iPluginId, new JMOSSendMessageDlg() );
138
139           // Add preference container object to plugin engine
140
if( prefs != null )
141             JSharedObjects.getPluginPreferencesManager().add( iPluginId.intValue(), prefs );
142
143           return iPluginId.intValue();
144         }
145       }
146     }
147     
148     return NULL_PLUGIN_OBJECT;
149   }
150
151   /**
152    * Removes a specific Plugin from PluginList.
153    * @param plugin The plugin that will be removed and destroyed;
154    */

155   public void remove( JPlugin plugin ) {
156     
157     Integer JavaDoc iPluginId = new Integer JavaDoc( plugin.getPluginProperties().getPluginId() );
158     
159     
160     hPluginList.remove( iPluginId );
161     hMessageWindowList.remove( iPluginId );
162     
163     if( pluginEngineListener != null )
164       pluginEngineListener.onDestroyPlugin( plugin );
165
166     try {
167       plugin.fireOnDestroy();
168     } catch( Exception JavaDoc e ) {
169       System.err.println( "JPluginEngine.remove() - " + e );
170     }
171     
172     JSharedObjects.getPluginPreferencesManager().remove( iPluginId.intValue() );
173     plugin = null;
174   }
175   
176   /**
177    * Called when the PluginManager will
178    * deallocate all plugins from memory.
179    * This method call the onDestroy for
180    * each allocated plugin.
181    */

182   public void removeAll() {
183
184     int nPluginListSize = hPluginList.values().toArray().length;
185   
186     
187     for( int nCount = 0; nCount < nPluginListSize; nCount++ ) {
188       org.planetamessenger.plugin.JPlugin plugin = ( org.planetamessenger.plugin.JPlugin ) hPluginList.values().toArray()[nCount];
189       
190       try {
191         plugin.fireOnDestroy();
192       } catch( Exception JavaDoc e ) {
193         System.err.println( "JPluginEngine.remove() - " + e );
194       }
195       
196       plugin = null;
197     }
198     
199     hPluginList.clear();
200     hMessageWindowList.clear();
201   }
202
203   /**
204    * Get a specific Plugin from PluginList
205    * based on Id passed by parameter.
206    * @param nPluginId The id from plugin
207    * that will be retrieved;
208    */

209   public JPlugin get( int nPluginId ) {
210     
211     Integer JavaDoc iPluginId = new Integer JavaDoc( nPluginId );
212     JPlugin plugin = ( JPlugin ) hPluginList.get( iPluginId );
213
214     
215     return plugin;
216   }
217   
218   /**
219    * Get a specific message window from List
220    * based on Id passed by parameter.
221    * @param nPluginId The id from plugin
222    * that dialog will be retrieved;
223    */

224   public JMOSSendMessageDlg getMessageWindow( int nPluginId ) {
225     
226     Integer JavaDoc iPluginId = new Integer JavaDoc( nPluginId );
227     JMOSSendMessageDlg msgDlg = ( JMOSSendMessageDlg ) hMessageWindowList.get( iPluginId );
228
229     return msgDlg;
230   }
231   
232   /**
233    * Return a array containing the complete
234    * window list.
235    * You must do a cast to JMOSSendMessageDlg
236    * for each array item to retrieve the correct
237    * object.
238    */

239   public Object JavaDoc[] getAllMessageWindows() {
240     
241     return hMessageWindowList.values().toArray();
242   }
243   
244   public JPlugin[] toArray() {
245   /**
246    * Get all PluginList in a JPlugin array.
247    */

248    
249     Object JavaDoc[] objectArray = hPluginList.values().toArray();
250
251     
252     if( objectArray.length == 0 )
253       return null;
254     
255     JPlugin[] pluginArray = new JPlugin[objectArray.length];
256     
257     for( int nCount = 0; nCount < objectArray.length; nCount++ )
258       pluginArray[nCount] = ( JPlugin ) objectArray[nCount];
259     
260     return pluginArray;
261   }
262
263   /**
264    * Destroy the engine.
265    */

266   public void destroy() {
267
268     removeAll();
269   }
270
271   /**
272    * Load a plugin from jar file.
273    * @param strJarFile The Jar file that the plugin will be loaded;
274    */

275   public JPlugin loadPlugin( String JavaDoc strJarFile ) {
276     
277     try {
278       JPlugin plugin = null;
279       JJarClassLoader jarLoader = new JJarClassLoader();
280       Manifest manifest = jarLoader.getManifestFromFile( strJarFile );
281
282       
283       // Load all jar Dependency
284
String JavaDoc strDependency = manifest.getMainAttributes().getValue( "Depends" );
285
286       if( strDependency != null ) {
287         StringTokenizer parser = new StringTokenizer( strDependency, ";" );
288         
289         try {
290           while( parser.hasMoreTokens() ) {
291             jarLoader.addDependency( JSharedObjects.getConfiguration().getDepLibPath() + parser.nextToken() );
292           }
293         } catch( java.util.NoSuchElementException JavaDoc e ) {
294           System.err.println( "JPluginEngine.loadPlugin() - " + e );
295         }
296       }
297
298       // Continue loading the Plugin Jar file
299
jarLoader.open( strJarFile );
300       
301       if( manifest != null ) {
302
303         String JavaDoc strEntryPointClass = manifest.getMainAttributes().getValue( "PluginEntryPoint" );
304         
305       
306         if( strEntryPointClass != null ) {
307
308           int nPluginId = JSharedObjects.getProfileManager().getPluginId( strEntryPointClass );
309
310           
311           if( nPluginId != -1 ) {
312             boolean bIsPluginInstalled = ( hPluginList.get( new Integer JavaDoc( nPluginId ) ) != null ? true : false );
313             boolean bIsPluginAvailable = JSharedObjects.getProfileManager().checkPluginInstall( nPluginId );
314
315             
316             if( bIsPluginAvailable && !bIsPluginInstalled ) {
317               
318               jarLoader.load();
319
320               try {
321                 String JavaDoc strPluginName = manifest.getMainAttributes().getValue( "PluginName" );
322                 String JavaDoc strPluginVersion = manifest.getMainAttributes().getValue( "Version" );
323                 String JavaDoc strPluginDescription = manifest.getMainAttributes().getValue( "Description" );
324                 String JavaDoc strPluginSpecMajorVersion = manifest.getMainAttributes().getValue( "PluginSpecMajorVersion" );
325                 String JavaDoc strPluginSpecMinorVersion = manifest.getMainAttributes().getValue( "PluginSpecMinorVersion" );
326                 String JavaDoc strPluginOwner = manifest.getMainAttributes().getValue( "Owner" );
327                 String JavaDoc strLicense = manifest.getMainAttributes().getValue( "License" );
328                 String JavaDoc strHomePage = manifest.getMainAttributes().getValue( "HomePage" );
329                 JPluginProperties pluginProperties = new JPluginProperties();
330
331
332                 pluginProperties.setPluginId( nPluginId );
333                 pluginProperties.setName( strPluginName );
334                 pluginProperties.setVersion( strPluginVersion );
335                 pluginProperties.setDescription( ( strPluginDescription == null ? "Default plugin implementation" : strPluginDescription ) );
336                 pluginProperties.setFileName( strJarFile );
337                 pluginProperties.setClassName( strEntryPointClass );
338                 pluginProperties.setPluginOwner( strPluginOwner );
339                 pluginProperties.setLicense( strLicense );
340                 pluginProperties.setHomePage( strHomePage );
341
342                 try {
343                   pluginProperties.setLibrarySpecificationMinorVersion( Integer.parseInt( strPluginSpecMinorVersion ) );
344                   pluginProperties.setLibrarySpecificationMajorVersion( Integer.parseInt( strPluginSpecMajorVersion ) );
345                 } catch( NumberFormatException JavaDoc e ) {
346                   System.err.println( "JPluginEngine.loadPlugin() - Invalid Plugin specification version" );
347                 }
348                 
349                 // Check if plugin was compiled with a kernel compatible library specification
350
if( pluginProperties.getLibrarySpecificationMajorVersion() == JKernelConstants.MAJOR_LIBRARY_VERSION ) {
351                   plugin = ( JPlugin ) jarLoader.loadClass( strEntryPointClass ).newInstance();
352                   plugin.fireOnCreate( pluginProperties );
353                   add( plugin );
354                 
355                   // Tell to PlanetaMessenger about plugin started
356
if( pluginEngineListener != null )
357                     pluginEngineListener.onCreatePlugin( plugin );
358                 }
359                 else {
360                   System.err.println( "JPluginEngine.loadPlugin() - " + pluginProperties.getName() + " was built with incompatible plugin library specification" );
361                   
362                   // Throws listener error handling
363
if( pluginEngineListener != null )
364                     pluginEngineListener.onError( pluginProperties.getPluginId(), pluginProperties.getName(), JPluginEngineListener.ERROR_INCOMPATIBLE_PLUGIN );
365                 }
366               } catch( ClassNotFoundException JavaDoc ce ) {
367                 System.err.println( "JPluginEngine.loadPlugin() - " + ce );
368               } catch( Exception JavaDoc e ) {
369                   System.err.println( "JPluginEngine.loadPlugin() - " + e );
370               }
371             }
372           }
373         }
374         else
375           System.err.println( "JPluginEngine.loadPlugin() - Unable to load the plugin. No entry point defined in Manifest file (PluginEntryPoint:)" );
376       }
377       
378       return plugin;
379       
380     } catch( JarException e ) {
381       System.err.println( "JPluginEngine.loadPlugin()" + e );
382       return null;
383     }
384   }
385
386   /**
387    * Loads all plugins for the specified profile.
388    * If a plugin is already in memory the plugin load will be ignored.
389    * @param nProfileId The profile that plugins will be loaded;
390    * @param bStartPlugin This flag starts plugin when true or when false
391    * only update the plugin's database table for new uninstalled plugins;
392    */

393   public boolean loadAllPlugins( long nProfileId, boolean bStartPlugin ) {
394
395     java.lang.String JavaDoc[] strPlugins;
396     File pluginList = new File( JSharedObjects.getConfiguration().getPluginsPath() );
397     JFilenameFilter pluginFilter = new JFilenameFilter();
398     int nPluginListSize;
399     
400    
401     // For plugins accept only jar files (for a while)
402
pluginFilter.add( "jar" );
403     strPlugins = pluginList.list( pluginFilter );
404     nPluginListSize = strPlugins.length;
405
406     // Only if will start the plugin
407
if( bStartPlugin )
408       JSharedObjects.getProfileManager().setProfileId( nProfileId );
409     
410     // No plugin files. Nothing to do !!!
411
if( nPluginListSize == 0 )
412       return true;
413     
414     for( int nCount = 0; nCount < nPluginListSize; nCount++ ) {
415       
416       JPlugin plugin;
417
418
419       // Only check and update plugins database table for new plugins
420
if( !bStartPlugin ) {
421         updateNewPlugin( JSharedObjects.getConfiguration().getPluginsPath() + strPlugins[nCount] );
422         continue;
423       }
424
425       plugin = loadPlugin( JSharedObjects.getConfiguration().getPluginsPath() + strPlugins[nCount] );
426
427       if( plugin != null ) {
428         java.lang.Object JavaDoc[] contactList = JSharedObjects.getContactListManager().getContactList( plugin ).values().toArray();
429         JUserInfo userInfo = JSharedObjects.getProfileManager().getUserInfo( plugin.getPluginProperties().getPluginId() );
430
431
432         // Starts the plugin session
433
if( userInfo != null ) {
434           org.planetamessenger.plugin.JContactListItem item = null;
435
436           
437           // Fill plugin contact list
438
for( int nItems = 0; nItems < contactList.length; nItems++ ) {
439             item = ( org.planetamessenger.plugin.JContactListItem ) contactList[nItems];
440             
441             // If contact isn't in list, not add the contact and remove from contact list database
442
if( item.getContactFlag() == JContactListItem.CONTACT_NOT_IN_LIST ) {
443               if( JSharedObjects.getContactListManager().countContactMessages( item ) > 0 )
444                 item.setStatus( JPlugin.STATUS_NOT_IN_LIST );
445               else {
446                 JSharedObjects.getContactListManager().removeFromContactList( plugin, item.getUserId() );
447                 continue;
448               }
449             }
450
451             JSharedObjects.getMainWindow().getContactList().addItem( item );
452           }
453
454           plugin.setUserInfo( userInfo );
455
456           // Brings up the plugin if, is a autoconnect plugin
457
if( userInfo.getAutoConnect() == 1 ) {
458             try {
459               plugin.fireOnLogin();
460             } catch( Exception JavaDoc e ) {
461               System.err.println( "JPluginEngine.loadAllPlugins() - " + e );
462             }
463           }
464         }
465       }
466     }
467     
468     return true;
469   }
470
471   /**
472    * Load the plugin information from jar file.
473    * @param strJarFile The Jar file that
474    * the plugin info will be loaded;
475    */

476   public JPluginProperties getPluginProperties( String JavaDoc strJarFile ) {
477     
478     try {
479       JPluginProperties pluginProperties = null;
480       JJarClassLoader jarLoader = new JJarClassLoader( strJarFile, false );
481       Manifest manifest = jarLoader.getManifest();
482     
483
484       if( manifest != null ) {
485
486         pluginProperties = new JPluginProperties();
487
488         pluginProperties.setName( manifest.getMainAttributes().getValue( "PluginName" ) );
489         pluginProperties.setVersion( manifest.getMainAttributes().getValue( "Version" ) );
490         pluginProperties.setDescription( manifest.getMainAttributes().getValue( "Description" ) );
491         pluginProperties.setClassName( manifest.getMainAttributes().getValue( "PluginEntryPoint" ) );
492         pluginProperties.setLicense( manifest.getMainAttributes().getValue( "License" ) );
493         pluginProperties.setPluginOwner( manifest.getMainAttributes().getValue( "Owner" ) );
494         pluginProperties.setHomePage( manifest.getMainAttributes().getValue( "HomePage" ) );
495         pluginProperties.setFileName( strJarFile );
496
497         try {
498           pluginProperties.setLibrarySpecificationMinorVersion( Integer.parseInt( manifest.getMainAttributes().getValue( "PluginSpecMinorVersion" ) ) );
499           pluginProperties.setLibrarySpecificationMajorVersion( Integer.parseInt( manifest.getMainAttributes().getValue( "PluginSpecMajorVersion" ) ) );
500         } catch( NumberFormatException JavaDoc e ) {
501           System.err.println( "JPluginEngine.getPluginProperties() - Invalid Plugin specification version" );
502         }
503       }
504
505       return pluginProperties;
506       
507     } catch( JarException e ) {
508       System.err.println( "JPluginEngine.getPluginProperties()" + e );
509       return null;
510     }
511   }
512
513   /**
514    * Load the plugin information based on class information.
515    * @param strClassName The class name to load properties;
516    */

517   public JPluginProperties getPluginPropertiesByClassName( String JavaDoc strClassName ) {
518
519     if( strClassName != null ) {
520
521       java.lang.String JavaDoc[] strPlugins;
522       JPluginProperties pluginProperties = null;
523       java.io.File JavaDoc pluginList = new File( JSharedObjects.getConfiguration().getPluginsPath() );
524       JFilenameFilter pluginFilter = new JFilenameFilter();
525       int nPluginListSize;
526
527
528       // For plugins we'll accept only jar files (for a while)
529
pluginFilter.add( "jar" );
530       strPlugins = pluginList.list( pluginFilter );
531       nPluginListSize = strPlugins.length;
532
533       // No plugin files. Nothing to do !!!
534
if( nPluginListSize == 0 )
535         return null;
536
537       for( int nCount = 0; nCount < nPluginListSize; nCount++ ) {
538
539         pluginProperties = getPluginProperties( JSharedObjects.getConfiguration().getPluginsPath() + strPlugins[nCount] );
540
541         if( strClassName.compareTo( pluginProperties.getClassName() ) == 0 )
542           return pluginProperties;
543       }
544     }
545
546     return null;
547   }
548
549   /**
550    * Get the number plugins loaded
551    */

552   public int getPluginCount() {
553    
554     return hPluginList.size();
555   }
556
557   // Event management
558
/**
559    * Handles the onSendMessage event of the SendMessage dialog.
560    * This method dispatches the onSendMessage event to the
561    * correct plugin onSendMessage event handler.
562    * @param selectedItem The JList selectes item;
563    * @param msg The Message that will sent;
564    */

565   public boolean onSendMessage( org.planetamessenger.plugin.JContactListItem selectedItem, java.lang.String JavaDoc msg ) {
566
567     JPlugin plugin = get( selectedItem.getPluginId() );
568
569     if( plugin != null ) {
570       if( plugin.isConnected() ) {
571         try {
572           return plugin.fireOnSendMessage( selectedItem.getUserId(), msg );
573         } catch( Exception JavaDoc e ) {
574           System.err.println( "JPluginEngine.onSendMessage() - " + e );
575           return false;
576         }
577       }
578       else {
579         // Throws listener capabilities handling
580
if( pluginEngineListener != null )
581           pluginEngineListener.onError( plugin.getPluginProperties().getPluginId(), plugin.getPluginProperties().getName(), JPluginEngineListener.ERROR_DISCONNECTED_PLUGIN );
582       }
583     }
584     
585     return false;
586   }
587   
588   // Private methods
589
/**
590    * Check if is new plugin and update plugins database table,
591    * inserting the new plugin.
592    * @param strJarFile The Jar file that plugin will be loaded;
593    */

594   private void updateNewPlugin( String JavaDoc strJarFile ) {
595     
596     try {
597       JPlugin plugin = null;
598       JJarClassLoader jarLoader = new JJarClassLoader();
599       Manifest manifest = jarLoader.getManifestFromFile( strJarFile );
600
601       // Continue loading the Plugin Jar file
602
jarLoader.open( strJarFile );
603       
604       if( manifest != null ) {
605         String JavaDoc strEntryPointClass = manifest.getMainAttributes().getValue( "PluginEntryPoint" );
606       
607         if( strEntryPointClass != null )
608           JSharedObjects.getProfileManager().getPluginId( strEntryPointClass );
609       }
610       
611       jarLoader.close();
612       jarLoader = null;
613       
614     } catch( JarException e ) {
615       System.err.println( "JPluginEngine.updateNewPlugin()" + e );
616     }
617   }
618 }
619 // JPluginEngine Class
620
Popular Tags