MailServiceImpl.java

00001 
00027 package org.objectweb.jonas.mail;
00028 
00029 
00030 import java.io.FileNotFoundException;
00031 import java.util.Enumeration;
00032 import java.util.Hashtable;
00033 import java.util.List;
00034 import java.util.Properties;
00035 import java.util.StringTokenizer;
00036 import java.util.Vector;
00037 
00038 import javax.management.JMException;
00039 import javax.management.MBeanServer;
00040 import javax.management.ObjectName;
00041 import javax.management.modelmbean.ModelMBean;
00042 import javax.naming.Context;
00043 import javax.naming.InitialContext;
00044 import javax.naming.NamingException;
00045 
00046 import org.apache.commons.modeler.ManagedBean;
00047 import org.apache.commons.modeler.Registry;
00048 import org.objectweb.jonas.common.JModule;
00049 import org.objectweb.jonas.common.JProp;
00050 import org.objectweb.jonas.common.Log;
00051 import org.objectweb.jonas.common.PropDump;
00052 import org.objectweb.jonas.jmx.J2eeObjectName;
00053 import org.objectweb.jonas.jmx.JmxService;
00054 import org.objectweb.jonas.jmx.JonasObjectName;
00055 import org.objectweb.jonas.mail.factory.JavaMail;
00056 import org.objectweb.jonas.mail.factory.JavaMailMimePartDS;
00057 import org.objectweb.jonas.mail.factory.JavaMailMimePartDSResource;
00058 import org.objectweb.jonas.mail.factory.JavaMailSession;
00059 import org.objectweb.jonas.mail.factory.JavaMailSessionResource;
00060 import org.objectweb.jonas.management.JonasMBeanTools;
00061 import org.objectweb.jonas.service.AbsServiceImpl;
00062 import org.objectweb.jonas.service.ServiceException;
00063 import org.objectweb.jonas.service.ServiceManager;
00064 import org.objectweb.util.monolog.api.BasicLevel;
00065 import org.objectweb.util.monolog.api.Logger;
00075 public class MailServiceImpl extends AbsServiceImpl
00076     implements MailService, MailServiceImplMBean {
00077 
00081     private Vector mailSessionList = null;
00082 
00086     private Vector mailMimePartDSList = null;
00087 
00091     private MBeanServer mbeanServer = null;
00092 
00096     private Context ictx = null;
00097 
00098     // the name of the JOnAS server that is administerd by the MBeanServer
00099     // the current management domain's name
00100     protected String serverName = null;
00101     protected String domainName = null;
00102 
00106     private static Logger logger = null;
00107 
00111     private Vector factoryNames = new Vector();
00112 
00116     private Hashtable jMailSessionFactories = new Hashtable();
00117 
00121     private Hashtable jMailMimePartDSFactories = new Hashtable();
00122 
00128     private Hashtable bindedFactories = new Hashtable();
00129 
00133     private static final int JAVAX_MAIL_SESSION_FACTORY = 1;
00134 
00138     private static final int JAVAX_MAIL_INTERNET_MIMEPARTDATASOURCE = 2;
00139 
00143     public static final String PROPERTY_NAME = "mail.factory.name";
00144 
00148     public static final String PROPERTY_TYPE = "mail.factory.type";
00149 
00150     public static final String SESSION_PROPERTY_TYPE = "javax.mail.Session";
00151     public static final String MIMEPART_PROPERTY_TYPE = "javax.mail.internet.MimePartDataSource";
00152 
00156     public static final String FACTORIES = "jonas.service.mail.factories";
00157 
00161     public static final String CLASS = "jonas.service.mail.class";
00162 
00168     protected void doInit(Context ctx) throws ServiceException {
00169 
00170         // get logger for this service
00171         logger = Log.getLogger(Log.JONAS_MAIL_PREFIX);
00172         // the logger for reconfig management
00173         super.initLogger(Log.getLogger(Log.JONAS_MANAGEMENT_PREFIX));
00174 
00175         //Get the inital Context
00176         try {
00177             ictx = new InitialContext();
00178         } catch (NamingException e) {
00179             logger.log(BasicLevel.ERROR, "Cannot create initial context during the mail service initializing");
00180             throw new ServiceException("Cannot create initial context during the mail service initializing", e);
00181         }
00182 
00183         // Get the current server and domain names
00184         try {
00185             serverName = (String) ctx.lookup(JProp.JONAS_NAME);
00186             domainName = (String) ctx.lookup(JProp.DOMAIN_NAME);
00187         } catch (NamingException ne) {
00188             logger.log(BasicLevel.DEBUG, "Cannot initialize the Mail service " + ne);
00189             throw new ServiceException("Cannot initialize the Mail service", ne);
00190         }
00191 
00192         // Get the JMX Server via JMX Service
00193         try {
00194             mbeanServer =
00195                 ((JmxService) ServiceManager.getInstance().getJmxService()).getJmxServer();
00196         } catch (Exception e) {
00197             // the JMX service may not be started
00198             mbeanServer = null;
00199         }
00200 
00201         // Get the list of the factory names
00202         String factories = null;
00203         try {
00204             factories = (String) ctx.lookup(FACTORIES);
00205         } catch (NamingException e) {
00206             ; // No problem if there is no value for 'factories'
00207         }
00208         if (factories != null) {
00209             StringTokenizer st = new StringTokenizer(factories, ",");
00210             while (st.hasMoreTokens()) {
00211                 factoryNames.add(st.nextToken().trim());
00212             }
00213         }
00214         logger.log(BasicLevel.DEBUG, "Mail service initialized");
00215 
00216     }
00217 
00222     protected void doStart() throws ServiceException {
00223 
00224         // creates each factory
00225         String factoryName = null;
00226         for (int i = 0; i < factoryNames.size(); i++) {
00227             factoryName = (String) factoryNames.elementAt(i);
00228             try {
00229                 JProp prop = JProp.getInstance(factoryName);
00230                 if (logger.isLoggable(BasicLevel.DEBUG)) {
00231                     logger.log(BasicLevel.DEBUG, "Creating mail factory " + factoryName);
00232                 }
00233                 createMailFactory(factoryName, prop.getConfigFileEnv());
00234             } catch (Exception e) {
00235                 if (logger.isLoggable(BasicLevel.ERROR)) {
00236                     logger.log(BasicLevel.ERROR, "JOnAS: Cannot create mail factory " + factoryName + " : " + e);
00237                     logger.log(BasicLevel.ERROR, "Please check the " + factoryName + ".properties file");
00238                 }
00239             }
00240         }
00241 
00242         try {
00243             // Register MailService MBean : MailServiceImplMBean
00244             if (mbeanServer != null) {
00245                 mbeanServer.registerMBean(this, JonasObjectName.mailService());
00246             }
00247         } catch (JMException e) {
00248             throw new ServiceException("Cannot start the MailService: " , e);
00249         }
00250 
00251     }
00252 
00257     protected void doStop() throws ServiceException {
00258 
00259         try {
00260             unbindMailFactories();
00261         } catch (MailServiceException e) {
00262             logger.log(BasicLevel.ERROR, "Cannot unbind mail factories " + e);
00263             throw new ServiceException("Cannot unbind mail factories ", e);
00264         }
00265 
00266         if (mbeanServer != null) {
00267             try {
00268                 mbeanServer.unregisterMBean(JonasObjectName.mailService());
00269                 // unregister all mail factories
00270             } catch (Exception e) {
00271                 logger.log(BasicLevel.ERROR, "Cannot stop the Mail Service (JMX): " + e.getMessage());
00272                 throw new ServiceException("Cannot stop the mail service (JMX).", e);
00273             }
00274         }
00275         logger.log(BasicLevel.DEBUG, "mail service stopped");
00276     }
00277 
00286     public void recreateJavaMailFactory(JavaMail factory) throws MailServiceException {
00287         String jndiName = factory.getName();
00288         // Rebind the factory object in the naming context
00289         try {
00290             ictx.rebind(jndiName, factory);
00291         } catch (NamingException e) {
00292             logger.log(BasicLevel.ERROR, "Cannot bind mail factory '" + jndiName + "'  :" + e.getMessage());
00293             throw new MailServiceException("Cannot bind mail factory " + jndiName + ".", e);
00294         }
00295     }
00296 
00308     public void renameJavaMailFactory(String oldName, JavaMail factory) throws MailServiceException {
00309 
00310         logger.log(BasicLevel.DEBUG, "In renameMailFactory, old name = " + oldName);
00311         try {
00312             ictx.unbind(oldName);
00313             logger.log(BasicLevel.DEBUG, oldName + " unbound");
00314         } catch (Exception e) {
00315             logger.log(BasicLevel.DEBUG, "Warning: cannot unbind mail factory object named " + oldName);
00316         }
00317         String jndiName = factory.getName();
00318         // Rebind the factory object in the naming context
00319         try {
00320             ictx.rebind(jndiName, factory);
00321             logger.log(BasicLevel.DEBUG, "factory rebound under the name " + jndiName);
00322         } catch (NamingException e) {
00323             logger.log(BasicLevel.ERROR, "Cannot bind mail factory '" + jndiName + "'  :" + e.getMessage());
00324             throw new MailServiceException("Cannot bind mail factory " + jndiName + ".", e);
00325         }
00326         bindedFactories.put(jndiName, factory.getFactoryName());
00327         bindedFactories.remove(oldName);
00328     }
00329 
00338     public void createMailFactory(String factoryName, Properties props)
00339         throws MailServiceException {
00340 
00341         PropDump.print("These are the properties from which the MailService picks to construct Mail Factories", props, logger, BasicLevel.DEBUG);
00342 
00343         Object factory = null;
00344 
00345         //Factory type/jndi name must be non null
00346         String factoryType = props.getProperty(PROPERTY_TYPE);
00347         String jndiName = props.getProperty(PROPERTY_NAME);
00348 
00349         if (jndiName == null) {
00350             logger.log(BasicLevel.ERROR, "The property 'mail.factory.name' is a required property.");
00351             throw new MailServiceException("The property 'mail.factory.name' is a required property for this factory.");
00352         }
00353 
00354         if (factoryType == null) {
00355             logger.log(BasicLevel.ERROR, "The property 'mail.factory.type' is a required property.");
00356             throw new MailServiceException("The property 'mail.factory.type' is a required property for this factory.");
00357         }
00358 
00359         // Verify that jndi name not already used
00360         if (bindedFactories.containsKey(jndiName)) {
00361             logger.log(BasicLevel.ERROR, "There is already a factory bound with the name " + jndiName);
00362             throw new MailServiceException("There is already a factory bound with the name '" + jndiName +  "', please correct the provided configuration properties");
00363         }
00364 
00365         //Define the type of our factory
00366         int typeOfFactory;
00367         if (factoryType.equalsIgnoreCase("javax.mail.Session")) {
00368             typeOfFactory = JAVAX_MAIL_SESSION_FACTORY;
00369         } else if (factoryType.equalsIgnoreCase("javax.mail.internet.MimePartDataSource")) {
00370             typeOfFactory = JAVAX_MAIL_INTERNET_MIMEPARTDATASOURCE;
00371         } else {
00372             typeOfFactory = 0;
00373         }
00374 
00375         // Create the factory object and register it in the internal data structure
00376         switch (typeOfFactory) {
00377 
00378         case JAVAX_MAIL_SESSION_FACTORY :
00379             JavaMailSession sessionFactory = new JavaMailSession(factoryName, jndiName, props);
00380             jMailSessionFactories.put(factoryName, sessionFactory);
00381             factory = sessionFactory;
00382             break;
00383 
00384         case JAVAX_MAIL_INTERNET_MIMEPARTDATASOURCE :
00385             JavaMailMimePartDS mimeFactory = new JavaMailMimePartDS(factoryName, jndiName, props);
00386             jMailMimePartDSFactories.put(factoryName, mimeFactory);
00387             factory = mimeFactory;
00388             break;
00389 
00390         default :
00391             throw new MailServiceException("Can not create a factory of the type '" + factoryType + "'. This type is incorrect.");
00392         }
00393 
00394         // Bind the factory object in the naming context
00395         try {
00396             ictx.rebind(jndiName, factory);
00397             bindedFactories.put(jndiName, factoryName);
00398         } catch (NamingException e) {
00399             logger.log(BasicLevel.ERROR, "Cannot bind mail factory '" + jndiName + "'  :" + e.getMessage());
00400             throw new MailServiceException("Cannot bind mail factory " + jndiName + ".", e);
00401         }
00402 
00403         logger.log(BasicLevel.INFO, "Mapping Mail Factory " + factoryType + " on " + jndiName);
00404 
00405         // Register the factory object as an MBean with the jmx server
00406         // Get the MBean register (and load mbeans-descriptors)
00407         Registry oRegistry = JonasMBeanTools.getRegistry();
00408 
00409         // Register the factory object as an MBean with the jmx server
00410         try {
00411             if (mbeanServer != null) {
00412                 ObjectName on = null;
00413                 switch (typeOfFactory) {
00414                 case JAVAX_MAIL_SESSION_FACTORY :
00415                     // J2EEManagement
00416 
00417                     on = J2eeObjectName.JavaMailResource(domainName, factoryName, serverName, SESSION_PROPERTY_TYPE);
00418                     JavaMailSessionResource javaMailSessionResource = new JavaMailSessionResource(on.toString(), false, false, false, (JavaMailSession) factory);
00419                     // JSR77
00420                     ManagedBean oManaged = oRegistry.findManagedBean("JavaMailSessionResource");
00421                     ModelMBean oMBean = oManaged.createMBean(javaMailSessionResource);
00422                     mbeanServer.registerMBean(oMBean, on);
00423                     //mbeanServer.registerMBean(s_mbean, on);
00424                     if (logger.isLoggable(BasicLevel.DEBUG)) {
00425                         logger.log(BasicLevel.DEBUG, "Register session mail factory with name " + factoryName);
00426                     }
00427                     break;
00428                 case JAVAX_MAIL_INTERNET_MIMEPARTDATASOURCE :
00429                     // J2EEManagement
00430                     on = J2eeObjectName.JavaMailResource(domainName, factoryName, serverName, MIMEPART_PROPERTY_TYPE);
00431                     JavaMailMimePartDSResource javaMailMimePartDSResource = new JavaMailMimePartDSResource(on.toString(), false, false, false, (JavaMailMimePartDS) factory);
00432                     // JSR77
00433                     oManaged = oRegistry.findManagedBean("JavaMailMimePartDSResource");
00434                     oMBean = oManaged.createMBean(javaMailMimePartDSResource);
00435                     mbeanServer.registerMBean(oMBean, on);
00436                     if (logger.isLoggable(BasicLevel.DEBUG)) {
00437                         logger.log(BasicLevel.DEBUG, "Register mime mail factory with name " + factoryName);
00438                     }
00439                 }
00440             }
00441         } catch (JMException me) {
00442             throw new MailServiceException("Cannot register mail factory '" + factoryName + "' in JMX server", me);
00443         } catch (Exception e) {
00444             logger.log(BasicLevel.WARN, "Could not register JavaMailResource MBean");
00445         }
00446 
00447 
00448     }
00449 
00460     public void createMailFactoryMBean(String name, Properties props, Boolean loadFromFile)
00461         throws MailServiceException {
00462 
00463         boolean fromFile = loadFromFile.booleanValue();
00464         if (!fromFile) {
00465             try {
00466                 logger.log(BasicLevel.DEBUG, "Call getInstance on JProp in order to create the properties file");
00467                 JProp.getInstance(name, props);
00468             } catch (Exception e) {
00469                 logger.log(BasicLevel.ERROR, "Cannot create mail factory " + name + " as cannot create properties file : " + e.toString());
00470                 throw new ServiceException("MailService: Cannot create mail factory " + name + ",\n" + e.toString());
00471             }
00472         }
00473         //call the internal proc
00474         try {
00475             createMailFactory(name, props);
00476         } catch (Exception e) {
00477             logger.log(BasicLevel.ERROR, "Cannot create mail factory: " + name);
00478             throw new ServiceException("MailService: Cannot create mail factory: " + name + ",\n" + e.toString());
00479         }
00480     }
00481 
00487     public void unbindMailFactories() throws MailServiceException {
00488         //Unbind all factories
00489         for (Enumeration e = jMailSessionFactories.keys(); e.hasMoreElements();) {
00490             unbindMailFactoryMBean((String) e.nextElement());
00491         }
00492         for (Enumeration e = jMailMimePartDSFactories.keys(); e.hasMoreElements();) {
00493             unbindMailFactoryMBean((String) e.nextElement());
00494         }
00495     }
00496 
00503     public void unbindMailFactoryMBean(String factoryName)
00504         throws MailServiceException {
00505 
00506         // determine the type of the factory and the jndi name
00507         String name = null;
00508         int typeOfFactory;
00509         JavaMailSession jmailSession = (JavaMailSession) jMailSessionFactories.get(factoryName);
00510         JavaMailMimePartDS jMailMimePartDS = (JavaMailMimePartDS) jMailMimePartDSFactories.get(factoryName);
00511         if (jmailSession != null) {
00512             name = jmailSession.getName();
00513             typeOfFactory = JAVAX_MAIL_SESSION_FACTORY;
00514         } else if (jMailMimePartDS != null) {
00515             name = jMailMimePartDS.getName();
00516             typeOfFactory = JAVAX_MAIL_INTERNET_MIMEPARTDATASOURCE;
00517         } else {
00518             throw new MailServiceException("Can not unload the mail factory '" + factoryName + "' (this is not a known factory name");
00519         }
00520 
00521         // unbind the factory
00522         try {
00523             ictx.unbind(name);
00524             bindedFactories.remove(name);
00525         } catch (NamingException e) {
00526             throw new MailServiceException("Can not unbind the factory '" + name + "'.", e);
00527         }
00528 
00529         // De-register the factory object from the jmx server and remove the factory from the internal data structure
00530         try {
00531             if (mbeanServer != null) {
00532                 ObjectName on = null;
00533                 switch (typeOfFactory) {
00534                 case JAVAX_MAIL_SESSION_FACTORY :
00535                     // J2EEManagement
00536                     on = J2eeObjectName.JavaMailResource(domainName, factoryName, serverName, SESSION_PROPERTY_TYPE);
00537                     mbeanServer.unregisterMBean(on);
00538                     if (logger.isLoggable(BasicLevel.DEBUG)) {
00539                         logger.log(BasicLevel.DEBUG, "Unregister session mail factory with name " + factoryName);
00540                     }
00541                     jMailSessionFactories.remove(factoryName);
00542                     break;
00543                 case JAVAX_MAIL_INTERNET_MIMEPARTDATASOURCE :
00544                     // J2EEManagement
00545                     on = J2eeObjectName.JavaMailResource(domainName, factoryName, serverName, MIMEPART_PROPERTY_TYPE);
00546                     mbeanServer.unregisterMBean(on);
00547                     if (logger.isLoggable(BasicLevel.DEBUG)) {
00548                         logger.log(BasicLevel.DEBUG, "Unregister mime mail factory with name " + factoryName);
00549                     }
00550                     jMailMimePartDSFactories.remove(factoryName);
00551                 }
00552             }
00553         } catch (JMException me) {
00554             throw new MailServiceException("Cannot unregister mail factory '" + factoryName + "' from the JMX server", me);
00555         }
00556 
00557 
00558     }
00559 
00565     public String getFactoryName(String jndiName) {
00566         return (String) bindedFactories.get(jndiName);
00567     }
00568 
00573     public Integer getCurrentNumberOfMailFactories() {
00574         return new Integer(jMailSessionFactories.size() + jMailMimePartDSFactories.size());
00575     }
00576 
00581     public Integer getCurrentNumberOfSessionMailFactories() {
00582         return new Integer(jMailSessionFactories.size());
00583     }
00584 
00589     public Integer getCurrentNumberOfMimeMailFactories() {
00590         return new Integer(jMailMimePartDSFactories.size());
00591     }
00592 
00599     public Properties getMailFactoryPropertiesFile(String configFile) throws Exception {
00600         try {
00601             return JProp.getInstance(configFile).getConfigFileEnv();
00602         } catch (Exception e) {
00603             if (e instanceof FileNotFoundException) {
00604                 logger.log(BasicLevel.ERROR, "Please check if " + configFile + ".properties is available in JONAS_ROOT/config, HOME, or .");
00605             } else {
00606                 logger.log(BasicLevel.ERROR, "Error occured when reading file " + configFile);
00607             }
00608             throw e;
00609         }
00610     }
00611 
00616     public List getMailFactoryPropertiesFiles() throws Exception {
00617         return JModule.getMailFactoryPropsInDir();
00618     }
00623     public List getMimePartMailFactoryPropertiesFiles() throws Exception {
00624         return JModule.getMailFactoryPropsInDir(MIMEPART_PROPERTY_TYPE);
00625     }
00630     public List getSessionMailFactoryPropertiesFiles() throws Exception {
00631         return JModule.getMailFactoryPropsInDir(SESSION_PROPERTY_TYPE);
00632     }
00633 }

Generated on Tue Feb 15 15:05:18 2005 for JOnAS by  doxygen 1.3.9.1