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
00099
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
00171 logger = Log.getLogger(Log.JONAS_MAIL_PREFIX);
00172
00173 super.initLogger(Log.getLogger(Log.JONAS_MANAGEMENT_PREFIX));
00174
00175
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
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
00193 try {
00194 mbeanServer =
00195 ((JmxService) ServiceManager.getInstance().getJmxService()).getJmxServer();
00196 } catch (Exception e) {
00197
00198 mbeanServer = null;
00199 }
00200
00201
00202 String factories = null;
00203 try {
00204 factories = (String) ctx.lookup(FACTORIES);
00205 } catch (NamingException e) {
00206 ;
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
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
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
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
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
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
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
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
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
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
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
00406
00407 Registry oRegistry = JonasMBeanTools.getRegistry();
00408
00409
00410 try {
00411 if (mbeanServer != null) {
00412 ObjectName on = null;
00413 switch (typeOfFactory) {
00414 case JAVAX_MAIL_SESSION_FACTORY :
00415
00416
00417 on = J2eeObjectName.JavaMailResource(domainName, factoryName, serverName, SESSION_PROPERTY_TYPE);
00418 JavaMailSessionResource javaMailSessionResource = new JavaMailSessionResource(on.toString(), false, false, false, (JavaMailSession) factory);
00419
00420 ManagedBean oManaged = oRegistry.findManagedBean("JavaMailSessionResource");
00421 ModelMBean oMBean = oManaged.createMBean(javaMailSessionResource);
00422 mbeanServer.registerMBean(oMBean, on);
00423
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
00430 on = J2eeObjectName.JavaMailResource(domainName, factoryName, serverName, MIMEPART_PROPERTY_TYPE);
00431 JavaMailMimePartDSResource javaMailMimePartDSResource = new JavaMailMimePartDSResource(on.toString(), false, false, false, (JavaMailMimePartDS) factory);
00432
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
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
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
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
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
00530 try {
00531 if (mbeanServer != null) {
00532 ObjectName on = null;
00533 switch (typeOfFactory) {
00534 case JAVAX_MAIL_SESSION_FACTORY :
00535
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
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 }