00001
00027 package org.objectweb.jonas.resource;
00028
00029 import java.io.PrintWriter;
00030 import java.lang.reflect.Method;
00031 import java.text.SimpleDateFormat;
00032 import java.util.Date;
00033 import java.util.Iterator;
00034 import java.util.List;
00035 import java.util.Vector;
00036
00037 import javax.management.MBeanServer;
00038 import javax.management.ObjectName;
00039 import javax.management.modelmbean.ModelMBean;
00040 import javax.naming.BinaryRefAddr;
00041 import javax.naming.Context;
00042 import javax.naming.Reference;
00043 import javax.naming.StringRefAddr;
00044 import javax.resource.Referenceable;
00045 import javax.resource.spi.ConnectionManager;
00046 import javax.resource.spi.ManagedConnectionFactory;
00047 import javax.resource.spi.ResourceAdapter;
00048 import javax.resource.spi.ResourceAdapterAssociation;
00049
00050 import org.apache.commons.modeler.ManagedBean;
00051 import org.apache.commons.modeler.Registry;
00052 import org.objectweb.jonas.common.JNDIUtils;
00053 import org.objectweb.jonas.common.Log;
00054 import org.objectweb.jonas.jmx.J2eeObjectName;
00055 import org.objectweb.jonas.naming.CompNamingContext;
00056 import org.objectweb.jonas_ejb.deployment.api.ActivationConfigPropertyDesc;
00057 import org.objectweb.jonas_rar.deployment.api.ConfigPropertyDesc;
00058 import org.objectweb.jonas_rar.deployment.api.ConnectorDesc;
00059 import org.objectweb.jonas_rar.deployment.api.JdbcConnParamsDesc;
00060 import org.objectweb.jonas_rar.deployment.api.JonasConfigPropertyDesc;
00061 import org.objectweb.jonas_rar.deployment.api.JonasConnectorDesc;
00062 import org.objectweb.jonas_rar.deployment.api.PoolParamsDesc;
00063 import org.objectweb.transaction.jta.TransactionManager;
00064 import org.objectweb.util.monolog.api.BasicLevel;
00065 import org.objectweb.util.monolog.api.Logger;
00066
00074 public class ResourceUtility {
00075
00079 private static Logger logger = null;
00083 private static Logger setterLogger = null;
00087 private static Logger manageLogger = null;
00088
00092 private Registry oRegistry = null;
00093
00097 private MBeanServer mbeanServer = null;
00098
00099
00100
00104 public static final String JCD = "JCD";
00108 public static final String JAS = "JAS";
00112 public static final String JAO = "JAO";
00113
00118 public ResourceUtility() {
00119 }
00120
00130 public ResourceUtility(MBeanServer mbeanServer, Registry oRegistry,
00131 Logger log, Logger sLog, Logger mLog) {
00132 this.mbeanServer = mbeanServer;
00133 this.oRegistry = oRegistry;
00134 logger = log;
00135 setterLogger = sLog;
00136 manageLogger = mLog;
00137 }
00138
00146 public ConfigPropertyDesc [] buildConfigProperty(List raCfg,
00147 List jRaCfg1,
00148 List jRaCfg2) {
00149 Vector cfVec = null;
00150 ConfigPropertyDesc[] configs = null;
00151
00152
00153 if (raCfg != null) {
00154 for (Iterator i = raCfg.iterator(); i.hasNext();) {
00155 if (cfVec == null) {
00156 cfVec = new Vector();
00157 }
00158 cfVec.add(new ConfigPropertyDesc((ConfigPropertyDesc) i.next()));
00159 }
00160 } else {
00161 ActivationConfigPropertyDesc acp = null;
00162 ConfigPropertyDesc cp = null;
00163 if (jRaCfg1 != null) {
00164 for (Iterator i = jRaCfg1.iterator(); i.hasNext();) {
00165 if (cfVec == null) {
00166 cfVec = new Vector();
00167 }
00168 acp = (ActivationConfigPropertyDesc) i.next();
00169 cp = new ConfigPropertyDesc();
00170 cp.setConfigPropertyName(acp.getActivationConfigPropertyName());
00171 cp.setConfigPropertyValue(acp.getActivationConfigPropertyValue());
00172 cfVec.add(cp);
00173 }
00174 }
00175
00176 if (cfVec == null) {
00177 if (jRaCfg2 != null) {
00178 for (Iterator i = jRaCfg2.iterator(); i.hasNext();) {
00179 if (cfVec == null) {
00180 cfVec = new Vector();
00181 }
00182 acp = (ActivationConfigPropertyDesc) i.next();
00183 cp = new ConfigPropertyDesc();
00184 cp.setConfigPropertyName(acp.getActivationConfigPropertyName());
00185 cp.setConfigPropertyValue(acp.getActivationConfigPropertyValue());
00186 cfVec.add(cp);
00187 }
00188 configs = new ConfigPropertyDesc[cfVec.size()];
00189 cfVec.copyInto(configs);
00190 }
00191 } else {
00192 if (jRaCfg2 != null) {
00193 boolean found = false;
00194 for (Iterator i = jRaCfg2.iterator(); i.hasNext();) {
00195 found = false;
00196 acp = (ActivationConfigPropertyDesc) i.next();
00197 String name = acp.getActivationConfigPropertyName();
00198 String val = acp.getActivationConfigPropertyValue();
00199 if (val != null && val.length() > 0) {
00200 for (int j = 0; j < cfVec.size(); j++) {
00201 cp = (ConfigPropertyDesc) cfVec.get(j);
00202 if (name.equalsIgnoreCase(cp.getConfigPropertyName())) {
00203 cp.setConfigPropertyValue(val);
00204 cfVec.set(j, cp);
00205 found = true;
00206 break;
00207 }
00208 }
00209
00210
00211 if (!found) {
00212 cp = new ConfigPropertyDesc();
00213 cp.setConfigPropertyName(name);
00214 cp.setConfigPropertyValue(val);
00215 cfVec.add(cp);
00216 }
00217 }
00218 }
00219 }
00220 configs = new ConfigPropertyDesc[cfVec.size()];
00221 cfVec.copyInto(configs);
00222 }
00223
00224 return configs;
00225 }
00226
00227 if (cfVec == null) {
00228 return null;
00229 }
00230
00231 configs = new ConfigPropertyDesc[cfVec.size()];
00232 cfVec.copyInto(configs);
00233
00234 JonasConfigPropertyDesc jcpNext = null;
00235 if (jRaCfg2 != null) {
00236 for (Iterator i = jRaCfg2.iterator(); i.hasNext();) {
00237 jcpNext = (JonasConfigPropertyDesc) i.next();
00238 String name = jcpNext.getJonasConfigPropertyName();
00239 String val = jcpNext.getJonasConfigPropertyValue();
00240 if (val != null && val.length() > 0) {
00241 for (int j = 0; j < configs.length; j++) {
00242 if (name.equalsIgnoreCase(configs[j].getConfigPropertyName())) {
00243 configs[j].setConfigPropertyValue(val);
00244 break;
00245 }
00246 }
00247 }
00248 }
00249 }
00250
00251 if (jRaCfg1 != null) {
00252 for (Iterator i = jRaCfg1.iterator(); i.hasNext();) {
00253 jcpNext = (JonasConfigPropertyDesc) i.next();
00254 String name = jcpNext.getJonasConfigPropertyName();
00255 String val = jcpNext.getJonasConfigPropertyValue();
00256 if (val != null && val.length() > 0) {
00257 for (int j = 0; j < configs.length; j++) {
00258 if (name.equalsIgnoreCase(configs[j].getConfigPropertyName())) {
00259 configs[j].setConfigPropertyValue(val);
00260 break;
00261 }
00262 }
00263 }
00264 }
00265 }
00266 return configs;
00267 }
00268
00274 private boolean checkLogEnabled(String inp) {
00275 if (inp.equals("1") || inp.equalsIgnoreCase("on")
00276 || inp.equalsIgnoreCase("t") || inp.equalsIgnoreCase("true")
00277 || inp.equalsIgnoreCase("y") || inp.equalsIgnoreCase("yes")) {
00278 return true;
00279 }
00280 return false;
00281 }
00282
00292 public ConnectionManager createConnectionManager(String trans,
00293 TransactionManager tm,
00294 Logger logger,
00295 Logger poolLogger)
00296 throws Exception {
00297
00298 ConnectionManagerImpl cm = new ConnectionManagerImpl(trans);
00299
00300 Context c = new CompNamingContext("");
00301 c.rebind(ConnectionManagerImpl.TRANSACTION_MANAGER, tm);
00302 c.rebind(ConnectionManagerImpl.RESOURCE_MANAGER_EVENT_LISTENER, tm);
00303
00304
00305 c.rebind(ConnectionManagerImpl.LOGGER, logger);
00306 c.rebind(ConnectionManagerImpl.POOL_LOGGER, poolLogger);
00307
00308
00309 cm.init(c);
00310 return cm;
00311 }
00312
00331 public Object processMCF(ConnectorDesc conn, JonasConnectorDesc jonasConn, ConnectionManager cm,
00332 ClassLoader curLoader, String rarName, String mcfc,
00333 String jndiName, String logEnabled, String logTopic,
00334 ConfigPropertyDesc [] cfgRaJonas, ResourceAdapter resAdp,
00335 int idOff) throws Exception {
00336
00337 if (mcfc == null) {
00338 logger.log(BasicLevel.ERROR, "ResourceService.createRA:"
00339 + " managedconnectionfactoryclass property not found");
00340 throw new Exception("configuration file incorrect");
00341 }
00342
00343 if (jndiName == null || jndiName.length() == 0) {
00344 logger.log(BasicLevel.ERROR, "ResourceService.createRA: jndi-name not set in jonas-ra.xml");
00345 throw new Exception("configuration file incorrect");
00346 }
00347
00348
00349 Class mcfClass = curLoader.loadClass(mcfc);
00350 ManagedConnectionFactory mcf =
00351 (ManagedConnectionFactory) mcfClass.newInstance();
00352
00353 if (resAdp != null) {
00354 try {
00355 ((ResourceAdapterAssociation) mcf).setResourceAdapter(resAdp);
00356 } catch (ClassCastException ce) {
00357
00358 } catch (Exception ex) {
00359 logger.log(BasicLevel.ERROR, "ResourceService: Error setting ResourceAdapter class to ManagedConnectionFactory ("
00360 + mcfc + ") for " + jndiName);
00361 throw ex;
00362 }
00363 }
00364
00365 logger.log(BasicLevel.DEBUG, "jndiName=" + jndiName);
00366
00367
00368 if (logEnabled != null) {
00369 logger.log(BasicLevel.DEBUG, "log-enabled=" + logEnabled);
00370 if (checkLogEnabled(logEnabled)) {
00371 if (logTopic != null && logTopic.length() > 0) {
00372 logger.log(BasicLevel.DEBUG, "log-topic=" + logTopic);
00373 mcf.setLogWriter(Log.getLogWriter(logTopic));
00374 } else {
00375 logger.log(BasicLevel.DEBUG, "default log-topic=" + Log.JONAS_JCA_PREFIX);
00376 mcf.setLogWriter(Log.getLogWriter(Log.JONAS_JCA_PREFIX));
00377 }
00378 }
00379 }
00380
00381 processSetters(mcfClass, mcf, rarName, cfgRaJonas);
00382
00383 PrintWriter pw = mcf.getLogWriter();
00384 if (pw != null) {
00385
00386 SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss z");
00387 String date = sdf.format(new Date());
00388 pw.println("MCF: output starting at " + date);
00389 pw.flush();
00390 }
00391
00392
00393 mcf.hashCode();
00394
00395 return mcf;
00396 }
00397
00398
00415 public void registerMBean(Referenceable cf, String jndiName, String rarName,
00416 ConnectorDesc conn, JonasConnectorDesc jonasConn,
00417 String factType, int factOffset,
00418 JCAResource jcaResourceMBean, String jcaResourceName,
00419 String jDomain, String jServer, Context ictx) throws Exception {
00420
00421 try {
00422 Reference ref =
00423 new Reference(cf.getClass().getName(),
00424 ResourceObjectJNDIHandler.class.getName(),
00425 null);
00426
00427 ref.add(new StringRefAddr(ResourceServiceImpl.JNDI_NAME, jndiName));
00428 ref.add(new StringRefAddr(ResourceServiceImpl.RAR_OBJNAME, rarName));
00429 ref.add(new StringRefAddr(ResourceServiceImpl.FACTORY_TYPE, factType));
00430 ref.add(new StringRefAddr(ResourceServiceImpl.FACTORY_OFFSET, "" + factOffset));
00431
00432 byte[] bytes = JNDIUtils.getBytesFromObject(conn);
00433 if (bytes != null) {
00434 ref.add(new BinaryRefAddr(ResourceServiceImpl.RA_XML, bytes));
00435 }
00436
00437 bytes = JNDIUtils.getBytesFromObject(jonasConn);
00438 if (bytes != null) {
00439 ref.add(new BinaryRefAddr(ResourceServiceImpl.JONAS_RA_XML, bytes));
00440 }
00441
00442 cf.setReference(ref);
00443 ictx.rebind(jndiName, cf);
00444
00445 } catch (Exception e) {
00446 logger.log(BasicLevel.ERROR, "ResourceService: Cannot register ResourceAdapter in naming with the name " + jndiName);
00447 logger.log(BasicLevel.ERROR, "ResourceService: Exception caught : " + e);
00448 }
00449
00450
00451
00452
00453 if (mbeanServer != null) {
00454
00455
00456
00457
00458
00459 String jcaConnectionFactoryName = jndiName;
00460 ObjectName onJCAConnectionFactory =
00461 J2eeObjectName.getJCAConnectionFactory(jDomain,
00462 jcaResourceName,
00463 jServer,
00464 jcaConnectionFactoryName);
00465 JCAConnectionFactory jcaConnectionFactoryMBean = new JCAConnectionFactory(onJCAConnectionFactory.toString());
00466 ManagedBean oManaged = oRegistry.findManagedBean("JCAConnectionFactory");
00467 ModelMBean oMBean = oManaged.createMBean(jcaConnectionFactoryMBean);
00468 if (manageLogger.isLoggable(BasicLevel.DEBUG)) {
00469 manageLogger.log(BasicLevel.DEBUG, "JCAConnectionFactory created");
00470 }
00471 mbeanServer.registerMBean(oMBean, onJCAConnectionFactory);
00472
00473
00474
00475 jcaResourceMBean.setConnectionFactory(onJCAConnectionFactory.toString());
00476
00477
00478
00479 String jcaManagedConnectionFactoryName = getJcaMcfName(jcaConnectionFactoryName);
00480 ObjectName onJCAManagedConnectionFactory =
00481 J2eeObjectName.getJCAManagedConnectionFactory(jDomain,
00482 jServer,
00483 jcaManagedConnectionFactoryName);
00484 JCAManagedConnectionFactory jcaManagedConnectionFactoryMBean =
00485 new JCAManagedConnectionFactory(onJCAManagedConnectionFactory.toString());
00486 oManaged = oRegistry.findManagedBean("JCAManagedConnectionFactory");
00487 oMBean = oManaged.createMBean(jcaManagedConnectionFactoryMBean);
00488 if (manageLogger.isLoggable(BasicLevel.DEBUG)) {
00489 manageLogger.log(BasicLevel.DEBUG, "JCAManagedConnectionFactory created");
00490 }
00491 mbeanServer.registerMBean(oMBean, onJCAManagedConnectionFactory);
00492
00493
00494 jcaConnectionFactoryMBean.setManagedConnectionFactory(onJCAManagedConnectionFactory.toString());
00495 if (manageLogger.isLoggable(BasicLevel.DEBUG)) {
00496 manageLogger.log(BasicLevel.DEBUG, "JCAConnectionFactory updated");
00497 }
00498 }
00499 }
00500
00501
00510 public void processSetters(Class clsClass, Object clsObj, String rarFileName,
00511 ConfigPropertyDesc [] cProp) throws Exception {
00512
00513 int curParam = 0;
00514 while (cProp != null && curParam < cProp.length) {
00515 String fieldName = cProp[curParam].getConfigPropertyName();
00516 String methodName = "set" + fieldName.substring(0, 1).toUpperCase()
00517 + fieldName.substring(1);
00518 String fieldType = cProp[curParam].getConfigPropertyType();
00519 Method[] m = clsClass.getMethods();
00520
00521 int i = 0;
00522 while (i < m.length
00523 && (!m[i].getName().equals(methodName)
00524 || m[i].getParameterTypes().length != 1
00525 || (fieldType != null
00526 && !(m[i].getParameterTypes())[0].getName().equals(fieldType)))
00527 ) {
00528 i++;
00529 }
00530 if (i < m.length) {
00531 Class [] paramtype = m[i].getParameterTypes();
00532 Object[] param = new Object[1];
00533
00534 String curValue = cProp[curParam].getConfigPropertyValue();
00535
00536 setterLogger.log(BasicLevel.DEBUG, "Processing Field Name: " + fieldName
00537 + " Type: " + fieldType + " Value: " + curValue);
00538
00539 if (paramtype[0].equals(java.lang.Integer.TYPE)
00540 || paramtype[0].equals(java.lang.Integer.class)) {
00541 param[0] = new Integer(curValue);
00542
00543 } else if (paramtype[0].equals(java.lang.Boolean.TYPE)
00544 || paramtype[0].equals(java.lang.Boolean.class)) {
00545 param[0] = new Boolean(curValue);
00546
00547 } else if (paramtype[0].equals(java.lang.Double.TYPE)
00548 || paramtype[0].equals(java.lang.Double.class)) {
00549 param[0] = new Double(curValue);
00550
00551 } else if (paramtype[0].equals(java.lang.Byte.TYPE)
00552 || paramtype[0].equals(java.lang.Byte.class)) {
00553 param[0] = new Byte(curValue);
00554
00555 } else if (paramtype[0].equals(java.lang.Short.TYPE)
00556 || paramtype[0].equals(java.lang.Short.class)) {
00557 param[0] = new Short(curValue);
00558
00559 } else if (paramtype[0].equals(java.lang.Long.TYPE)
00560 || paramtype[0].equals(java.lang.Long.class)) {
00561 param[0] = new Long(curValue);
00562
00563 } else if (paramtype[0].equals(java.lang.Float.TYPE)
00564 || paramtype[0].equals(java.lang.Float.class)) {
00565 param[0] = new Float(curValue);
00566
00567 } else if (paramtype[0].equals(java.lang.Character.TYPE)
00568 || paramtype[0].equals(java.lang.Character.class)) {
00569 param[0] = new Character(curValue.charAt(0));
00570
00571 } else if (paramtype[0].equals(java.lang.String.class)) {
00572 param[0] = curValue;
00573 setterLogger.log(BasicLevel.DEBUG, "Calling String method with " + curValue);
00574
00575 } else {
00576 logger.log(BasicLevel.ERROR, "Type unsupported for setter method:"
00577 + methodName);
00578 throw new Exception("incorrect type for setter method ");
00579 }
00580
00581
00582 try {
00583 m[i].invoke(clsObj, param);
00584 } catch (Exception e) {
00585 logger.log(BasicLevel.DEBUG, "method "
00586 + methodName
00587 + " not found for " + rarFileName + "check its configuration ");
00588 }
00589 curParam++;
00590 } else {
00591 logger.log(BasicLevel.ERROR, "Method not found: " + methodName);
00592 throw new Exception("incorrect method name: " + methodName);
00593 }
00594 }
00595 }
00596
00605 public ConnectionManagerPoolParams configurePoolParams (PoolParamsDesc pParams,
00606 JdbcConnParamsDesc jConnParams,
00607 ConnectionManagerPoolParams pool)
00608 throws Exception {
00609
00610 ConnectionManagerPoolParams cmpp = null;
00611 if (pool == null) {
00612 cmpp = new ConnectionManagerPoolParams();
00613 } else {
00614 cmpp = new ConnectionManagerPoolParams(pool);
00615 }
00616 String tmpPool = null;
00617 try {
00618 if (pParams != null) {
00619 if (pParams.getPoolInit() != null) {
00620 tmpPool = pParams.getPoolInit();
00621 if (tmpPool != null && tmpPool.length() > 0) {
00622 cmpp.setPoolInit(Integer.parseInt(tmpPool));
00623 }
00624 }
00625 if (pParams.getPoolMin() != null) {
00626 tmpPool = pParams.getPoolMin();
00627 if (tmpPool != null && tmpPool.length() > 0) {
00628 cmpp.setPoolMin(Integer.parseInt(tmpPool));
00629 }
00630 }
00631 if (pParams.getPoolMax() != null) {
00632 tmpPool = pParams.getPoolMax();
00633 if (tmpPool != null && tmpPool.length() > 0) {
00634 cmpp.setPoolMax(Integer.parseInt(tmpPool));
00635 }
00636 }
00637 if (pParams.getPoolMaxAge() != null) {
00638 tmpPool = pParams.getPoolMaxAge();
00639 if (tmpPool != null && tmpPool.length() > 0) {
00640 cmpp.setPoolMaxAge(Long.parseLong(tmpPool));
00641 }
00642 }
00643 if (pParams.getPoolMaxAgeMinutes() != null) {
00644 tmpPool = pParams.getPoolMaxAgeMinutes();
00645 if (tmpPool != null && tmpPool.length() > 0) {
00646 cmpp.setPoolMaxAgeMinutes(Integer.parseInt(tmpPool));
00647 }
00648 }
00649 if (pParams.getPoolMaxOpentime() != null) {
00650 tmpPool = pParams.getPoolMaxOpentime();
00651 if (tmpPool != null && tmpPool.length() > 0) {
00652 cmpp.setPoolMaxOpentime(Integer.parseInt(tmpPool));
00653 }
00654 }
00655 if (pParams.getPoolMaxWaiters() != null) {
00656 tmpPool = pParams.getPoolMaxWaiters();
00657 if (tmpPool != null && tmpPool.length() > 0) {
00658 cmpp.setPoolMaxWaiters(Integer.parseInt(tmpPool));
00659 }
00660 }
00661 if (pParams.getPoolMaxWaittime() != null) {
00662 tmpPool = pParams.getPoolMaxWaittime();
00663 if (tmpPool != null && tmpPool.length() > 0) {
00664 cmpp.setPoolMaxWaittime(Integer.parseInt(tmpPool));
00665 }
00666 }
00667 if (pParams.getPoolSamplingPeriod() != null) {
00668 tmpPool = pParams.getPoolSamplingPeriod();
00669 if (tmpPool != null && tmpPool.length() > 0) {
00670 cmpp.setPoolSamplingPeriod(Integer.parseInt(tmpPool));
00671 }
00672 }
00673 if (pParams.getPstmtMax() != null) {
00674 tmpPool = pParams.getPstmtMax();
00675 if (tmpPool != null && tmpPool.length() > 0) {
00676 cmpp.setPstmtMax(Integer.parseInt(tmpPool));
00677 }
00678 }
00679 }
00680 if (jConnParams != null) {
00681 if (jConnParams.getJdbcCheckLevel() != null) {
00682 tmpPool = jConnParams.getJdbcCheckLevel();
00683 if (tmpPool != null && tmpPool.length() > 0) {
00684 cmpp.setJdbcConnLevel(Integer.parseInt(tmpPool));
00685 }
00686 }
00687 if (jConnParams.getJdbcTestStatement() != null) {
00688 cmpp.setJdbcConnTestStmt(jConnParams.getJdbcTestStatement());
00689 }
00690 }
00691 } catch (Exception ex) {
00692 ex.printStackTrace();
00693 logger.log(BasicLevel.ERROR, "Invalid Pool parameter from jonas-ra.xml: Ensure that numeric values are used. " + tmpPool);
00694 throw new Exception("incorrect pool parameter ");
00695 }
00696 return cmpp;
00697 }
00698
00708 public Object getJonasXML(JonasConnectorDesc jonasConn,
00709 String id, int idOffset, String oType) {
00710 Object obj = null;
00711 if (oType == JCD) {
00712 obj = jonasConn.getJonasConnectionDefinitionList().get(idOffset);
00713 } else if (oType == JAS) {
00714 obj = jonasConn.getJonasActivationspecList().get(idOffset);
00715 } else if (oType == JAO) {
00716 obj = jonasConn.getJonasAdminobjectList().get(idOffset);
00717 }
00718 return obj;
00719 }
00720
00726 public String getJcaMcfName(String jndiName) {
00727 return jndiName;
00728 }
00729 }