package org.tgdb.project; import java.io.PrintWriter; import org.tgdb.exceptions.ApplicationException; import org.tgdb.exceptions.PermissionDeniedException; import org.tgdb.TgDbCaller; import org.tgdb.id.IdGenerator; import org.tgdb.id.PostgresId; import org.tgdb.project.project.ProjectRemote; import org.tgdb.project.user.UserRemoteHome; import org.tgdb.servicelocator.ServiceLocator; import java.io.Serializable; import java.io.StringWriter; import java.sql.Connection; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Iterator; import javax.ejb.EJBException; import org.apache.log4j.Logger; public abstract class AbstractTgDbBean implements Serializable { protected static Logger logger = Logger.getLogger(AbstractTgDbBean.class); protected TgDbCaller caller; protected ServiceLocator locator; /** This is used in most entity beans */ protected static UserRemoteHome userHome; protected static int countMakeConnection; protected static int countReleaseConnection; public AbstractTgDbBean() { locator = ServiceLocator.getInstance(); if (userHome==null) userHome = (UserRemoteHome)locator.getHome(ServiceLocator.Services.USER); } /** * The database connection. This can be used after a call to * <CODE>makeConnection()</CODE> and before a <CODE>releaseConnection()</CODE> */ protected Connection conn; /** * The id object gets the Id class for the database in use. Use the method * getIdGenerator. */ private IdGenerator id; /** * Get the Id generator object * * Example: to get a rid for a new role the following code should be called: * <CODE>rid = getIIdGenerator().getNextId(conn, "roles_seq");</CODE> * @return a IdGenerator that should be used. */ protected IdGenerator getIIdGenerator() { if (id==null) { // create new id = new PostgresId(); } return id; } public void setCaller(TgDbCaller caller) { this.caller = caller; } // public TgDbCaller getCaller() { // return caller; // } protected synchronized void makeConnection() { try { countMakeConnection++; javax.sql.DataSource ds = null; javax.naming.Context c = new javax.naming.InitialContext(); ds = (javax.sql.DataSource)c.lookup("jdbc/crezoo"); conn = ds.getConnection(); } catch (Exception e) { //e.printStackTrace(); logger.error("---------------------------------------->AbstractTgDbBean#makeConnection: Failed to connect to database"); throw new EJBException("AbstractTgDbBean#makeConnection\n"+e.getMessage()); } } /** * Release an active connection to the database from the connection pool. * This must be called after database operations are done. Failure to do * so results in a full connection pool. */ protected synchronized void releaseConnection() { try { countReleaseConnection++; //logger.debug("---------------------------------------->AbstractTgDbBean#releaseConnection: Released connection"); conn.close(); conn = null; } catch (Exception e) { e.printStackTrace(); throw new EJBException("Unable to close database: "+e.getMessage()); } } /** * Validates if the string passed along as argument is a number. * @param field The name of the input field to be tested * @param asDouble Sets if the number should be tested as a decimal number * @param number The string to validate * @throws org.tgdb.exceptions.ApplicationException If the string is not a number */ protected void validate(String field, String number, boolean asDouble) throws ApplicationException { String mess = "is not an integer"; try { if(asDouble) { Double.parseDouble(number); mess = "is not a decimal"; } else { Integer.parseInt(number); } } catch(NumberFormatException e){ throw new ApplicationException(field+" "+mess); } } /** * Validates the length of a string * @param field The name of the data field * @param data The data string * @param maxLength The maximum allowed length of the string * @throws ApplicationException if the length of the data exceeds the max length */ protected void validate(String field, String data, int maxLength) throws ApplicationException { if(data == null) data = ""; if(data.length() > maxLength) throw new ApplicationException("Input value for '"+field+"' has too many characters."); } /** * Validates if the user has the required privilege * @param caller The caller to validate * @param priv The privilege to validate * @throws org.tgdb.exceptions.PermissionDeniedException If the user did not have the privilege */ protected void validate(String priv, TgDbCaller caller) throws PermissionDeniedException { if (!caller.hasPrivilege(priv) && !caller.isAdmin()) { PermissionDeniedException pd = new PermissionDeniedException("No privilege: "+priv+" is required for user "+caller.getName()+"["+caller.getId()+"]"); pd.fillInStackTrace(); throw pd; } } protected void validatePid(String priv, TgDbCaller caller, int pid) throws PermissionDeniedException { if (!caller.hasPrivilege(priv, pid) && !caller.isAdmin()) { PermissionDeniedException pd = new PermissionDeniedException("No privilege: "+priv+" is required for user "+caller.getName()+"["+caller.getId()+"]"); pd.fillInStackTrace(); throw pd; } } protected void validateSU(String priv, TgDbCaller caller, int suid) throws PermissionDeniedException { if (!caller.hasPrivilegeSU(priv, suid) && !caller.isAdmin()) { PermissionDeniedException pd = new PermissionDeniedException("No privilege: "+priv+" is required for user "+caller.getName()+"["+caller.getId()+"]"); pd.fillInStackTrace(); throw pd; } } /** * Validates if the user has the required privilege * @param projects a collection of ProjectRemote objects * @param caller The caller to validate * @param priv The privilege to validate * @throws org.tgdb.exceptions.PermissionDeniedException If the user did not have the privilege */ protected void validate(String priv, TgDbCaller caller, Collection projects) throws PermissionDeniedException { // If admin, dont bother to check more, privilege granted. if (caller.isAdmin()) return; boolean projectMatch = false; try { Iterator i = projects.iterator(); while (i.hasNext()) { ProjectRemote prj = (ProjectRemote)i.next(); logger.debug("---------------------------------------->AbstractTgDbBean#validate: Project '"+prj.getName()+"'"); if (prj.getPid() == caller.getPid()) projectMatch = true; } } catch (Exception e) { e.printStackTrace(); } if (!projectMatch) { logger.error("---------------------------------------->AbstractTgDbBean#validate: User not assigned to project"); throw new PermissionDeniedException("User not assigned to project"); } //logger.debug("---------------------------------------->AbstractTgDbBean#validate: User qualification '"+projectMatch+"'"); if (!caller.hasPrivilege(priv)) { logger.error("---------------------------------------->AbstractTgDbBean#validate: No '"+priv+"' privilege for user '"+caller.getName()+"'"); PermissionDeniedException pd = new PermissionDeniedException("No privilege: "+priv+" is required for user "+caller.getName()+"["+caller.getId()+"]"); //pd.fillInStackTrace(); throw pd; } } /** * Validates if the user has the required privilege * @param caller The caller to validate * @param priv The privilege to validate * @throws org.tgdb.exceptions.PermissionDeniedException If the user did not have the privilege */ protected void validate(String priv, String message, TgDbCaller caller) throws PermissionDeniedException { if (!caller.hasPrivilege(priv)) throw new PermissionDeniedException("No privilege: "+message); } /** * Validates a date * @param field The name of the field to validate * @param date The date to validate * @param format The format to validate * @throws org.tgdb.exceptions.ApplicationException If the date was in wrong format */ protected void validate(String field, String date, SimpleDateFormat format) throws ApplicationException { if(date == null) date = ""; try { SimpleDateFormat sdf = format; sdf.setLenient(false); Date dt2 = sdf.parse(date); } catch (ParseException e) { throw new ApplicationException("Input value for field '"+field+"' is on wrong format for date. Expected format is: "+format.toPattern()); } catch (IllegalArgumentException e) { throw new ApplicationException("Input value for field '"+field+"' is on wrong format for date. Expected format is: "+format.toPattern()); } } public boolean exists(String value) { if(value != null && value.length() > 0) return true; else return false; } protected String buildQueryConditions(ParamDataObject qdo) { String sql = ""; if(qdo != null && qdo.hasValues()) { ArrayList list = qdo.getKeys(); String column = ""; String data = ""; for(int i=0;i<list.size();i++) { column = (String)list.get(i); data = qdo.getValue(column); if(data.length() > 0) sql += " AND "+column+"='"+data+"'"; } } return sql; } /* * Returns the stack trace as string */ public String getStackTrace(Throwable t) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw, true); t.printStackTrace(pw); pw.flush(); sw.flush(); return sw.toString(); } }