00001
00025 package org.objectweb.jonas.jdbc;
00026
00027 import java.lang.reflect.Method;
00028 import java.util.Enumeration;
00029 import java.util.Iterator;
00030 import java.util.Set;
00031 import java.util.Vector;
00032
00033 import javax.resource.ResourceException;
00034 import javax.resource.spi.ConnectionRequestInfo;
00035 import javax.resource.spi.ManagedConnectionFactory;
00036 import javax.resource.spi.SecurityException;
00037 import javax.resource.spi.security.PasswordCredential;
00038 import javax.security.auth.Subject;
00039
00040 import org.objectweb.util.monolog.api.BasicLevel;
00041 import org.objectweb.util.monolog.api.Logger;
00042
00047 public class Utility {
00048
00049 static synchronized Object getDataSource(ManagedConnectionFactoryImpl mcf, PasswordCredential pc, Logger trace)
00050 throws ResourceException {
00051
00052 MCFData prop = mcf.mcfData;
00053
00054 if (prop.getMCFData(MCFData.DSCLASS) == null) {
00055 ResourceException re = new ResourceException("A DataSource (dsClass) value must be specified");
00056 trace.log(BasicLevel.INFO, re.getMessage());
00057 }
00058 String clsName = prop.getMCFData(MCFData.DSCLASS);
00059 Class dsClass = null;
00060 Object dsObj = null;
00061 try {
00062 dsClass = Class.forName(clsName, true, Thread.currentThread().getContextClassLoader());
00063 dsObj = dsClass.newInstance();
00064 trace.log(BasicLevel.DEBUG, "dsClass(" + clsName + ") is " + dsObj);
00065 } catch (ClassNotFoundException cnfe) {
00066 throw new ResourceException("Class Name not found:" + clsName);
00067 } catch (Exception ex) {
00068 throw new ResourceException("Error in class: " + clsName + " " + ex.getMessage());
00069 }
00070
00071 Object[] param = new Object[1];
00072 String methodName = null;
00073 String paramVal = null;
00074 Method meth = null;
00075 for (Enumeration e = prop.getProperties(); e.hasMoreElements();) {
00076 int offset = Integer.parseInt((String) e.nextElement());
00077 methodName = MCFData.dsMethodNames[offset];
00078 if (!(methodName.equals("setDSClass") || methodName.equals("setDbSpecificMethods") || offset > MCFData.JONASOFFSET)) {
00079 try {
00080
00081 paramVal = prop.getProperty("" + offset);
00082 trace.log(BasicLevel.DEBUG, "calling method " + methodName + " with String " + paramVal);
00083 meth = dsClass.getMethod(methodName, new Class[] {String.class});
00084 param[0] = paramVal;
00085 meth.invoke(dsObj, param);
00086 } catch (NoSuchMethodException ns) {
00087 try {
00088
00089 trace.log(BasicLevel.DEBUG, "calling method " + methodName + " with int " + paramVal);
00090 meth = dsClass.getMethod(methodName, new Class[] {int.class});
00091 param[0] = new Integer(paramVal);
00092 meth.invoke(dsObj, param);
00093 } catch (NoSuchMethodException nsme) {
00094
00095
00096 ;
00097 } catch (NumberFormatException nfm) {
00098
00099 ;
00100 } catch (Exception ex0) {
00101 ex0.printStackTrace();
00102 throw new ResourceException("Error on method: " + methodName + " " + ex0.getMessage());
00103 }
00104 } catch (IllegalArgumentException iae) {
00105 ;
00106 } catch (Exception ex) {
00107 ex.printStackTrace();
00108 throw new ResourceException("Error on method: " + methodName + " " + ex.getMessage());
00109 }
00110 }
00111 if (methodName.equals("setDbSpecificMethods")) {
00112 Vector meths = new Vector();
00113 Vector methParams = new Vector();
00114 Vector methTypes = new Vector();
00115 try {
00116 Utility.parseValues(prop.getProperty("" + offset), meths, methParams, methTypes, trace);
00117 } catch (Exception ex1) {
00118 throw new ResourceException("Error parsing dbSpecificMethods: " + ex1.getMessage());
00119 }
00120 if (meths != null && meths.size() > 0) {
00121 for (int i = 0; i < meths.size(); i++) {
00122 try {
00123
00124 methodName = (String) meths.elementAt(i);
00125 Class toPass = null;
00126 String curMethType = (String) methTypes.elementAt(i);
00127 if (curMethType.equalsIgnoreCase("String")) {
00128 toPass = String.class;
00129 param[0] = (String) methParams.elementAt(i);
00130 } else if (curMethType.equalsIgnoreCase("Integer")) {
00131 toPass = Integer.class;
00132 param[0] = Integer.valueOf((String) methParams.elementAt(i));
00133 } else if (curMethType.equalsIgnoreCase("int")) {
00134 toPass = int.class;
00135 param[0] = Integer.valueOf((String) methParams.elementAt(i));
00136 } else if (curMethType.equals("Float")) {
00137 toPass = Float.class;
00138 param[0] = Float.valueOf((String) methParams.elementAt(i));
00139 } else if (curMethType.equals("float")) {
00140 toPass = float.class;
00141 param[0] = Float.valueOf((String) methParams.elementAt(i));
00142 } else if (curMethType.equals("Boolean")) {
00143 toPass = Boolean.class;
00144 param[0] = Boolean.valueOf((String) methParams.elementAt(i));
00145 } else if (curMethType.equals("boolean")) {
00146 toPass = boolean.class;
00147 param[0] = Boolean.valueOf((String) methParams.elementAt(i));
00148 } else if (curMethType.equalsIgnoreCase("Character")) {
00149 toPass = Character.class;
00150 param[0] = new Character(((String) methParams.elementAt(i)).charAt(0));
00151 } else if (curMethType.equalsIgnoreCase("char")) {
00152 toPass = char.class;
00153 param[0] = new Character(((String) methParams.elementAt(i)).charAt(0));
00154 } else if (curMethType.equals("Double")) {
00155 toPass = Double.class;
00156 param[0] = Double.valueOf((String) methParams.elementAt(i));
00157 } else if (curMethType.equals("double")) {
00158 toPass = double.class;
00159 param[0] = Double.valueOf((String) methParams.elementAt(i));
00160 } else if (curMethType.equals("Byte")) {
00161 toPass = Byte.class;
00162 param[0] = Byte.valueOf((String) methParams.elementAt(i));
00163 } else if (curMethType.equals("byte")) {
00164 toPass = byte.class;
00165 param[0] = Byte.valueOf((String) methParams.elementAt(i));
00166 } else if (curMethType.equals("Short")) {
00167 toPass = Short.class;
00168 param[0] = Short.valueOf((String) methParams.elementAt(i));
00169 } else if (curMethType.equals("short")) {
00170 toPass = short.class;
00171 param[0] = Short.valueOf((String) methParams.elementAt(i));
00172 } else if (curMethType.equals("Long")) {
00173 toPass = Long.class;
00174 param[0] = Long.valueOf((String) methParams.elementAt(i));
00175 } else if (curMethType.equals("long")) {
00176 toPass = long.class;
00177 param[0] = Long.valueOf((String) methParams.elementAt(i));
00178 }
00179 trace.log(BasicLevel.DEBUG, "calling method " + methodName + " with " + param[0]);
00180 meth = dsClass.getMethod(methodName, new Class[] {toPass});
00181 meth.invoke(dsObj, param);
00182 } catch (NoSuchMethodException ns) {
00183 throw new ResourceException("No such method: " + methodName + " " + ns.getMessage());
00184 } catch (Exception ex) {
00185 ex.printStackTrace();
00186 throw new ResourceException("Error on method: " + methodName + " " + ex.getMessage());
00187 }
00188 }
00189 }
00190 }
00191 }
00192 if (pc != null) {
00193 try {
00194 param[0] = pc.getUserName();
00195 meth = dsClass.getMethod("setUserName", new Class[] {Class.forName("String")});
00196 meth.invoke(dsObj, param);
00197
00198 param[0] = new String(pc.getPassword());
00199 meth = dsClass.getMethod("setPassword", new Class[] {Class.forName("String")});
00200 meth.invoke(dsObj, param);
00201 } catch (Exception ex) {
00202 throw new ResourceException("Error on method: " + methodName + " " + ex.getMessage());
00203 }
00204 }
00205 if (trace.isLoggable(BasicLevel.DEBUG)) {
00206 try {
00207 meth = dsClass.getMethod("getURL", (Class[]) null);
00208 trace.log(BasicLevel.DEBUG, "URL is " + meth.invoke(dsObj, (Object[]) null));
00209 } catch (Exception e) {
00210 }
00211 }
00212 return dsObj;
00213
00214 }
00215
00216 private static void parseValues(String val, Vector vMeth, Vector vValues, Vector vTypes, Logger trace)
00217 throws Exception {
00218
00219 trace.log(BasicLevel.DEBUG, "");
00220 char delim = ':';
00221 boolean done = false;
00222 String methName = null;
00223 int offset = 0;
00224 boolean parsed = false;
00225 String parseVal = val.trim();
00226 String typeVal = "";
00227 String valVal = "";
00228
00229 if (parseVal.length() == 0) {
00230 return;
00231 }
00232 if (parseVal.startsWith(":")) {
00233 delim = parseVal.charAt(1);
00234 parseVal = parseVal.substring(2);
00235 }
00236 while (!parsed) {
00237 offset = parseVal.indexOf('=');
00238 if (offset < 0) {
00239 throw new Exception("Invalid value specified for dbSpecificMethods");
00240 }
00241 methName = parseVal.substring(0, offset);
00242 vMeth.add(methName);
00243 parseVal = parseVal.substring(offset + 1);
00244 if (parseVal.charAt(0) == delim) {
00245 valVal = "";
00246 } else {
00247 offset = parseVal.indexOf(delim);
00248 if (offset < 0) {
00249 valVal = parseVal;
00250 offset = valVal.length() - 1;
00251 } else {
00252 valVal = parseVal.substring(0, offset);
00253 }
00254 }
00255 vValues.add(valVal);
00256 if (offset < 0) {
00257 parsed = true;
00258 } else {
00259 parseVal = parseVal.substring(offset + 1);
00260 if (parseVal.length() == 0) {
00261 parsed = true;
00262 }
00263 }
00264 if (parseVal.startsWith("" + delim)) {
00265 parseVal = parseVal.substring(1);
00266 offset = parseVal.indexOf(delim);
00267 if (offset < 0) {
00268 typeVal = parseVal;
00269 } else {
00270 typeVal = parseVal.substring(0, offset);
00271 }
00272 vTypes.add(typeVal);
00273 if (offset < 0) {
00274 parsed = true;
00275 } else {
00276 parseVal = parseVal.substring(offset + 1);
00277 if (parseVal.length() == 0) {
00278 parsed = true;
00279 }
00280 }
00281 } else {
00282 vTypes.add("String");
00283 }
00284 trace.log(BasicLevel.DEBUG, "Parsed: method(" + methName + ") value(" + valVal + ") type(" + typeVal + ")");
00285 }
00286 }
00287
00295 static synchronized PasswordCredential getPasswordCredential(ManagedConnectionFactory mcf, Subject subject,
00296 ConnectionRequestInfo info, java.io.PrintWriter out) throws ResourceException {
00297
00298 if (subject == null) {
00299 if (info == null) {
00300 return null;
00301 }
00302 ConnectionRequestInfoImpl crii = (ConnectionRequestInfoImpl) info;
00303 PasswordCredential pc = new PasswordCredential(crii.user, crii.password.toCharArray());
00304 pc.setManagedConnectionFactory(mcf);
00305 return pc;
00306 }
00307 Set cred = subject.getPrivateCredentials(PasswordCredential.class);
00308 PasswordCredential pc = null;
00309 for (Iterator iter = cred.iterator(); iter.hasNext();) {
00310 PasswordCredential tmpPc = (PasswordCredential) iter.next();
00311 if (tmpPc.getManagedConnectionFactory().equals(mcf)) {
00312 pc = tmpPc;
00313 break;
00314 }
00315 }
00316 if (pc == null) {
00317 SecurityException se = new SecurityException("No PasswordCredential found");
00318 out.println("" + se);
00319 throw se;
00320 }
00321 return pc;
00322 }
00323
00324 }