0001: package org.enhydra.realm;
0002:
0003: import java.io.FileInputStream;
0004: import java.io.InputStream;
0005: import java.lang.reflect.Constructor;
0006: import java.lang.reflect.Method;
0007: import java.security.Principal;
0008: import java.sql.Connection;
0009: import java.util.ArrayList;
0010: import java.util.HashMap;
0011: import java.util.Hashtable;
0012: import java.util.Iterator;
0013: import java.util.StringTokenizer;
0014:
0015: import javax.management.MalformedObjectNameException;
0016: import javax.management.ObjectName;
0017: import javax.naming.Context;
0018: import javax.naming.NameAlreadyBoundException;
0019: import javax.naming.NamingException;
0020: import javax.naming.Reference;
0021: import javax.naming.StringRefAddr;
0022: import javax.sql.DataSource;
0023:
0024: import org.apache.catalina.Engine;
0025: import org.apache.catalina.Host;
0026: import org.apache.catalina.LifecycleException;
0027: import org.apache.catalina.ServerFactory;
0028: import org.apache.catalina.Service;
0029: import org.apache.catalina.core.ContainerBase;
0030: import org.apache.catalina.core.StandardServer;
0031: import org.apache.catalina.deploy.ContextEjb;
0032: import org.apache.catalina.deploy.ContextEnvironment;
0033: import org.apache.catalina.deploy.ContextResource;
0034: import org.apache.catalina.deploy.ContextResourceEnvRef;
0035: import org.apache.catalina.deploy.ContextResourceLink;
0036: import org.apache.catalina.deploy.ContextTransaction;
0037: import org.apache.catalina.deploy.NamingResources;
0038: import org.apache.catalina.realm.GenericPrincipal;
0039: import org.apache.catalina.realm.RealmBase;
0040: import org.apache.catalina.util.StringManager;
0041: import org.apache.tomcat.util.modeler.Registry;
0042: import org.apache.naming.ContextAccessController;
0043: import org.apache.naming.ContextBindings;
0044: import org.apache.naming.EjbRef;
0045: import org.apache.naming.NamingContext;
0046: import org.apache.naming.ResourceEnvRef;
0047: import org.apache.naming.ResourceLinkRef;
0048: import org.apache.naming.ResourceRef;
0049: import org.apache.naming.TransactionRef;
0050: import org.enhydra.dods.DODS;
0051:
0052: import com.lutris.appserver.server.Application;
0053: import com.lutris.appserver.server.Enhydra;
0054: import com.lutris.appserver.server.StandardApplication;
0055: import com.lutris.appserver.server.sql.DBTransaction;
0056: import com.lutris.dods.builder.generator.dataobject.GenericDO;
0057: import com.lutris.logging.StandardLogger;
0058: import com.lutris.util.Config;
0059: import com.lutris.util.ConfigFile;
0060:
0061: /**
0062: * @author Tanja Jovanovic
0063: * @version 1.0
0064: */
0065: public class DODSRealm extends RealmBase {
0066:
0067: // ----------------------------------------------------- Instance Variables
0068:
0069: /**
0070: * Descriptive information about this Realm implementation.
0071: */
0072: protected static final String info = "org.enhydra.realm.DODSRealm/1.0";
0073:
0074: /**
0075: * Descriptive information about this Realm implementation.
0076: */
0077: protected static final String name = "DODSRealm";
0078:
0079: /**
0080: * The string manager for this package.
0081: */
0082: protected static final StringManager sm = StringManager
0083: .getManager(DODSRealmConstants.Package);
0084:
0085: /**
0086: * The table that holds data about users and their credentials.
0087: */
0088: protected String userTableName = null;
0089:
0090: /**
0091: * The table that holds data about roles.
0092: */
0093: protected String roleTableName = null;
0094:
0095: /**
0096: * The table that holds data about relationships between users and roles.
0097: */
0098: protected String userRoleTableName = null;
0099:
0100: /**
0101: * The column in the user table that holds user's name.
0102: */
0103: protected String userColUserTableName = null;
0104:
0105: /**
0106: * The column in the user table that holds user's credintials.
0107: */
0108: protected String credColUserTableName = null;
0109:
0110: /**
0111: * The column in the role table that holds roles.
0112: */
0113: protected String roleColRoleTableName = null;
0114:
0115: /**
0116: * The column in the user-role table that holds users.
0117: */
0118: protected String userColUserRoleTableName = null;
0119:
0120: /**
0121: * The column in the user-role table that holds roles.
0122: */
0123: protected String roleColUserRoleTableName = null;
0124:
0125: /**
0126: * Path to configuration file for DODS.
0127: */
0128: protected String configurationFilePath = null;
0129:
0130: /**
0131: * Context local datasource.
0132: */
0133: protected boolean localDataSource = false;
0134:
0135: /**
0136: * Associated JNDI context.
0137: */
0138: protected NamingContext namingContext = null;
0139:
0140: /**
0141: * Associated naming resources.
0142: */
0143: protected NamingResources namingResources = null;
0144:
0145: /**
0146: * Comp context.
0147: */
0148: protected javax.naming.Context compCtx = null;
0149:
0150: /**
0151: * Env context.
0152: */
0153: protected javax.naming.Context envCtx = null;
0154:
0155: /**
0156: * Objectnames hashtable.
0157: */
0158: protected HashMap objectNames = new HashMap();
0159:
0160: // Enhydra application
0161: private Application app;
0162:
0163: // ------------------------------------------------------------- Properties
0164:
0165: /**
0166: * Returns the name of the table that contains users and credentials.
0167: * @return name of the table that contains users and credentials
0168: */
0169: public String getUserTableName() {
0170: return userTableName;
0171: }
0172:
0173: /**
0174: * Sets the name of the table that contains users and credentials.
0175: *
0176: * @param userTableName name of the table that contains users and credentials
0177: */
0178: public void setUserTableName(String userTableName) {
0179: this .userTableName = userTableName;
0180: }
0181:
0182: /**
0183: * Returns the name of the table that contains roles.
0184: * @return name of the table that contains roles.
0185: */
0186: public String getRoleTableName() {
0187: return roleTableName;
0188: }
0189:
0190: /**
0191: * Sets the name of the table that contains roles.
0192: *
0193: * @param roleTableName name of the table that contains roles.
0194: */
0195: public void setRoleTableName(String roleTableName) {
0196: this .roleTableName = roleTableName;
0197: }
0198:
0199: /**
0200: * Returns the name of the table that contains relationships
0201: * between users and roles.
0202: * @return name of the table that contains relationships
0203: * between users and roles.
0204: */
0205: public String getUserRoleTableName() {
0206: return userRoleTableName;
0207: }
0208:
0209: /**
0210: * Sets the name of the table that contains relationships
0211: * between users and roles.
0212: *
0213: * @param userRoleTableName name of the table that contains relationships
0214: * between users and roles.
0215: */
0216: public void setUserRoleTableName(String userRoleTableName) {
0217: this .userRoleTableName = userRoleTableName;
0218: }
0219:
0220: /**
0221: * Returns the name of the user colum in user table.
0222: * @return name of the user colum in user table.
0223: */
0224: public String getUserColUserTableName() {
0225: return userColUserTableName;
0226: }
0227:
0228: /**
0229: * Sets the name of the user colum in user table.
0230: *
0231: * @param userColUserTableName name of the user colum in user table.
0232: */
0233: public void setUserColUserTableName(String userColUserTableName) {
0234: this .userColUserTableName = userColUserTableName;
0235: }
0236:
0237: /**
0238: * Returns the name of the credential colum in user table.
0239: * @return name of the credential colum in user table.
0240: */
0241: public String getCredColUserTableName() {
0242: return credColUserTableName;
0243: }
0244:
0245: /**
0246: * Sets the name of the credential colum in user table.
0247: *
0248: * @param credColUserTableName name of the credential colum in user table.
0249: */
0250: public void setCredColUserTableName(String credColUserTableName) {
0251: this .credColUserTableName = credColUserTableName;
0252: }
0253:
0254: /**
0255: * Returns the name of the role colum in role table.
0256: * @return name of the role colum in role table.
0257: */
0258: public String getRoleColRoleTableName() {
0259: return roleColRoleTableName;
0260: }
0261:
0262: /**
0263: * Sets the name of the role colum in role table.
0264: *
0265: * @param roleColRoleTableName name of the role colum in role table.
0266: */
0267: public void setRoleColRoleTableName(String roleColRoleTableName) {
0268: this .roleColRoleTableName = roleColRoleTableName;
0269: }
0270:
0271: /**
0272: * Returns the name of the user colum in user-role table.
0273: * @return name of the user colum in user-role table.
0274: */
0275: public String getUserColUserRoleTableName() {
0276: return userColUserRoleTableName;
0277: }
0278:
0279: /**
0280: * Sets the name of the user colum in user-role table.
0281: *
0282: * @param userColUserRoleTableName name of the user colum in user-role table.
0283: */
0284: public void setUserColUserRoleTableName(
0285: String userColUserRoleTableName) {
0286: this .userColUserRoleTableName = userColUserRoleTableName;
0287: }
0288:
0289: /**
0290: * Returns the name of the role colum in user-role table.
0291: * @return name of the role colum in user-role table.
0292: */
0293: public String getRoleColUserRoleTableName() {
0294: return roleColUserRoleTableName;
0295: }
0296:
0297: /**
0298: * Sets the name of the role colum in user-role table.
0299: *
0300: * @param roleColUserRoleTableName name of the role colum in user-role table.
0301: */
0302: public void setRoleColUserRoleTableName(
0303: String roleColUserRoleTableName) {
0304: this .roleColUserRoleTableName = roleColUserRoleTableName;
0305: }
0306:
0307: /**
0308: * Returns path to configuration file for DODS.
0309: * @returnpath to configuration file for DODS.
0310: */
0311: public String getConfigurationFilePath() {
0312: return configurationFilePath;
0313: }
0314:
0315: /**
0316: * Sets path to configuration file for DODS.
0317: *
0318: * @param configurationFilePath path to configuration file for DODS.
0319: */
0320: public void setConfigurationFilePath(String configurationFilePath) {
0321: this .configurationFilePath = configurationFilePath;
0322: }
0323:
0324: /**
0325: * Return if the datasource will be looked up in the webapp JNDI Context.
0326: */
0327: public boolean getLocalDataSource() {
0328: return localDataSource;
0329: }
0330:
0331: /**
0332: * Set to true to cause the datasource to be looked up in the webapp JNDI
0333: * Context.
0334: *
0335: * @param localDataSource the new flag value
0336: */
0337: public void setLocalDataSource(boolean localDataSource) {
0338: this .localDataSource = localDataSource;
0339: }
0340:
0341: /**
0342: * Return the associated naming context.
0343: */
0344: public NamingContext getNamingContext() {
0345:
0346: return (this .namingContext);
0347:
0348: }
0349:
0350: // --------------------------------------------------------- Public Methods
0351:
0352: /**
0353: * Return the Principal associated with the specified username and
0354: * credentials, if there is one; otherwise return <code>null</code>.
0355: *
0356: * If there are any errors with the JDBC connection, executing
0357: * the query or anything we return null (don't authenticate). This
0358: * event is also logged, and the connection will be closed so that
0359: * a subsequent request will automatically re-open it.
0360: *
0361: *
0362: * @param username Username of the Principal to look up
0363: * @param credentials Password or other credentials to use in
0364: * authenticating this username
0365: */
0366: public synchronized Principal authenticate(String username,
0367: String credentials) {
0368:
0369: // No user - can't possibly authenticate
0370: if (username == null) {
0371: return (null);
0372: }
0373:
0374: // Look up the user's credentials
0375: String dbCredentials = getPassword(username);
0376:
0377: // Validate the user's credentials
0378: boolean validated = false;
0379: if (hasMessageDigest()) {
0380: // Hex hashes should be compared case-insensitive
0381: validated = (digest(credentials)
0382: .equalsIgnoreCase(dbCredentials));
0383: } else {
0384: validated = (digest(credentials).equals(dbCredentials));
0385: }
0386:
0387: if (validated) {
0388: if (containerLog.isTraceEnabled())
0389: containerLog.trace(sm.getString(
0390: "dodsRealm.authenticateSuccess", username));
0391: } else {
0392: if (containerLog.isTraceEnabled())
0393: containerLog.trace(sm.getString(
0394: "dodsRealm.authenticateFailure", username));
0395: return (null);
0396: }
0397:
0398: ArrayList roles = getRoles(username);
0399:
0400: // Create and return a suitable Principal for this user
0401: return (new GenericPrincipal(this , username, credentials, roles));
0402:
0403: }
0404:
0405: /**
0406: * Return a short name for this Realm implementation.
0407: */
0408: protected String getName() {
0409: return (name);
0410:
0411: }
0412:
0413: /**
0414: * Return the password associated with the given principal's user name.
0415: */
0416: protected String getPassword(String username) {
0417: String tableName;
0418: if (userTableName != null)
0419: tableName = userTableName;
0420: else
0421: tableName = DODSRealmConstants.TABLE_USER_NAME;
0422:
0423: String userColumnName;
0424: if (userColUserTableName != null)
0425: userColumnName = userColUserTableName;
0426: else
0427: userColumnName = DODSRealmConstants.COLUMN_USER_USER_TABLE_NAME;
0428:
0429: String passwordColumnName;
0430: if (credColUserTableName != null)
0431: passwordColumnName = credColUserTableName;
0432: else
0433: passwordColumnName = DODSRealmConstants.COLUMN_CREDENTIAL_USER_TABLE_NAME;
0434:
0435: String password = null;
0436:
0437: registerEnhydraApplication();
0438:
0439: // Look up the user's credentials
0440: try {
0441: Class tableClass = Class.forName(tableName + "DO", true,
0442: this .getClass().getClassLoader());
0443: Class queryClass = Class.forName(tableName + "Query", true,
0444: this .getClass().getClassLoader());
0445:
0446: DBTransaction tr = DODS.getDatabaseManager()
0447: .createTransaction();
0448:
0449: Class[] ArgClassArray = new Class[] { DBTransaction.class };
0450: Object[] ArgObject = new Object[] { tr };
0451: Constructor c = queryClass.getConstructor(ArgClassArray);
0452: Object queryObject = c.newInstance(ArgObject);
0453:
0454: String methodName = "setQuery"
0455: + userColumnName.substring(0, 1).toUpperCase()
0456: + userColumnName.substring(1).trim();
0457:
0458: ArgClassArray = new Class[] { String.class };
0459: ArgObject = new Object[] { username };
0460:
0461: // setQueryUsername(username)
0462: Method qMethod = queryClass.getDeclaredMethod(methodName,
0463: ArgClassArray);
0464: qMethod.invoke(queryObject, ArgObject);
0465:
0466: // requireUniqueInstance()
0467: qMethod = queryClass.getDeclaredMethod(
0468: "requireUniqueInstance", null);
0469: qMethod.invoke(queryObject, null);
0470:
0471: // getNextDO()
0472: qMethod = queryClass.getDeclaredMethod("getNextDO", null);
0473: GenericDO userDO = (GenericDO) qMethod.invoke(queryObject,
0474: null);
0475:
0476: if (userDO == null) {
0477: return null;
0478: }
0479:
0480: // getPassword()
0481: methodName = "get"
0482: + passwordColumnName.substring(0, 1).toUpperCase()
0483: + passwordColumnName.substring(1).trim();
0484: qMethod = userDO.getClass().getDeclaredMethod(methodName,
0485: null);
0486: password = (String) qMethod.invoke(userDO, null);
0487:
0488: tr.release();
0489: } catch (Exception e) {
0490: if (containerLog.isTraceEnabled())
0491: containerLog.trace(sm.getString(
0492: "dodsRealm.getPassword.exception", username));
0493: } finally {
0494: unregisterEnhydraApplication();
0495: }
0496: return password;
0497: }
0498:
0499: /**
0500: * Return the Principal associated with the given user name.
0501: */
0502: protected Principal getPrincipal(String username) {
0503: return (new GenericPrincipal(this , username,
0504: getPassword(username), getRoles(username)));
0505:
0506: }
0507:
0508: /**
0509: * Return the roles associated with the gven user name.
0510: */
0511: protected ArrayList getRoles(String username) {
0512: ArrayList roleList = null;
0513:
0514: String userTableN;
0515: if (userTableName != null)
0516: userTableN = userTableName;
0517: else
0518: userTableN = DODSRealmConstants.TABLE_USER_NAME;
0519:
0520: String roleTableN;
0521: if (roleTableName != null)
0522: roleTableN = roleTableName;
0523: else
0524: roleTableN = DODSRealmConstants.TABLE_ROLE_NAME;
0525:
0526: String userroleTableN;
0527: if (userRoleTableName != null)
0528: userroleTableN = userRoleTableName;
0529: else
0530: userroleTableN = DODSRealmConstants.TABLE_USER_ROLE_NAME;
0531:
0532: String userColUserTableN;
0533: if (userColUserTableName != null)
0534: userColUserTableN = userColUserTableName;
0535: else
0536: userColUserTableN = DODSRealmConstants.COLUMN_USER_USER_TABLE_NAME;
0537:
0538: String userColUserRoleTableN;
0539: if (userColUserRoleTableName != null)
0540: userColUserRoleTableN = userColUserRoleTableName;
0541: else
0542: userColUserRoleTableN = DODSRealmConstants.COLUMN_USER_USER_ROLE_TABLE_NAME;
0543:
0544: String roleColRoleTableN;
0545: if (userColUserTableName != null)
0546: roleColRoleTableN = roleColRoleTableName;
0547: else
0548: roleColRoleTableN = DODSRealmConstants.COLUMN_ROLE_ROLE_TABLE_NAME;
0549:
0550: String roleColUserRoleTableN;
0551: if (userColUserRoleTableName != null)
0552: roleColUserRoleTableN = roleColUserRoleTableName;
0553: else
0554: roleColUserRoleTableN = DODSRealmConstants.COLUMN_ROLE_USER_ROLE_TABLE_NAME;
0555:
0556: // Look up the user's credentials
0557:
0558: registerEnhydraApplication();
0559:
0560: try {
0561: Class userTableClass = Class.forName(userTableN + "DO",
0562: true, this .getClass().getClassLoader());
0563: Class userQueryClass = Class.forName(userTableN + "Query",
0564: true, this .getClass().getClassLoader());
0565:
0566: DBTransaction tr = DODS.getDatabaseManager()
0567: .createTransaction();
0568:
0569: Class[] ArgClassArray = new Class[] { DBTransaction.class };
0570: Object[] ArgObject = new Object[] { tr };
0571: Constructor c = userQueryClass
0572: .getConstructor(ArgClassArray);
0573: Object userQueryObject = c.newInstance(ArgObject);
0574:
0575: String methodName = "setQuery"
0576: + userColUserTableN.substring(0, 1).toUpperCase()
0577: + userColUserTableN.substring(1).trim();
0578:
0579: ArgClassArray = new Class[] { String.class };
0580: ArgObject = new Object[] { username };
0581:
0582: // setQueryUsername(username)
0583: Method qMethod = userQueryClass.getDeclaredMethod(
0584: methodName, ArgClassArray);
0585: qMethod.invoke(userQueryObject, ArgObject);
0586:
0587: // requireUniqueInstance()
0588: qMethod = userQueryClass.getDeclaredMethod(
0589: "requireUniqueInstance", null);
0590: qMethod.invoke(userQueryObject, null);
0591:
0592: // getNextDO()
0593: qMethod = userQueryClass.getDeclaredMethod("getNextDO",
0594: null);
0595: GenericDO userDO = (GenericDO) qMethod.invoke(
0596: userQueryObject, null);
0597:
0598: if (userDO == null) {
0599: return null;
0600: }
0601:
0602: Class userroleTableClass = Class.forName(userroleTableN
0603: + "DO", true, this .getClass().getClassLoader());
0604: Class userroleQueryClass = Class.forName(userroleTableN
0605: + "Query", true, this .getClass().getClassLoader());
0606:
0607: ArgClassArray = new Class[] { DBTransaction.class };
0608: ArgObject = new Object[] { tr };
0609: c = userroleQueryClass.getConstructor(ArgClassArray);
0610: Object userroleQueryObject = c.newInstance(ArgObject);
0611:
0612: methodName = "setQuery"
0613: + userColUserRoleTableN.substring(0, 1)
0614: .toUpperCase()
0615: + userColUserRoleTableN.substring(1).trim();
0616:
0617: ArgClassArray = new Class[] { userDO.getClass() };
0618: ArgObject = new Object[] { userDO };
0619:
0620: // setQueryFk_user(userDO)
0621: qMethod = userroleQueryClass.getDeclaredMethod(methodName,
0622: ArgClassArray);
0623: qMethod.invoke(userroleQueryObject, ArgObject);
0624:
0625: // getDOArray()
0626: qMethod = userroleQueryClass.getDeclaredMethod(
0627: "getDOArray", null);
0628: GenericDO[] linkDOs = (GenericDO[]) qMethod.invoke(
0629: userroleQueryObject, null);
0630:
0631: if (linkDOs == null) {
0632: return null;
0633: }
0634:
0635: roleList = new ArrayList();
0636: for (int i = 0; i < linkDOs.length; i++) {
0637:
0638: // getFk_role()
0639: methodName = "get"
0640: + roleColUserRoleTableN.substring(0, 1)
0641: .toUpperCase()
0642: + roleColUserRoleTableN.substring(1).trim();
0643: qMethod = linkDOs[i].getClass().getDeclaredMethod(
0644: methodName, null);
0645: GenericDO roleDO = (GenericDO) qMethod.invoke(
0646: linkDOs[i], null);
0647:
0648: // getRole()
0649: methodName = "get"
0650: + roleColRoleTableN.substring(0, 1)
0651: .toUpperCase()
0652: + roleColRoleTableN.substring(1).trim();
0653: qMethod = roleDO.getClass().getDeclaredMethod(
0654: methodName, null);
0655: String role = (String) qMethod.invoke(roleDO, null);
0656:
0657: roleList.add(role);
0658: }
0659: tr.release();
0660: } catch (Exception e) {
0661: if (containerLog.isTraceEnabled())
0662: containerLog.trace(sm.getString(
0663: "dodsRealm.getRole.exception", username));
0664: } finally {
0665: unregisterEnhydraApplication();
0666: }
0667: return roleList;
0668: }
0669:
0670: /**
0671: * Release our use of this connection so that it can be recycled.
0672: *
0673: * @param dbConnection The connection to be released
0674: */
0675: protected void release(Connection dbConnection) {
0676: ; // NO-OP since we are not pooling anything
0677:
0678: }
0679:
0680: // ------------------------------------------------------ Lifecycle Methods
0681:
0682: /**
0683: *
0684: * Prepare for active use of the public methods of this Component.
0685: *
0686: * @exception LifecycleException if this component detects a fatal error
0687: * that prevents it from being started
0688: */
0689: public void start() throws LifecycleException {
0690: // Perform normal superclass initialization
0691: super .start();
0692:
0693: try {
0694: InputStream stream = new FileInputStream(
0695: configurationFilePath);
0696: ConfigFile cf = new ConfigFile(stream);
0697:
0698: Config dmConfig = new Config(cf.getConfig());
0699:
0700: Context context = null;
0701: try {
0702: if (localDataSource) {
0703: if (container instanceof org.apache.catalina.Context) {
0704: namingResources = ((org.apache.catalina.Context) container)
0705: .getNamingResources();
0706: } else if (container instanceof org.apache.catalina.Server) {
0707: namingResources = ((org.apache.catalina.Server) container)
0708: .getGlobalNamingResources();
0709: } else {
0710: return;
0711: }
0712:
0713: Hashtable contextEnv = new Hashtable();
0714: try {
0715: namingContext = new NamingContext(contextEnv,
0716: getName());
0717: } catch (NamingException e) {
0718: // Never happens
0719: }
0720: ContextAccessController.setSecurityToken(getName(),
0721: container);
0722: ContextBindings.bindContext(container,
0723: namingContext, container);
0724:
0725: // Setting the context in read/write mode
0726: ContextAccessController.setWritable(getName(),
0727: container);
0728:
0729: try {
0730: createNamingContext();
0731: } catch (NamingException e) {
0732: }
0733: // Binding the naming context to the class loader
0734: if (container instanceof org.apache.catalina.Context) {
0735: // Setting the context in read only mode
0736: ContextAccessController.setReadOnly(getName());
0737: try {
0738: ContextBindings
0739: .bindClassLoader(
0740: container,
0741: container,
0742: ((org.apache.catalina.Container) container)
0743: .getLoader()
0744: .getClassLoader());
0745: } catch (NamingException e) {
0746: }
0747: }
0748: if (container instanceof org.apache.catalina.Server) {
0749: //namingResources.addPropertyChangeListener(this);
0750: org.apache.naming.factory.ResourceLinkFactory
0751: .setGlobalContext(namingContext);
0752: try {
0753: ContextBindings.bindClassLoader(container,
0754: container, this .getClass()
0755: .getClassLoader());
0756: } catch (NamingException e) {
0757: }
0758: /* if (container instanceof StandardServer) {
0759: ((StandardServer) container).setGlobalNamingContext
0760: (namingContext);
0761: }*/
0762: }
0763: context = ContextBindings.getClassLoader();
0764: context = (Context) context.lookup("comp/env");
0765: } else {
0766: StandardServer server = (StandardServer) ServerFactory
0767: .getServer();
0768: context = server.getGlobalNamingContext();
0769: }
0770: } catch (Exception e) {
0771: // Log the problem for posterity
0772: containerLog.error(sm.getString("dodsRealm.exception"),
0773: e);
0774: }
0775:
0776: String[] params = dmConfig.leafKeys();
0777: for (int i = 0; i < params.length; i++) {
0778: try {
0779: String key = params[i];
0780: if (key != null) {
0781: String value = dmConfig.getString(key);
0782: if (value.startsWith("jndi:")) {
0783: String dataSourceName = value.substring(5);
0784: DataSource dataSource = (DataSource) context
0785: .lookup(dataSourceName);
0786: if (dataSource != null) {
0787: dmConfig.set(key, dataSource);
0788: }
0789: }
0790: }
0791: } catch (Exception e) {
0792: }
0793: }
0794: try {
0795: //create the underlying enhydra Application
0796: app = new DODSRealmApplication();
0797:
0798: //set the log channel
0799: app.setLogChannel(new StandardLogger(true)
0800: .getChannel(""));
0801:
0802: //startup the app
0803: app.startup(dmConfig);
0804:
0805: } catch (Exception e) {
0806: throw new LifecycleException(
0807: "Error while setting up enhydra application.",
0808: e);
0809: }
0810: } catch (Exception e) {
0811: throw new LifecycleException("DODS init problem.", e);
0812: }
0813: }
0814:
0815: /**
0816: * Gracefully shut down active use of the public methods of this Component.
0817: *
0818: * @exception LifecycleException if this component detects a fatal error
0819: * that needs to be reported
0820: */
0821: public void stop() throws LifecycleException {
0822: // Perform normal superclass finalization
0823: super .stop();
0824: }
0825:
0826: /**
0827: *
0828: */
0829: private void registerEnhydraApplication() {
0830: Enhydra.register(app);
0831: }
0832:
0833: /**
0834: *
0835: */
0836: private void unregisterEnhydraApplication() {
0837: Enhydra.unRegister();
0838: }
0839:
0840: class DODSRealmApplication extends StandardApplication {
0841:
0842: }
0843:
0844: /**
0845: * Create and initialize the JNDI naming context.
0846: */
0847: private void createNamingContext() throws NamingException {
0848:
0849: // Creating the comp subcontext
0850: if (container instanceof org.apache.catalina.Server) {
0851: compCtx = namingContext;
0852: envCtx = namingContext;
0853: } else {
0854: compCtx = namingContext.createSubcontext("comp");
0855: envCtx = compCtx.createSubcontext("env");
0856: }
0857:
0858: int i;
0859:
0860: if (namingResources == null) {
0861: namingResources = new NamingResources();
0862: namingResources.setContainer(container);
0863: }
0864:
0865: // Resource links
0866: ContextResourceLink[] resourceLinks = namingResources
0867: .findResourceLinks();
0868: for (i = 0; i < resourceLinks.length; i++) {
0869: addResourceLink(resourceLinks[i]);
0870: }
0871:
0872: // Resources
0873: ContextResource[] resources = namingResources.findResources();
0874: for (i = 0; i < resources.length; i++) {
0875: addResource(resources[i]);
0876: }
0877:
0878: // Resources Env
0879: ContextResourceEnvRef[] resourceEnvRefs = namingResources
0880: .findResourceEnvRefs();
0881: for (i = 0; i < resourceEnvRefs.length; i++) {
0882: addResourceEnvRef(resourceEnvRefs[i]);
0883: }
0884:
0885: // Environment entries
0886: ContextEnvironment[] contextEnvironments = namingResources
0887: .findEnvironments();
0888: for (i = 0; i < contextEnvironments.length; i++) {
0889: addEnvironment(contextEnvironments[i]);
0890: }
0891:
0892: // EJB references
0893: ContextEjb[] ejbs = namingResources.findEjbs();
0894: for (i = 0; i < ejbs.length; i++) {
0895: addEjb(ejbs[i]);
0896: }
0897:
0898: // Binding a User Transaction reference
0899: if (container instanceof org.apache.catalina.Context) {
0900: try {
0901: Reference ref = new TransactionRef();
0902: compCtx.bind("UserTransaction", ref);
0903: ContextTransaction transaction = namingResources
0904: .getTransaction();
0905: if (transaction != null) {
0906: Iterator params = transaction.listProperties();
0907: while (params.hasNext()) {
0908: String paramName = (String) params.next();
0909: String paramValue = (String) transaction
0910: .getProperty(paramName);
0911: StringRefAddr refAddr = new StringRefAddr(
0912: paramName, paramValue);
0913: ref.add(refAddr);
0914: }
0915: }
0916: } catch (NameAlreadyBoundException e) {
0917: // Ignore because UserTransaction was obviously
0918: // added via ResourceLink
0919: } catch (NamingException e) {
0920: }
0921: }
0922:
0923: // Binding the resources directory context
0924: if (container instanceof org.apache.catalina.Context) {
0925: try {
0926: compCtx.bind("Resources",
0927: ((org.apache.catalina.Container) container)
0928: .getResources());
0929: } catch (NamingException e) {
0930: }
0931: }
0932:
0933: }
0934:
0935: /**
0936: * Set the specified EJBs in the naming context.
0937: */
0938: public void addEjb(ContextEjb ejb) {
0939:
0940: // Create a reference to the EJB.
0941: Reference ref = new EjbRef(ejb.getType(), ejb.getHome(), ejb
0942: .getRemote(), ejb.getLink());
0943: // Adding the additional parameters, if any
0944: Iterator params = ejb.listProperties();
0945: while (params.hasNext()) {
0946: String paramName = (String) params.next();
0947: String paramValue = (String) ejb.getProperty(paramName);
0948: StringRefAddr refAddr = new StringRefAddr(paramName,
0949: paramValue);
0950: ref.add(refAddr);
0951: }
0952: try {
0953: createSubcontexts(envCtx, ejb.getName());
0954: envCtx.bind(ejb.getName(), ref);
0955: } catch (NamingException e) {
0956: }
0957: }
0958:
0959: /**
0960: * Set the specified environment entries in the naming context.
0961: */
0962: public void addEnvironment(ContextEnvironment env) {
0963:
0964: Object value = null;
0965: // Instantiating a new instance of the correct object type, and
0966: // initializing it.
0967: String type = env.getType();
0968: try {
0969: if (type.equals("java.lang.String")) {
0970: value = env.getValue();
0971: } else if (type.equals("java.lang.Byte")) {
0972: if (env.getValue() == null) {
0973: value = new Byte((byte) 0);
0974: } else {
0975: value = Byte.decode(env.getValue());
0976: }
0977: } else if (type.equals("java.lang.Short")) {
0978: if (env.getValue() == null) {
0979: value = new Short((short) 0);
0980: } else {
0981: value = Short.decode(env.getValue());
0982: }
0983: } else if (type.equals("java.lang.Integer")) {
0984: if (env.getValue() == null) {
0985: value = new Integer(0);
0986: } else {
0987: value = Integer.decode(env.getValue());
0988: }
0989: } else if (type.equals("java.lang.Long")) {
0990: if (env.getValue() == null) {
0991: value = new Long(0);
0992: } else {
0993: value = Long.decode(env.getValue());
0994: }
0995: } else if (type.equals("java.lang.Boolean")) {
0996: value = Boolean.valueOf(env.getValue());
0997: } else if (type.equals("java.lang.Double")) {
0998: if (env.getValue() == null) {
0999: value = new Double(0);
1000: } else {
1001: value = Double.valueOf(env.getValue());
1002: }
1003: } else if (type.equals("java.lang.Float")) {
1004: if (env.getValue() == null) {
1005: value = new Float(0);
1006: } else {
1007: value = Float.valueOf(env.getValue());
1008: }
1009: } else if (type.equals("java.lang.Character")) {
1010: if (env.getValue() == null) {
1011: value = new Character((char) 0);
1012: } else {
1013: if (env.getValue().length() == 1) {
1014: value = new Character(env.getValue().charAt(0));
1015: } else {
1016: throw new IllegalArgumentException();
1017: }
1018: }
1019: } else {
1020: }
1021: } catch (NumberFormatException e) {
1022: } catch (IllegalArgumentException e) {
1023: }
1024:
1025: // Binding the object to the appropriate name
1026: if (value != null) {
1027: try {
1028: createSubcontexts(envCtx, env.getName());
1029: envCtx.bind(env.getName(), value);
1030: } catch (NamingException e) {
1031: }
1032: }
1033:
1034: }
1035:
1036: /**
1037: * Set the specified resources in the naming context.
1038: */
1039: public void addResource(ContextResource resource) {
1040:
1041: // Create a reference to the resource.
1042: Reference ref = new ResourceRef(resource.getType(), resource
1043: .getDescription(), resource.getScope(), resource
1044: .getAuth());
1045: // Adding the additional parameters, if any
1046: Iterator params = resource.listProperties();
1047: while (params.hasNext()) {
1048: String paramName = (String) params.next();
1049: String paramValue = (String) resource
1050: .getProperty(paramName);
1051: StringRefAddr refAddr = new StringRefAddr(paramName,
1052: paramValue);
1053: ref.add(refAddr);
1054: }
1055: try {
1056:
1057: createSubcontexts(envCtx, resource.getName());
1058: envCtx.bind(resource.getName(), ref);
1059: } catch (NamingException e) {
1060: }
1061:
1062: if ("javax.sql.DataSource".equals(ref.getClassName())) {
1063: try {
1064: ObjectName on = createObjectName(resource);
1065: Object actualResource = envCtx.lookup(resource
1066: .getName());
1067: Registry.getRegistry(null, null).registerComponent(
1068: actualResource, on, null);
1069: objectNames.put(resource.getName(), on);
1070: } catch (Exception e) {
1071: }
1072: }
1073:
1074: }
1075:
1076: /**
1077: * Create an <code>ObjectName</code> for this
1078: * <code>ContextResource</code> object.
1079: *
1080: * @param resource The resource
1081: * @return ObjectName The object name
1082: * @exception MalformedObjectNameException if a name cannot be created
1083: */
1084: protected ObjectName createObjectName(ContextResource resource)
1085: throws MalformedObjectNameException {
1086:
1087: String domain = null;
1088: /* if (container instanceof StandardServer) {
1089: domain = ((StandardServer) container).getDomain();
1090: } else */if (container instanceof ContainerBase) {
1091: domain = ((ContainerBase) container).getDomain();
1092: }
1093: if (domain == null) {
1094: domain = "Catalina";
1095: }
1096:
1097: ObjectName name = null;
1098: String quotedResourceName = ObjectName
1099: .quote(resource.getName());
1100: if (container instanceof org.apache.catalina.Server) {
1101: name = new ObjectName(domain + ":type=DataSource"
1102: + ",class=" + resource.getType() + ",name="
1103: + quotedResourceName);
1104: } else if (container instanceof org.apache.catalina.Context) {
1105: String path = ((org.apache.catalina.Context) container)
1106: .getPath();
1107: if (path.length() < 1)
1108: path = "/";
1109: Host host = (Host) ((org.apache.catalina.Context) container)
1110: .getParent();
1111: Engine engine = (Engine) host.getParent();
1112: Service service = engine.getService();
1113: name = new ObjectName(domain + ":type=DataSource"
1114: + ",path=" + path + ",host=" + host.getName()
1115: + ",class=" + resource.getType() + ",name="
1116: + quotedResourceName);
1117: }
1118:
1119: return (name);
1120:
1121: }
1122:
1123: /**
1124: * Set the specified resources in the naming context.
1125: */
1126: public void addResourceEnvRef(ContextResourceEnvRef resourceEnvRef) {
1127:
1128: // Create a reference to the resource env.
1129: Reference ref = new ResourceEnvRef(resourceEnvRef.getType());
1130: // Adding the additional parameters, if any
1131: Iterator params = resourceEnvRef.listProperties();
1132: while (params.hasNext()) {
1133: String paramName = (String) params.next();
1134: String paramValue = (String) resourceEnvRef
1135: .getProperty(paramName);
1136: StringRefAddr refAddr = new StringRefAddr(paramName,
1137: paramValue);
1138: ref.add(refAddr);
1139: }
1140: try {
1141: createSubcontexts(envCtx, resourceEnvRef.getName());
1142: envCtx.bind(resourceEnvRef.getName(), ref);
1143: } catch (NamingException e) {
1144: }
1145:
1146: }
1147:
1148: /**
1149: * Set the specified resource link in the naming context.
1150: */
1151: public void addResourceLink(ContextResourceLink resourceLink) {
1152:
1153: // Create a reference to the resource.
1154: Reference ref = new ResourceLinkRef(resourceLink.getType(),
1155: resourceLink.getGlobal());
1156: javax.naming.Context ctx = "UserTransaction"
1157: .equals(resourceLink.getName()) ? compCtx : envCtx;
1158: try {
1159: createSubcontexts(envCtx, resourceLink.getName());
1160: ctx.bind(resourceLink.getName(), ref);
1161: } catch (NamingException e) {
1162: }
1163:
1164: }
1165:
1166: /**
1167: * Create all intermediate subcontexts.
1168: */
1169: private void createSubcontexts(javax.naming.Context ctx, String name)
1170: throws NamingException {
1171: javax.naming.Context currentContext = ctx;
1172: StringTokenizer tokenizer = new StringTokenizer(name, "/");
1173: while (tokenizer.hasMoreTokens()) {
1174: String token = tokenizer.nextToken();
1175: if ((!token.equals("")) && (tokenizer.hasMoreTokens())) {
1176: try {
1177: currentContext = currentContext
1178: .createSubcontext(token);
1179: } catch (NamingException e) {
1180: // Silent catch. Probably an object is already bound in
1181: // the context.
1182: currentContext = (javax.naming.Context) currentContext
1183: .lookup(token);
1184: }
1185: }
1186: }
1187: }
1188:
1189: }
|