diff --git a/alitheia/core/pom.xml b/alitheia/core/pom.xml index 4203d2dda..74600386a 100644 --- a/alitheia/core/pom.xml +++ b/alitheia/core/pom.xml @@ -63,7 +63,83 @@ + + org.jacoco + jacoco-maven-plugin + 0.7.2.201409121644 + + + + pre-unit-test + + prepare-agent + + + + ${project.build.directory}/coverage-reports/jacoco-ut.exec + + surefireArgLine + + + + + post-unit-test + test + + report + + + + ${project.build.directory}/coverage-reports/jacoco-ut.exec + + ${project.reporting.outputDirectory}/jacoco-ut + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.jacoco + + jacoco-maven-plugin + + + [0.7.2.201409121644,) + + + prepare-agent + + + + + + + + + + + + @@ -176,6 +252,18 @@ 1.9.5 test + + com.h2database + h2 + 1.4.184 + test + + + org.hamcrest + hamcrest-all + 1.3 + test + diff --git a/alitheia/core/src/main/java/eu/sqooss/core/AlitheiaCore.java b/alitheia/core/src/main/java/eu/sqooss/core/AlitheiaCore.java index 63610d55f..d55d062a7 100644 --- a/alitheia/core/src/main/java/eu/sqooss/core/AlitheiaCore.java +++ b/alitheia/core/src/main/java/eu/sqooss/core/AlitheiaCore.java @@ -162,6 +162,10 @@ public static AlitheiaCore testInstance() { return instance; } + public static void setTestInstance(AlitheiaCore testInstance) { + instance = testInstance; + } + /** * Register an external implementation of an AlitheiaCore service. It * will override any internally defined implementation. diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/admin/AdminServiceImpl.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/admin/AdminServiceImpl.java index bcd0f6556..88de58f37 100644 --- a/alitheia/core/src/main/java/eu/sqooss/impl/service/admin/AdminServiceImpl.java +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/admin/AdminServiceImpl.java @@ -100,9 +100,9 @@ public void execute(AdminAction a) { DBService db = null; if (AlitheiaCore.getInstance() != null) { db = AlitheiaCore.getInstance().getDBService(); - if (db.isDBSessionActive() != true) { + if (db.getSessionManager().isDBSessionActive() != true) { commitDB = true; - db.startDBSession(); + db.getSessionManager().startDBSession(); } } @@ -111,14 +111,14 @@ public void execute(AdminAction a) { a.execute(); } catch (Exception e) { if ((db != null) && commitDB) - db.rollbackDBSession(); + db.getSessionManager().rollbackDBSession(); err("Error executing action " + a.mnemonic() + ", id " + a.id() + "\nCause:" + e.getMessage(), e); } finally { ActionContainer ac = liveactions.get(a.id()); if (db != null) - if (db.isDBSessionActive() && commitDB) - db.commitDBSession(); + if (db.getSessionManager().isDBSessionActive() && commitDB) + db.getSessionManager().commitDBSession(); ac.end = System.currentTimeMillis(); debug("Action " + a.id() + " finished in " + (ac.end - ac.start) + " msec" ); } diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/cluster/ClusterNodeServiceImpl.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/cluster/ClusterNodeServiceImpl.java index 5f8f77478..ba590cc59 100644 --- a/alitheia/core/src/main/java/eu/sqooss/impl/service/cluster/ClusterNodeServiceImpl.java +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/cluster/ClusterNodeServiceImpl.java @@ -55,6 +55,7 @@ import eu.sqooss.service.cluster.ClusterNodeService; import eu.sqooss.service.db.ClusterNode; import eu.sqooss.service.db.DBService; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.StoredProject; import eu.sqooss.service.logging.Logger; import eu.sqooss.service.updater.UpdaterService; @@ -160,9 +161,9 @@ public boolean assignProject(StoredProject project) throws ClusterNodeActionExce * @param projectname project's name to assign */ public boolean assignProject(String projectname) throws ClusterNodeActionException { - dbs.startDBSession(); + dbs.getSessionManager().startDBSession(); StoredProject project = StoredProject.getProjectByName(projectname); - dbs.rollbackDBSession(); + dbs.getSessionManager().rollbackDBSession(); if (project == null) { //the project was not found, can't be assign String errorMessage = "The project [" + projectname + "] was not found"; @@ -275,9 +276,9 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) // If empty, assign it to this clusternode // Example: http://localhost:8088/clusternode?action=assign_project&projectname=iTALC&clusternode=sqoserver1 - dbs.startDBSession(); + dbs.getSessionManager().startDBSession(); project = StoredProject.getProjectByName(projectname); - dbs.rollbackDBSession(); + dbs.getSessionManager().rollbackDBSession(); if (project==null) { if (projectid!=null) { long id = 0; @@ -288,9 +289,9 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) sendXMLResponse(response, HttpServletResponse.SC_BAD_REQUEST, content); break; } - dbs.startDBSession(); - project = dbs.findObjectById(StoredProject.class, id); - dbs.rollbackDBSession(); + dbs.getSessionManager().startDBSession(); + project = dbs.getQueryInterface().findObjectById(StoredProject.class, id); + dbs.getSessionManager().rollbackDBSession(); if (project==null) { content = createXMLResponse(null,"Project with id:" + projectid + " not found", HttpServletResponse.SC_NOT_FOUND); sendXMLResponse(response, HttpServletResponse.SC_NOT_FOUND, content); @@ -306,9 +307,9 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) if (clusternode==null) { node = thisNode; } else { - dbs.startDBSession(); + dbs.getSessionManager().startDBSession(); node = ClusterNode.getClusteNodeByName(clusternode); - dbs.rollbackDBSession(); + dbs.getSessionManager().rollbackDBSession(); if (node==null) { content = createXMLResponse(null,"ClusterNode " + clusternode + " not found", HttpServletResponse.SC_NOT_FOUND); sendXMLResponse(response, HttpServletResponse.SC_NOT_FOUND, content); @@ -335,9 +336,9 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) if (clusternode==null) { node = thisNode; } else { - dbs.startDBSession(); + dbs.getSessionManager().startDBSession(); node = ClusterNode.getClusteNodeByName(clusternode); - dbs.rollbackDBSession(); + dbs.getSessionManager().rollbackDBSession(); } if (node==null){ content = createXMLResponse(null, "ClusterNode "+clusternode+" not found", HttpServletResponse.SC_NOT_FOUND); @@ -346,7 +347,7 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) } bcontent = new StringBuilder(); - dbs.startDBSession(); + dbs.getSessionManager().startDBSession(); Set assignments = ClusterNode.thisNode().getProjects(); if ((assignments!=null) && (assignments.size()>0) ){ bcontent.append("\n"); @@ -357,7 +358,7 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) bcontent.append(">" + sp.getName() + "\n"); } } - dbs.rollbackDBSession(); + dbs.getSessionManager().rollbackDBSession(); content = createXMLResponse(bcontent.toString(), "Project list processed succesfuly", HttpServletResponse.SC_OK); sendXMLResponse(response, HttpServletResponse.SC_OK, content); break; @@ -365,15 +366,15 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) // valid parameters: No need for parameters! // Example: http://localhost:8088/clusternode?action=get_known_servers bcontent = new StringBuilder(); - dbs.startDBSession(); - List nodes = (List) dbs.doHQL("FROM ClusterNode",null); + dbs.getSessionManager().startDBSession(); + List nodes = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL("FROM ClusterNode",null); if ((nodes!=null) && (nodes.size()>0) ){ bcontent.append("\n"); for (ClusterNode cn : nodes) { bcontent.append("" + cn.getName() + "\n"); } } - dbs.rollbackDBSession(); + dbs.getSessionManager().rollbackDBSession(); content = createXMLResponse(bcontent.toString(), "Clusternode list processed succesfuly", HttpServletResponse.SC_OK); sendXMLResponse(response, HttpServletResponse.SC_OK, content); break; @@ -429,31 +430,31 @@ public boolean startUp() { // At this point, this ClusterNode has not been registered to the // database yet, so do it! if (thisNode == null) { // paranoia check - dbs.startDBSession(); + dbs.getSessionManager().startDBSession(); // Check if previously registered in DB Map serverProps = new HashMap(1); serverProps.put("name", localServerName); - List s = dbs.findObjectsByProperties( + List s = dbs.getQueryInterface().findObjectsByProperties( ClusterNode.class, serverProps); if (s.isEmpty()) { // not registered yet, create a record in DB thisNode = new ClusterNode(); thisNode.setName(localServerName); - if (!dbs.addRecord(thisNode)) { + if (!dbs.getQueryInterface().addRecord(thisNode)) { logger.error("Failed to register ClusterNode <" + localServerName + ">"); - dbs.rollbackDBSession(); + dbs.getSessionManager().rollbackDBSession(); return false; } else { - dbs.commitDBSession(); + dbs.getSessionManager().commitDBSession(); logger.info("ClusterNode <" + localServerName + "> registered succesfully."); return true; } } else { // already registered, keep the record from DB - dbs.rollbackDBSession(); + dbs.getSessionManager().rollbackDBSession(); thisNode = s.get(0); logger.info("ClusterNode <" + localServerName + "> registered succesfully."); diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/db/DBServiceImpl.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/db/DBServiceImpl.java index 546b4addd..65e122994 100644 --- a/alitheia/core/src/main/java/eu/sqooss/impl/service/db/DBServiceImpl.java +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/db/DBServiceImpl.java @@ -36,35 +36,32 @@ import java.io.File; import java.io.FilenameFilter; -import java.net.URL; import java.net.URI; +import java.net.URL; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.concurrent.atomic.AtomicBoolean; -import org.hibernate.HibernateException; -import org.hibernate.LockMode; -import org.hibernate.QueryException; -import org.hibernate.JDBCException; -import org.hibernate.Query; -import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; -import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Configuration; import org.osgi.framework.BundleContext; import eu.sqooss.core.AlitheiaCoreService; -import eu.sqooss.service.db.DAObject; import eu.sqooss.service.db.DBService; +import eu.sqooss.service.db.DBSessionManager; +import eu.sqooss.service.db.DBSessionValidation; +import eu.sqooss.service.db.HQLQueryInterface; +import eu.sqooss.service.db.QueryInterface; +import eu.sqooss.service.db.QueryInterfaceFactory; +import eu.sqooss.service.db.SQLQueryInterface; import eu.sqooss.service.logging.Logger; import eu.sqooss.service.util.URIUtills; @@ -125,52 +122,12 @@ public class DBServiceImpl implements DBService, AlitheiaCoreService { private BundleContext bc = null; private AtomicBoolean isInitialised = new AtomicBoolean(false); private Properties conProp = new Properties(); + private DBSessionManager sessionManager = null; + private DBSessionValidation sessionValidation = null; - private void logSQLException(SQLException e) { - - while (e != null) { - String message = String.format("SQLException: SQL State:%s, Error Code:%d, Message:%s", - e.getSQLState(), e.getErrorCode(), e.getMessage()); - logger.warn(message); - e = e.getNextException(); - } - } - - private void logExceptionAndTerminateSession( Exception e ) { - if ( e instanceof JDBCException ) { - JDBCException jdbce = (JDBCException) e; - logSQLException(jdbce.getSQLException()); - } - logger.warn("Exception caught during database session: " + e.getMessage() - + ". Rolling back current transaction and terminating session..."); - e.printStackTrace(); - Session s = null; - try { - s = sessionFactory.getCurrentSession(); - s.getTransaction().rollback(); - } catch (HibernateException e1) { - logger.error("Error while rolling back failed transaction :" + e1.getMessage()); - if ( s != null ) { - try { - s.close(); - } catch ( HibernateException e2) {} - } - } - - } - - private boolean checkSession() { - if ( !isDBSessionActive() ) { - logger.warn("Trying to call a DBService method without an active session"); - try { - throw new Exception("No active session."); - } catch (Exception e) { - e.printStackTrace(); - } - return false; - } - return true; - } + private Map, Class>> + queryInterfaceFactories = new HashMap<>(); + private Map, QueryInterface> queryInterfaces = new HashMap<>(); private boolean getJDBCConnection() { String driver = conProp.getProperty("hibernate.connection.driver_class"); @@ -190,7 +147,7 @@ private boolean getJDBCConnection() { return false; } catch (SQLException e) { logger.error("Failed to register driver " + driver); - logSQLException(e); + sessionValidation.logSQLException(e); return false; } @@ -205,7 +162,7 @@ private boolean getJDBCConnection() { } catch (SQLException e) { logger.error("Unable to connect to DB URL " + conProp.getProperty("hibernate.connection.url")); - logSQLException(e); + sessionValidation.logSQLException(e); return false; } } @@ -273,6 +230,10 @@ public boolean accept(File dir, String name) { } sessionFactory = c.buildSessionFactory(); + DBSessionManagerImpl ssm = new DBSessionManagerImpl(sessionFactory, logger, isInitialised); + sessionManager = ssm; + sessionValidation = ssm; + if (sessionFactory == null) return false; } catch (Throwable e) { @@ -283,12 +244,19 @@ public boolean accept(File dir, String name) { return true; } + private void preloadFactories() { + registerQueryInterface(QueryInterface.class, HQLQueryInterfaceImpl.Factory.class); + registerQueryInterface(HQLQueryInterface.class, HQLQueryInterfaceImpl.Factory.class); + registerQueryInterface(SQLQueryInterface.class, SQLQueryInterfaceImpl.Factory.class); + } + public DBServiceImpl() { } public DBServiceImpl(Properties p, URL configFileURL, Logger l) { this.conProp = p; this.logger = l; initHibernate(configFileURL); + preloadFactories(); isInitialised.compareAndSet(false, true); instance = this; } @@ -298,480 +266,10 @@ public static DBService getInstance() { instance = new DBServiceImpl(); return instance; } - - public T findObjectById(Class daoClass, long id) { - return doFindObjectById(daoClass, id, false); - } - - public T findObjectByIdForUpdate(Class daoClass, long id) { - return doFindObjectById(daoClass, id, true); - } - - @SuppressWarnings("unchecked") - private T doFindObjectById(Class daoClass, long id, boolean useLock) { - if ( !checkSession() ) - return null; - - try { - Session s = sessionFactory.getCurrentSession(); - return (T) (useLock ? s.get(daoClass, id, LockMode.UPGRADE) : s.get(daoClass, id)); - } catch (HibernateException e) { - logExceptionAndTerminateSession(e); - return null; - } - } - - public List findObjectsByProperties(Class daoClass, Map properties) { - return doFindObjectsByProperties(daoClass, properties, false); - } - - public List findObjectsByPropertiesForUpdate(Class daoClass, Map properties) { - return doFindObjectsByProperties(daoClass, properties, true); - } - - @SuppressWarnings("unchecked") - private List doFindObjectsByProperties(Class daoClass, Map properties, boolean useLock) { - if( !checkSession() ) - return Collections.emptyList(); - - // TODO maybe check that the properties are valid (e.g. with java.bean.PropertyDescriptor) - - Map parameterMap = new HashMap(); - StringBuffer whereClause = new StringBuffer(); - for (String key : properties.keySet()) { - whereClause.append( whereClause.length() == 0 ? " where " : " and " ); - // We use "foo" as the name of the object - whereClause.append("foo" + "." + key + "=:_" + key ); - parameterMap.put( "_" + key, properties.get(key) ); - } - try { - // We use "foo" as the name of the object - return (List) doHQL( "from " + daoClass.getName() + " as foo " + whereClause, parameterMap, useLock ); - } catch (QueryException e) { - logger.warn("findObjectsByProperties(): invalid properties map. Restarting session..."); - // Automatically restart a session - // (just be careful with preloaded DAOs that become detached) - startDBSession(); - return Collections.emptyList(); - } - } - - /* (non-Javadoc) - * @see eu.sqooss.service.db.DBService#doSQL(java.lang.String) - */ - public List doSQL(String sql) - throws SQLException { - return doSQL(sql, null); - } - - /* (non-Javadoc) - * @see eu.sqooss.service.db.DBService#doSQL(java.lang.String, java.util.Map) - */ - public List doSQL(String sql, Map params) - throws SQLException, QueryException { - boolean autoSession = !isDBSessionActive(); - try { - Session s = sessionFactory.getCurrentSession(); - if (autoSession) { - s.beginTransaction(); - } - Query query = s.createSQLQuery(sql); - if ( params != null ) { - for ( String param : params.keySet() ) { - query.setParameter(param, params.get(param)); - } - } - List result = query.list(); - if (autoSession) { - s.getTransaction().commit(); - } - return result; - } catch ( JDBCException e ) { - logExceptionAndTerminateSession(e); - throw e.getSQLException(); - } catch ( QueryException e ) { - logExceptionAndTerminateSession(e); - throw e; - } catch( HibernateException e ) { - logExceptionAndTerminateSession(e); - return Collections.emptyList(); - } - } - - public int callProcedure(String procName, List args, Map params) - throws SQLException, QueryException { - boolean autoSession = !isDBSessionActive(); - StringBuilder sql = new StringBuilder("call " + procName + "("); - - for (String arg : args) { - sql.append(":").append(arg).append(","); - } - sql.deleteCharAt(sql.lastIndexOf(",")).append(")"); - - try { - Session s = sessionFactory.getCurrentSession(); - if (autoSession) { - s.beginTransaction(); - } - Query query = s.createSQLQuery(sql.toString()); - if (params != null) { - for (String param : params.keySet()) { - query.setParameter(param, params.get(param)); - } - } - int result = query.executeUpdate(); - if (autoSession) { - s.getTransaction().commit(); - } - return result; - } catch (JDBCException e) { - logExceptionAndTerminateSession(e); - throw e.getSQLException(); - } catch (QueryException e) { - logExceptionAndTerminateSession(e); - throw e; - } catch (HibernateException e) { - logExceptionAndTerminateSession(e); - throw e; - } - } - - /* (non-Javadoc) - * @see eu.sqooss.service.db.DBService#doHQL(java.lang.String) - */ - public List doHQL(String hql) - throws QueryException { - return doHQL(hql, null, null, false, -1, -1); - } - - /* (non-Javadoc) - * @see eu.sqooss.service.db.DBService#doHQL(java.lang.String, java.util.Map) - */ - public List doHQL(String hql, Map params) - throws QueryException { - return doHQL(hql, params, null, false, -1, -1); - } - - /* (non-Javadoc) - * @see eu.sqooss.service.db.DBService#doHQL(java.lang.String, java.util.Map, int) - */ - public List doHQL(String hql, Map params, int limit) - throws QueryException { - return doHQL(hql, params, null, false, 0, limit); - } - - /* (non-Javadoc) - * @see eu.sqooss.service.db.DBService#doHQL(java.lang.String, java.util.Map, boolean) - */ - public List doHQL(String hql, Map params, boolean lockForUpdate) - throws QueryException { - return doHQL(hql, params, null, lockForUpdate, -1, -1); - } - - /* (non-Javadoc) - * @see eu.sqooss.service.db.DBService#doHQL(java.lang.String, java.util.Map, java.util.Map) - */ - public List doHQL(String hql, Map params, - Map collectionParams) - throws QueryException { - return doHQL(hql, params, collectionParams, false, -1, -1); - } - /* (non-Javadoc) - * @see eu.sqooss.service.db.DBService#doHQL(java.lang.String, java.util.Map, java.util.Map, boolean, int, int) - */ - public List doHQL(String hql, Map params, - Map collectionParams, boolean lockForUpdate, int start, int limit) - throws QueryException { - if ( !checkSession() ) { - return Collections.emptyList(); - } - try { - Session s = sessionFactory.getCurrentSession(); - Query query = s.createQuery(hql); - if (params != null) { - for ( String param : params.keySet() ) { - query.setParameter(param, params.get(param)); - } - } - if (collectionParams != null) { - for ( String param : collectionParams.keySet() ) { - query.setParameterList(param, collectionParams.get(param)); - } - } - if (lockForUpdate) { - query.setLockMode("foo", LockMode.PESSIMISTIC_WRITE); - } - if ( start >= 0 && limit >= 0 ) { - query.setFirstResult(start); - query.setMaxResults(limit); - } - return query.list(); - } catch ( QueryException e ) { - logExceptionAndTerminateSession(e); - throw e; - } catch( HibernateException e ) { - logExceptionAndTerminateSession(e); - return Collections.emptyList(); - } catch (ClassCastException e) { - // Throw a QueryException instead of forwarding the ClassCastException - // it's more explicit - QueryException ebis = new QueryException("Invalid HQL query parameter type: " - + e.getMessage(), e); - logExceptionAndTerminateSession(ebis); - throw ebis; - } - - } - - /* (non-Javadoc) - * @see eu.sqooss.service.db.DBService#addRecord(eu.sqooss.service.db.DAObject) - */ - public boolean addRecord(DAObject record) { - ArrayList tmpList = new ArrayList(1); - tmpList.add(record); - return addRecords(tmpList); - } - - /* (non-Javadoc) - * @see eu.sqooss.service.db.DBService#deleteRecord(eu.sqooss.service.db.DAObject) - */ - public boolean deleteRecord(DAObject record) { - ArrayList tmpList = new ArrayList(1); - tmpList.add(record); - return deleteRecords(tmpList); - } - - /* (non-Javadoc) - * @see eu.sqooss.service.db.DBService#addRecords(java.util.List) - */ - public boolean addRecords(List records) { - if( !checkSession() ) - return false; - - DAObject lastRecord = null; - try { - Session s = sessionFactory.getCurrentSession(); - for (DAObject record : records) { - lastRecord = record; - s.save(record); - } - lastRecord = null; - s.flush(); - return true; - } catch (HibernateException e) { - if (lastRecord != null) { - logger.error("Failed to add object " - + "[" + lastRecord.getClass().getName() + ":" + lastRecord.getId() + "]" - + " to the database: " + e.getMessage()); - } - logExceptionAndTerminateSession(e); - return false; - } - } - - /* (non-Javadoc) - * @see eu.sqooss.service.db.DBService#deleteRecords(java.util.List) - */ - public boolean deleteRecords(List records) { - if( !checkSession() ) - return false; - - DAObject lastRecord = null; - try { - Session s = sessionFactory.getCurrentSession(); - for (DAObject record : records) { - lastRecord = record; - s.delete(record); - } - lastRecord = null; - s.flush(); - return true; - } catch (HibernateException e) { - if (lastRecord != null) { - logger.error("Failed to remove object " - + "[" + lastRecord.getClass().getName() + ":" + lastRecord.getId() + "]" - + " from the database: " + e.getMessage()); - } - logExceptionAndTerminateSession(e); - return false; - } - } public Logger logger() { return this.logger; - } - - public boolean startDBSession() { - //Boot time check - if(isInitialised.get() == false) { - return false; - } - - if( isDBSessionActive() ) { - logger.debug("startDBSession() - a session was already started for that thread"); - return true; - } - - Session s = null; - try { - s = sessionFactory.getCurrentSession(); - //logger.debug("startDBSession: " + s + "[hashcode=" + s.hashCode() + ",open=" + s.isOpen() + "]"); - s.beginTransaction(); - } catch (HibernateException e) { - logger.error("startDBSession() - error while initializing session: " + e.getMessage()); - if ( s != null ) { - try { - s.close(); - } catch (HibernateException e1) { - } - } - return false; - } - return true; - } - - public boolean commitDBSession() { - if ( !checkSession() ) - return false; - - Session s = null; - try { - s = sessionFactory.getCurrentSession(); - //logger.debug("commitDBSession: " + s + "[hashcode=" + s.hashCode() + ",open=" + s.isOpen() + "]"); - s.getTransaction().commit(); - } catch (HibernateException e) { - logger.error("commitDBSession() - error while committing transaction: " + e.getMessage()); - if ( s != null ) { - // The docs say to do so - try { - s.getTransaction().rollback(); - } catch (HibernateException e1) { - try { - s.close(); - } catch (HibernateException e2) { - } - } - } - return false; - } - return true; - } - - public boolean rollbackDBSession() { - if ( !checkSession() ) - return false; - - Session s = null; - try { - s = sessionFactory.getCurrentSession(); - s.getTransaction().rollback(); - } catch (HibernateException e) { - logger.error("commitDBSession() - error while rolling back transaction: " + e.getMessage()); - if ( s != null ) { - try { - s.close(); - } catch (HibernateException e1) { - } - } - return false; - } - return true; - } - - public boolean flushDBSession() { - if ( !checkSession() ) - return false; - - Session s = null; - try { - s = sessionFactory.getCurrentSession(); - s.flush(); - s.clear(); - } catch (HibernateException e) { - logger.error("flushDBSession() - error while flushing session: " + e.getMessage()); - if ( s != null ) { - try { - s.close(); - } catch (HibernateException e1) { - } - } - return false; - } - return true; - } - - public boolean isDBSessionActive() { - //Boot time check - if(isInitialised.get() == false) { - return false; - } - - Session s = null; - try { - s = sessionFactory.getCurrentSession(); - return s.getTransaction() != null && s.getTransaction().isActive(); - } catch (HibernateException e) { - logger.error("isDBSessionActive() - error while checking session status: " + e.getMessage()); - if ( s != null ) { - try { - s.close(); - } catch (HibernateException e1) { - } - } - return false; - } - } - - @SuppressWarnings("unchecked") - public T attachObjectToDBSession(T obj) { - if( !checkSession() ) - return null; - - try { - Session s = sessionFactory.getCurrentSession(); - if ( s.contains(obj)) { - return obj; - } else { - return (T) s.merge(obj); - } - } catch (HibernateException e) { - logExceptionAndTerminateSession(e); - return null; - } - } - - public int executeUpdate(String hql, Map params) - throws QueryException { - if (!checkSession()) { - return -1; - } - - try { - Session s = sessionFactory.getCurrentSession(); - Query query = s.createQuery(hql); - if (params != null) { - for (String param : params.keySet()) { - query.setParameter(param, params.get(param)); - } - } - - return query.executeUpdate(); - - } catch (QueryException e) { - logExceptionAndTerminateSession(e); - throw e; - } catch (HibernateException e) { - logExceptionAndTerminateSession(e); - return -1; - } catch (ClassCastException e) { - // Throw a QueryException instead of forwarding the ClassCastException - // it's more explicit - QueryException ebis = new QueryException( - "Invalid HQL query parameter type: " + e.getMessage(), e); - logExceptionAndTerminateSession(ebis); - throw ebis; - } - } + } @Override public boolean startUp() { @@ -810,6 +308,72 @@ public void setInitParams(BundleContext bc, Logger l) { this.bc = bc; this.logger = l; } + + @Override + public DBSessionManager getSessionManager() { + return sessionManager; + } + + @Override + public QueryInterface getQueryInterface() { + return getQueryInterface(QueryInterface.class); + } + + @SuppressWarnings("unchecked") + @Override + public T getQueryInterface(Class queryInterfaceType) { + if (!queryInterfaces.containsKey(queryInterfaceType)) { + if (!queryInterfaceFactories.containsKey(queryInterfaceType)) { + logger.error("Requesting QueryInterface of unknown type: " + queryInterfaceType.getName()); + return null; + } + + try { + // Lazy initialization of QueryInterfaces by using a factory pattern + QueryInterfaceFactory factory = (QueryInterfaceFactory) + queryInterfaceFactories.get(queryInterfaceType).newInstance(); + T qi = factory.build(this, sessionFactory, sessionValidation); + + queryInterfaces.put(queryInterfaceType, qi); + } catch (InstantiationException | IllegalAccessException e) { + logger.error("Failed to instantiate QueryInterface: ", e); + e.printStackTrace(); + return null; + } + } + + return (T) queryInterfaces.get(queryInterfaceType); + } + + @Override + public void registerQueryInterface(Class queryInterfaceType, + Class> factoryType) { + // Override any existing interface + if (queryInterfaces.containsKey(queryInterfaceType)) + queryInterfaces.remove(queryInterfaceType); + + queryInterfaceFactories.put(queryInterfaceType, factoryType); + } + + /** + * Prepare the DB service for testing by injecting a custom SessionFactory. + * Note: this should NOT be used in production code. + * + * @param s a custom SessionFactory object + * @param setInitialised true if the DBServiceImpl should be considered initialised + * @param l the logger to use for the DB service + */ + public void prepareForTest(SessionFactory s, boolean setInitialised, Logger l) { + this.sessionFactory = s; + this.logger = l; + + DBSessionManagerImpl ssm = new DBSessionManagerImpl(sessionFactory, logger, isInitialised); + this.sessionManager = ssm; + this.sessionValidation = ssm; + preloadFactories(); + + isInitialised.set(setInitialised); + } } //vi: ai nosi sw=4 ts=4 expandtab diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/db/DBSessionManagerImpl.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/db/DBSessionManagerImpl.java new file mode 100644 index 000000000..02320db46 --- /dev/null +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/db/DBSessionManagerImpl.java @@ -0,0 +1,226 @@ +package eu.sqooss.impl.service.db; + +import java.sql.SQLException; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.hibernate.HibernateException; +import org.hibernate.JDBCException; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import eu.sqooss.service.db.DAObject; +import eu.sqooss.service.db.DBSessionManager; +import eu.sqooss.service.db.DBSessionValidation; +import eu.sqooss.service.logging.Logger; + +/** + * Default implementation of the DBSessionManager and DBSessionValidation interfaces + * based on the Hibernate framework. + */ +public class DBSessionManagerImpl implements DBSessionManager, DBSessionValidation { + + private AtomicBoolean isInitialised = null; + private Logger logger = null; + private SessionFactory sessionFactory = null; + + public DBSessionManagerImpl(SessionFactory factory, Logger logger, AtomicBoolean isInit) { + this.sessionFactory = factory; + this.logger = logger; + this.isInitialised = isInit; + } + + @Override + public boolean startDBSession() { + // Boot time check + if (isInitialised.get() == false) { + return false; + } + + if (isDBSessionActive()) { + logger.debug("startDBSession() - a session was already started for that thread"); + return true; + } + + Session s = null; + try { + s = sessionFactory.getCurrentSession(); + // logger.debug("startDBSession: " + s + "[hashcode=" + s.hashCode() + // + ",open=" + s.isOpen() + "]"); + s.beginTransaction(); + } catch (HibernateException e) { + logger.error("startDBSession() - error while initializing session: " + + e.getMessage()); + if (s != null) { + try { + s.close(); + } catch (HibernateException e1) { + } + } + return false; + } + return true; + } + + @Override + public boolean commitDBSession() { + if ( !checkSession() ) + return false; + + Session s = null; + try { + s = sessionFactory.getCurrentSession(); + //logger.debug("commitDBSession: " + s + "[hashcode=" + s.hashCode() + ",open=" + s.isOpen() + "]"); + s.getTransaction().commit(); + } catch (HibernateException e) { + logger.error("commitDBSession() - error while committing transaction: " + e.getMessage()); + if ( s != null ) { + // The docs say to do so + try { + s.getTransaction().rollback(); + } catch (HibernateException e1) { + try { + s.close(); + } catch (HibernateException e2) { + } + } + } + return false; + } + return true; + } + + @Override + public boolean rollbackDBSession() { + if ( !checkSession() ) + return false; + + Session s = null; + try { + s = sessionFactory.getCurrentSession(); + s.getTransaction().rollback(); + } catch (HibernateException e) { + logger.error("commitDBSession() - error while rolling back transaction: " + e.getMessage()); + if ( s != null ) { + try { + s.close(); + } catch (HibernateException e1) { + } + } + return false; + } + return true; + } + + @Override + public boolean flushDBSession() { + if ( !checkSession() ) + return false; + + Session s = null; + try { + s = sessionFactory.getCurrentSession(); + s.flush(); + s.clear(); + } catch (HibernateException e) { + logger.error("flushDBSession() - error while flushing session: " + e.getMessage()); + if ( s != null ) { + try { + s.close(); + } catch (HibernateException e1) { + } + } + return false; + } + return true; + } + + @Override + public boolean isDBSessionActive() { + //Boot time check + if(isInitialised.get() == false) { + return false; + } + + Session s = null; + try { + s = sessionFactory.getCurrentSession(); + return s.getTransaction() != null && s.getTransaction().isActive(); + } catch (HibernateException e) { + logger.error("isDBSessionActive() - error while checking session status: " + e.getMessage()); + if ( s != null ) { + try { + s.close(); + } catch (HibernateException e1) { + } + } + return false; + } + } + + @Override + public T attachObjectToDBSession(T obj) { + if( !checkSession() ) + return null; + + try { + Session s = sessionFactory.getCurrentSession(); + if ( s.contains(obj)) { + return obj; + } else { + return (T) s.merge(obj); + } + } catch (HibernateException e) { + logExceptionAndTerminateSession(e); + return null; + } + } + + @Override + public boolean checkSession() { + if ( !isDBSessionActive() ) { + logger.warn("Trying to call a DBService method without an active session"); + try { + throw new Exception("No active session."); + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + return true; + } + + @Override + public void logExceptionAndTerminateSession( Exception e ) { + if ( e instanceof JDBCException ) { + JDBCException jdbce = (JDBCException) e; + logSQLException(jdbce.getSQLException()); + } + logger.warn("Exception caught during database session: " + e.getMessage() + + ". Rolling back current transaction and terminating session..."); + e.printStackTrace(); + Session s = null; + try { + s = sessionFactory.getCurrentSession(); + s.getTransaction().rollback(); + } catch (HibernateException e1) { + logger.error("Error while rolling back failed transaction :" + e1.getMessage()); + if ( s != null ) { + try { + s.close(); + } catch ( HibernateException e2) {} + } + } + + } + + @Override + public void logSQLException(SQLException e) { + + while (e != null) { + String message = String.format("SQLException: SQL State:%s, Error Code:%d, Message:%s", + e.getSQLState(), e.getErrorCode(), e.getMessage()); + logger.warn(message); + e = e.getNextException(); + } + } +} diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/db/HQLQueryInterfaceImpl.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/db/HQLQueryInterfaceImpl.java new file mode 100644 index 000000000..db997d9f2 --- /dev/null +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/db/HQLQueryInterfaceImpl.java @@ -0,0 +1,273 @@ +package eu.sqooss.impl.service.db; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.hibernate.HibernateException; +import org.hibernate.LockMode; +import org.hibernate.Query; +import org.hibernate.QueryException; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import eu.sqooss.service.db.DAObject; +import eu.sqooss.service.db.DBService; +import eu.sqooss.service.db.DBSessionManager; +import eu.sqooss.service.db.DBSessionValidation; +import eu.sqooss.service.db.HQLQueryInterface; +import eu.sqooss.service.db.QueryInterfaceFactory; +import eu.sqooss.service.logging.Logger; + +/** + * Default implementation of the doHQL functions and standard query functions. + */ +public class HQLQueryInterfaceImpl implements HQLQueryInterface { + + private SessionFactory sessionFactory; + private DBSessionManager sessionManager; + private DBSessionValidation sessionValidation; + private Logger logger; + + public HQLQueryInterfaceImpl(DBSessionManager sessionManager, DBSessionValidation sessionValidation, + SessionFactory sessionFactory, Logger logger) { + this.sessionManager = sessionManager; + this.sessionValidation = sessionValidation; + this.sessionFactory = sessionFactory; + this.logger = logger; + } + + public T findObjectById(Class daoClass, long id) { + return doFindObjectById(daoClass, id, false); + } + + public T findObjectByIdForUpdate(Class daoClass, long id) { + return doFindObjectById(daoClass, id, true); + } + + @SuppressWarnings("unchecked") + private T doFindObjectById(Class daoClass, long id, boolean useLock) { + if ( !sessionValidation.checkSession() ) + return null; + + try { + Session s = sessionFactory.getCurrentSession(); + return (T) (useLock ? s.get(daoClass, id, LockMode.UPGRADE) : s.get(daoClass, id)); + } catch (HibernateException e) { + sessionValidation.logExceptionAndTerminateSession(e); + return null; + } + } + + public List findObjectsByProperties(Class daoClass, Map properties) { + return doFindObjectsByProperties(daoClass, properties, false); + } + + public List findObjectsByPropertiesForUpdate(Class daoClass, Map properties) { + return doFindObjectsByProperties(daoClass, properties, true); + } + + @SuppressWarnings("unchecked") + private List doFindObjectsByProperties(Class daoClass, Map properties, boolean useLock) { + if( !sessionValidation.checkSession() ) + return Collections.emptyList(); + + // TODO maybe check that the properties are valid (e.g. with java.bean.PropertyDescriptor) + + Map parameterMap = new HashMap(); + StringBuffer whereClause = new StringBuffer(); + for (String key : properties.keySet()) { + whereClause.append( whereClause.length() == 0 ? " where " : " and " ); + // We use "foo" as the name of the object + whereClause.append("foo" + "." + key + "=:_" + key ); + parameterMap.put( "_" + key, properties.get(key) ); + } + try { + // We use "foo" as the name of the object + return (List) doHQL( "from " + daoClass.getName() + " as foo " + whereClause, parameterMap, useLock ); + } catch (QueryException e) { + logger.warn("findObjectsByProperties(): invalid properties map. Restarting session..."); + // Automatically restart a session + // (just be careful with preloaded DAOs that become detached) + sessionManager.startDBSession(); + return Collections.emptyList(); + } + } + + public boolean addRecord(DAObject record) { + ArrayList tmpList = new ArrayList(1); + tmpList.add(record); + return addRecords(tmpList); + } + + public boolean deleteRecord(DAObject record) { + ArrayList tmpList = new ArrayList(1); + tmpList.add(record); + return deleteRecords(tmpList); + } + + public boolean addRecords(List records) { + if( !sessionValidation.checkSession() ) + return false; + + DAObject lastRecord = null; + try { + Session s = sessionFactory.getCurrentSession(); + for (DAObject record : records) { + lastRecord = record; + s.save(record); + } + lastRecord = null; + s.flush(); + return true; + } catch (HibernateException e) { + if (lastRecord != null) { + logger.error("Failed to add object " + + "[" + lastRecord.getClass().getName() + ":" + lastRecord.getId() + "]" + + " to the database: " + e.getMessage()); + } + sessionValidation.logExceptionAndTerminateSession(e); + return false; + } + } + + public boolean deleteRecords(List records) { + if( !sessionValidation.checkSession() ) + return false; + + DAObject lastRecord = null; + try { + Session s = sessionFactory.getCurrentSession(); + for (DAObject record : records) { + lastRecord = record; + s.delete(record); + } + lastRecord = null; + s.flush(); + return true; + } catch (HibernateException e) { + if (lastRecord != null) { + logger.error("Failed to remove object " + + "[" + lastRecord.getClass().getName() + ":" + lastRecord.getId() + "]" + + " from the database: " + e.getMessage()); + } + sessionValidation.logExceptionAndTerminateSession(e); + return false; + } + } + + public List doHQL(String hql) + throws QueryException { + return doHQL(hql, null, null, false, -1, -1); + } + + public List doHQL(String hql, Map params) + throws QueryException { + return doHQL(hql, params, null, false, -1, -1); + } + + public List doHQL(String hql, Map params, int limit) + throws QueryException { + return doHQL(hql, params, null, false, 0, limit); + } + + public List doHQL(String hql, Map params, boolean lockForUpdate) + throws QueryException { + return doHQL(hql, params, null, lockForUpdate, -1, -1); + } + + public List doHQL(String hql, Map params, + Map collectionParams) + throws QueryException { + return doHQL(hql, params, collectionParams, false, -1, -1); + } + + public List doHQL(String hql, Map params, + Map collectionParams, boolean lockForUpdate, int start, int limit) + throws QueryException { + if ( !sessionValidation.checkSession() ) { + return Collections.emptyList(); + } + try { + Session s = sessionFactory.getCurrentSession(); + Query query = s.createQuery(hql); + if (params != null) { + for ( String param : params.keySet() ) { + query.setParameter(param, params.get(param)); + } + } + if (collectionParams != null) { + for ( String param : collectionParams.keySet() ) { + query.setParameterList(param, collectionParams.get(param)); + } + } + if (lockForUpdate) { + query.setLockMode("foo", LockMode.PESSIMISTIC_WRITE); + } + if ( start >= 0 && limit >= 0 ) { + query.setFirstResult(start); + query.setMaxResults(limit); + } + return query.list(); + } catch ( QueryException e ) { + sessionValidation.logExceptionAndTerminateSession(e); + throw e; + } catch( HibernateException e ) { + sessionValidation.logExceptionAndTerminateSession(e); + return Collections.emptyList(); + } catch (ClassCastException e) { + // Throw a QueryException instead of forwarding the ClassCastException + // it's more explicit + QueryException ebis = new QueryException("Invalid HQL query parameter type: " + + e.getMessage(), e); + sessionValidation.logExceptionAndTerminateSession(ebis); + throw ebis; + } + + } + + public int executeUpdate(String hql, Map params) throws QueryException { + if (!sessionValidation.checkSession()) { + return -1; + } + + try { + Session s = sessionFactory.getCurrentSession(); + Query query = s.createQuery(hql); + if (params != null) { + for (String param : params.keySet()) { + query.setParameter(param, params.get(param)); + } + } + + return query.executeUpdate(); + + } catch (QueryException e) { + sessionValidation.logExceptionAndTerminateSession(e); + throw e; + } catch (HibernateException e) { + sessionValidation.logExceptionAndTerminateSession(e); + return -1; + } catch (ClassCastException e) { + // Throw a QueryException instead of forwarding the ClassCastException + // it's more explicit + QueryException ebis = new QueryException( + "Invalid HQL query parameter type: " + e.getMessage(), e); + sessionValidation.logExceptionAndTerminateSession(ebis); + throw ebis; + } + } + + public static class Factory implements QueryInterfaceFactory { + + @Override + public HQLQueryInterface build(DBService dbService, SessionFactory sessionFactory, + DBSessionValidation sessionValidation) { + return new HQLQueryInterfaceImpl(dbService.getSessionManager(), + sessionValidation, sessionFactory, dbService.logger()); + } + } +} diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/db/SQLQueryInterfaceImpl.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/db/SQLQueryInterfaceImpl.java new file mode 100644 index 000000000..9ec935472 --- /dev/null +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/db/SQLQueryInterfaceImpl.java @@ -0,0 +1,181 @@ +package eu.sqooss.impl.service.db; + +import java.sql.SQLException; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.hibernate.HibernateException; +import org.hibernate.JDBCException; +import org.hibernate.Query; +import org.hibernate.QueryException; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import eu.sqooss.service.db.DAObject; +import eu.sqooss.service.db.DBService; +import eu.sqooss.service.db.DBSessionManager; +import eu.sqooss.service.db.DBSessionValidation; +import eu.sqooss.service.db.QueryInterface; +import eu.sqooss.service.db.QueryInterfaceFactory; +import eu.sqooss.service.db.SQLQueryInterface; + +/** + * Default implementation of the (deprecated) SQL queries. The standard queries + * specified by QueryInterface are not supported through SQL, so these functions + * are delegated to the QueryInterface instance provided by DBService. + */ +public class SQLQueryInterfaceImpl implements SQLQueryInterface { + + private DBService dbService; + private QueryInterface qi; + private DBSessionManager sessionManager; + private DBSessionValidation sessionValidation; + private SessionFactory sessionFactory; + + public SQLQueryInterfaceImpl(DBService dbService, DBSessionValidation sesVal, + SessionFactory sesFac) { + this.sessionManager = dbService.getSessionManager(); + this.sessionValidation = sesVal; + this.sessionFactory = sesFac; + this.dbService = dbService; + this.qi = null; + } + + @Override + @Deprecated + public List doSQL(String sql) throws SQLException { + return doSQL(sql, null); + } + + @Override + @Deprecated + public List doSQL(String sql, Map params) + throws SQLException, QueryException { + boolean autoSession = !sessionManager.isDBSessionActive(); + try { + Session s = sessionFactory.getCurrentSession(); + if (autoSession) { + s.beginTransaction(); + } + Query query = s.createSQLQuery(sql); + if ( params != null ) { + for ( String param : params.keySet() ) { + query.setParameter(param, params.get(param)); + } + } + List result = query.list(); + if (autoSession) { + s.getTransaction().commit(); + } + return result; + } catch ( JDBCException e ) { + sessionValidation.logExceptionAndTerminateSession(e); + throw e.getSQLException(); + } catch ( QueryException e ) { + sessionValidation.logExceptionAndTerminateSession(e); + throw e; + } catch( HibernateException e ) { + sessionValidation.logExceptionAndTerminateSession(e); + return Collections.emptyList(); + } + } + + @Override + @Deprecated + public int callProcedure(String procName, List args, + Map params) throws SQLException, QueryException { + boolean autoSession = !sessionManager.isDBSessionActive(); + StringBuilder sql = new StringBuilder("call " + procName + "("); + + for (String arg : args) { + sql.append(":").append(arg).append(","); + } + sql.deleteCharAt(sql.lastIndexOf(",")).append(")"); + + try { + Session s = sessionFactory.getCurrentSession(); + if (autoSession) { + s.beginTransaction(); + } + Query query = s.createSQLQuery(sql.toString()); + if (params != null) { + for (String param : params.keySet()) { + query.setParameter(param, params.get(param)); + } + } + int result = query.executeUpdate(); + if (autoSession) { + s.getTransaction().commit(); + } + return result; + } catch (JDBCException e) { + sessionValidation.logExceptionAndTerminateSession(e); + throw e.getSQLException(); + } catch (QueryException e) { + sessionValidation.logExceptionAndTerminateSession(e); + throw e; + } catch (HibernateException e) { + sessionValidation.logExceptionAndTerminateSession(e); + throw e; + } + } + + @Override + public T findObjectById(Class daoClass, long id) { + return getQI().findObjectById(daoClass, id); + } + + @Override + public T findObjectByIdForUpdate(Class daoClass, + long id) { + return getQI().findObjectByIdForUpdate(daoClass, id); + } + + @Override + public List findObjectsByProperties( + Class daoClass, Map properties) { + return getQI().findObjectsByProperties(daoClass, properties); + } + + @Override + public List findObjectsByPropertiesForUpdate( + Class daoClass, Map properties) { + return getQI().findObjectsByPropertiesForUpdate(daoClass, properties); + } + + @Override + public boolean addRecord(DAObject record) { + return getQI().addRecord(record); + } + + @Override + public boolean addRecords(List records) { + return getQI().addRecords(records); + } + + @Override + public boolean deleteRecord(DAObject record) { + return getQI().deleteRecord(record); + } + + @Override + public boolean deleteRecords(List records) { + return getQI().deleteRecords(records); + } + + private QueryInterface getQI() { + if (qi == null) + qi = dbService.getQueryInterface(); + return qi; + } + + public static class Factory implements QueryInterfaceFactory { + + @Override + public SQLQueryInterface build(DBService dbService, SessionFactory sessionFactory, + DBSessionValidation sessionValidation) { + return new SQLQueryInterfaceImpl(dbService, sessionValidation, sessionFactory); + } + } +} diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/fds/FDSServiceImpl.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/fds/FDSServiceImpl.java index e28fb7ea3..a96af47d2 100644 --- a/alitheia/core/src/main/java/eu/sqooss/impl/service/fds/FDSServiceImpl.java +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/fds/FDSServiceImpl.java @@ -393,7 +393,7 @@ private ProjectVersion cacheKeyProjectVersion(String key) { DBService dbs = AlitheiaCore.getInstance().getDBService(); Long id = Long.parseLong(key.split("|")[1]); - return dbs.findObjectById(ProjectVersion.class, id); + return dbs.getQueryInterface().findObjectById(ProjectVersion.class, id); } /** diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/fds/OnDiskCheckoutImpl.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/fds/OnDiskCheckoutImpl.java index 36087f5b8..b7c6f0d0a 100644 --- a/alitheia/core/src/main/java/eu/sqooss/impl/service/fds/OnDiskCheckoutImpl.java +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/fds/OnDiskCheckoutImpl.java @@ -122,7 +122,7 @@ public File getRoot() /** {@inheritDoc} */ public ProjectVersion getProjectVersion() { DBService dbs = AlitheiaCore.getInstance().getDBService(); - revision = dbs.attachObjectToDBSession(revision); + revision = dbs.getSessionManager().attachObjectToDBSession(revision); return revision; } diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/fds/TimelineImpl.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/fds/TimelineImpl.java index 8707e9348..064284033 100644 --- a/alitheia/core/src/main/java/eu/sqooss/impl/service/fds/TimelineImpl.java +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/fds/TimelineImpl.java @@ -46,6 +46,7 @@ import eu.sqooss.core.AlitheiaCore; import eu.sqooss.service.db.Bug; import eu.sqooss.service.db.DBService; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.MailMessage; import eu.sqooss.service.db.MailingList; import eu.sqooss.service.db.ProjectVersion; @@ -85,7 +86,7 @@ private SortedSet getScmTimeLine(Calendar from, Calendar to) { params.put("paramFrom", begin); params.put("paramProject", project); - List versions = (List) dbs.doHQL(query.toString(), params); + List versions = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query.toString(), params); for(ProjectVersion version : versions) { result.add( new RepositoryEvent(version.getTimestamp(), version) ); @@ -113,7 +114,7 @@ private SortedSet getMailTimeLine(Calendar from, Calendar to) if (lists != null) { for (MailingList list : lists) { params.put("paramList", list); - List messages = (List) dbs.doHQL(query.toString(), params); + List messages = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query.toString(), params); for (MailMessage message : messages) { result.add(new MailingListEvent( @@ -141,7 +142,7 @@ private SortedSet getBugTimeLine(Calendar from, Calendar to) { params.put("paramTo", end); params.put("paramFrom", begin); params.put("paramProject", project); - List bugs = (List) dbs.doHQL(query.toString(), params); + List bugs = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query.toString(), params); for (Bug bug : bugs) { result.add(new BugDBEvent(bug.getCreationTS().getTime(), bug)); diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/metricactivator/MetricActivatorImpl.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/metricactivator/MetricActivatorImpl.java index 4487e5202..0df5f78c7 100644 --- a/alitheia/core/src/main/java/eu/sqooss/impl/service/metricactivator/MetricActivatorImpl.java +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/metricactivator/MetricActivatorImpl.java @@ -37,6 +37,7 @@ import java.util.concurrent.atomic.AtomicLong; import eu.sqooss.service.abstractmetric.InvocationOrder; + import org.osgi.framework.BundleContext; import eu.sqooss.core.AlitheiaCore; @@ -51,6 +52,7 @@ import eu.sqooss.service.db.DBService; import eu.sqooss.service.db.EncapsulationUnit; import eu.sqooss.service.db.ExecutionUnit; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.MailMessage; import eu.sqooss.service.db.MailingList; import eu.sqooss.service.db.MailingListThread; @@ -132,7 +134,7 @@ public void syncMetrics(StoredProject sp, Class actType) { @Override public void syncMetrics(AlitheiaPlugin ap) { List lp = - (List) db.doHQL("from StoredProject"); + (List) db.getQueryInterface(HQLQueryInterface.class).doHQL("from StoredProject"); for(StoredProject sp : lp) { syncMetric(ap, sp); @@ -286,7 +288,7 @@ public long priority() { @Override protected void run() throws Exception { DBService dbs = AlitheiaCore.getInstance().getDBService(); - dbs.startDBSession(); + dbs.getSessionManager().startDBSession(); sp = DAObject.loadDAObyId(sp.getId(), StoredProject.class); PluginInfo mi = pa.getPluginInfo(m); Set> actTypes = mi.getActivationTypes(); @@ -364,7 +366,7 @@ protected void run() throws Exception { } } sched.enqueueNoDependencies(jobs); - dbs.commitDBSession(); + dbs.getSessionManager().commitDBSession(); } @Override diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/metricactivator/MetricActivatorJob.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/metricactivator/MetricActivatorJob.java index 8a8c923b4..592af556e 100644 --- a/alitheia/core/src/main/java/eu/sqooss/impl/service/metricactivator/MetricActivatorJob.java +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/metricactivator/MetricActivatorJob.java @@ -83,9 +83,9 @@ public long priority() { @Override protected void run() throws Exception { - dbs.startDBSession(); + dbs.getSessionManager().startDBSession(); metric.setJob(this); - DAObject obj = dbs.findObjectById(daoType, daoID); + DAObject obj = dbs.getQueryInterface().findObjectById(daoType, daoID); try { if (fastSync) { @@ -108,13 +108,13 @@ protected void run() throws Exception { } catch (AlreadyProcessingException ape) { logger.warn("DAO id " + daoID + " is locked, job has been " + "rescheduled"); - dbs.rollbackDBSession(); + dbs.getSessionManager().rollbackDBSession(); return; } catch (LockAcquisitionException lae) { - dbs.rollbackDBSession(); + dbs.getSessionManager().rollbackDBSession(); } - if (!dbs.commitDBSession()) { + if (!dbs.getSessionManager().commitDBSession()) { logger.warn("commit failed - restarting metric job"); restart(); } diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/pa/PAServiceImpl.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/pa/PAServiceImpl.java index 436496aba..379316c3c 100644 --- a/alitheia/core/src/main/java/eu/sqooss/impl/service/pa/PAServiceImpl.java +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/pa/PAServiceImpl.java @@ -397,7 +397,7 @@ public void serviceChanged(ServiceEvent event) { // Get a reference to the affected service ServiceReference affectedService = event.getServiceReference(); - sobjDB.startDBSession(); + sobjDB.getSessionManager().startDBSession(); // Find out what happened to the service switch (event.getType()) { @@ -415,7 +415,7 @@ public void serviceChanged(ServiceEvent event) { } // Close the DB session - sobjDB.commitDBSession(); + sobjDB.getSessionManager().commitDBSession(); } /* ===[ Implementation of the PluginAdmin interface ]===================== */ @@ -646,7 +646,7 @@ protected void run() throws Exception { try { DBService dbs = AlitheiaCore.getInstance().getDBService(); - dbs.startDBSession(); + dbs.getSessionManager().startDBSession(); // Get the metric plug-in's service ServiceReference srefPlugin = getPluginService(serviceID); @@ -674,7 +674,7 @@ protected void run() throws Exception { pluginInfo.getHashcode(), pluginInfo); } } - dbs.commitDBSession(); + dbs.getSessionManager().commitDBSession(); } catch (Exception e) { logger.warn(UNINSTALL_FAILED, e); } diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/rest/ResteasyServlet.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/rest/ResteasyServlet.java index cbb414ca1..114dcc0ae 100644 --- a/alitheia/core/src/main/java/eu/sqooss/impl/service/rest/ResteasyServlet.java +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/rest/ResteasyServlet.java @@ -51,12 +51,12 @@ protected void service(HttpServletRequest httpServletRequest, DBService db = AlitheiaCore.getInstance().getDBService(); - if (!db.isDBSessionActive()) - db.startDBSession(); + if (!db.getSessionManager().isDBSessionActive()) + db.getSessionManager().startDBSession(); super.service(httpServletRequest, httpServletResponse); - if (db.isDBSessionActive()) - db.commitDBSession(); + if (db.getSessionManager().isDBSessionActive()) + db.getSessionManager().commitDBSession(); } } \ No newline at end of file diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/tds/TDSServiceImpl.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/tds/TDSServiceImpl.java index 9635be25d..b51ae556f 100644 --- a/alitheia/core/src/main/java/eu/sqooss/impl/service/tds/TDSServiceImpl.java +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/tds/TDSServiceImpl.java @@ -146,13 +146,13 @@ private void stuffer() { logger.info("TDS is now running the stuffer."); DBService db = AlitheiaCore.getInstance().getDBService(); - if (db != null && db.startDBSession()) { + if (db != null && db.getSessionManager().startDBSession()) { for (StoredProject p : ClusterNode.thisNode().getProjects()) { addAccessor(p.getId(), p.getName(), p.getBtsUrl(), p.getMailUrl(), p.getScmUrl()); } - db.commitDBSession(); + db.getSessionManager().commitDBSession(); } logger.info("TDS Stuffer is finished."); diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/updater/OhlohUpdater.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/updater/OhlohUpdater.java index 6d7016203..f02c14ba2 100644 --- a/alitheia/core/src/main/java/eu/sqooss/impl/service/updater/OhlohUpdater.java +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/updater/OhlohUpdater.java @@ -106,7 +106,7 @@ public boolean accept(File dir, String name) { for (String file : files) { - dbs.startDBSession(); + dbs.getSessionManager().startDBSession(); SAXReader reader = new SAXReader(false); Document document = null; @@ -160,10 +160,10 @@ public InputSource resolveEntity(String publicId, String systemId) { od.setUname(uname); } else { od = new OhlohDeveloper(uname, mailhash, id); - dbs.addRecord(od); + dbs.getQueryInterface().addRecord(od); } } - dbs.commitDBSession(); + dbs.getSessionManager().commitDBSession(); } } diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/updater/UpdaterServiceImpl.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/updater/UpdaterServiceImpl.java index 75148b1fe..c63b34732 100644 --- a/alitheia/core/src/main/java/eu/sqooss/impl/service/updater/UpdaterServiceImpl.java +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/updater/UpdaterServiceImpl.java @@ -571,8 +571,8 @@ public synchronized void jobStateChanged(Job j, State newState) { return; } - if (!dbs.isDBSessionActive()) - dbs.startDBSession(); + if (!dbs.getSessionManager().isDBSessionActive()) + dbs.getSessionManager().startDBSession(); StoredProject sp = StoredProject.loadDAObyId(projectId, StoredProject.class); removeUpdater(sp, ut); @@ -580,7 +580,7 @@ public synchronized void jobStateChanged(Job j, State newState) { logger.warn(ut + " updater job for project " + sp + " did not finish properly"); } - dbs.commitDBSession(); + dbs.getSessionManager().commitDBSession(); } } diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/webadmin/AdminServlet.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/webadmin/AdminServlet.java index bde9ad0e3..ea1b42fba 100644 --- a/alitheia/core/src/main/java/eu/sqooss/impl/service/webadmin/AdminServlet.java +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/webadmin/AdminServlet.java @@ -157,8 +157,8 @@ private void addStaticContent(String path, String type) { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - if (!db.isDBSessionActive()) { - db.startDBSession(); + if (!db.getSessionManager().isDBSessionActive()) { + db.getSessionManager().startDBSession(); } try { @@ -199,8 +199,8 @@ else if ((query != null) && (dynamicContentMap.containsKey(query))) { logger.warn("Got a NPE while rendering a page.",e); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } finally { - if (db.isDBSessionActive()) { - db.commitDBSession(); + if (db.getSessionManager().isDBSessionActive()) { + db.getSessionManager().commitDBSession(); } } } @@ -208,8 +208,8 @@ else if ((query != null) && (dynamicContentMap.containsKey(query))) { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - if (!db.isDBSessionActive()) { - db.startDBSession(); + if (!db.getSessionManager().isDBSessionActive()) { + db.getSessionManager().startDBSession(); } try { @@ -236,8 +236,8 @@ protected void doPost(HttpServletRequest request, logger.warn("Got a NPE while handling POST data."); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } finally { - if (db.isDBSessionActive()) { - db.commitDBSession(); + if (db.getSessionManager().isDBSessionActive()) { + db.getSessionManager().commitDBSession(); } } } diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/webadmin/ProjectDeleteJob.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/webadmin/ProjectDeleteJob.java index dcdda445d..31491f7ee 100644 --- a/alitheia/core/src/main/java/eu/sqooss/impl/service/webadmin/ProjectDeleteJob.java +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/webadmin/ProjectDeleteJob.java @@ -39,6 +39,7 @@ import eu.sqooss.core.AlitheiaCore; import eu.sqooss.service.abstractmetric.AlitheiaPlugin; import eu.sqooss.service.db.DBService; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.Plugin; import eu.sqooss.service.db.ProjectVersion; import eu.sqooss.service.db.StoredProject; @@ -65,17 +66,17 @@ public long priority() { protected void run() throws Exception { DBService dbs = core.getDBService(); - if (!dbs.isDBSessionActive()) { - dbs.startDBSession(); + if (!dbs.getSessionManager().isDBSessionActive()) { + dbs.getSessionManager().startDBSession(); } - sp = dbs.attachObjectToDBSession(sp); + sp = dbs.getSessionManager().attachObjectToDBSession(sp); // Delete any associated invocation rules first HashMap properties = new HashMap(); properties.put("project", sp); //Cleanup plugin results - List ps = (List) dbs.doHQL("from Plugin"); + List ps = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL("from Plugin"); for (Plugin p : ps ) { AlitheiaPlugin ap = core.getPluginAdmin().getPlugin(core.getPluginAdmin().getPluginInfo(p.getHashcode())); @@ -104,16 +105,16 @@ protected void run() throws Exception { //Delete the project's config options List confParams = StoredProjectConfig.fromProject(sp); if (!confParams.isEmpty()) { - success &= dbs.deleteRecords(confParams); + success &= dbs.getQueryInterface().deleteRecords(confParams); } // Delete the selected project - success &= dbs.deleteRecord(sp); + success &= dbs.getQueryInterface().deleteRecord(sp); if (success) { - dbs.commitDBSession(); + dbs.getSessionManager().commitDBSession(); } else { - dbs.rollbackDBSession(); + dbs.getSessionManager().rollbackDBSession(); } } diff --git a/alitheia/core/src/main/java/eu/sqooss/impl/service/webadmin/ProjectsView.java b/alitheia/core/src/main/java/eu/sqooss/impl/service/webadmin/ProjectsView.java index 2975b36d6..957122eea 100644 --- a/alitheia/core/src/main/java/eu/sqooss/impl/service/webadmin/ProjectsView.java +++ b/alitheia/core/src/main/java/eu/sqooss/impl/service/webadmin/ProjectsView.java @@ -135,7 +135,7 @@ public static String render(HttpServletRequest req) { // Retrieve the selected project's DAO (if any) reqValProjectId = fromString(req.getParameter(REQ_PAR_PROJECT_ID)); if (reqValProjectId != null) { - selProject = sobjDB.findObjectById( + selProject = sobjDB.getQueryInterface().findObjectById( StoredProject.class, reqValProjectId); } diff --git a/alitheia/core/src/main/java/eu/sqooss/rest/api/MetricsResource.java b/alitheia/core/src/main/java/eu/sqooss/rest/api/MetricsResource.java index a3416b5c7..85e1e5d81 100644 --- a/alitheia/core/src/main/java/eu/sqooss/rest/api/MetricsResource.java +++ b/alitheia/core/src/main/java/eu/sqooss/rest/api/MetricsResource.java @@ -45,6 +45,7 @@ import eu.sqooss.service.abstractmetric.Result; import eu.sqooss.service.db.DAObject; import eu.sqooss.service.db.DBService; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.Metric; import eu.sqooss.service.db.MetricType; import eu.sqooss.service.db.MetricType.Type; @@ -64,7 +65,7 @@ public MetricsResource() {} public List getMetrics() { DBService db = AlitheiaCore.getInstance().getDBService(); String q = " from Metric"; - List sp = (List) db.doHQL(q); + List sp = (List) db.getQueryInterface(HQLQueryInterface.class).doHQL(q); return sp; } @@ -74,7 +75,7 @@ public List getMetrics() { public List getMetricTypes() { DBService db = AlitheiaCore.getInstance().getDBService(); String q = " from MetricType"; - List sp = (List) db.doHQL(q); + List sp = (List) db.getQueryInterface(HQLQueryInterface.class).doHQL(q); return sp; } diff --git a/alitheia/core/src/main/java/eu/sqooss/rest/api/StoredProjectResource.java b/alitheia/core/src/main/java/eu/sqooss/rest/api/StoredProjectResource.java index 6c5cf004b..4fcb5fc5f 100644 --- a/alitheia/core/src/main/java/eu/sqooss/rest/api/StoredProjectResource.java +++ b/alitheia/core/src/main/java/eu/sqooss/rest/api/StoredProjectResource.java @@ -48,6 +48,7 @@ import eu.sqooss.service.db.DAObject; import eu.sqooss.service.db.DBService; import eu.sqooss.service.db.Directory; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.Metric; import eu.sqooss.service.db.ProjectFile; import eu.sqooss.service.db.ProjectVersion; @@ -64,7 +65,7 @@ public StoredProjectResource() {} public List getProjects() { DBService db = AlitheiaCore.getInstance().getDBService(); String q = " from StoredProject"; - List sp = (List) db.doHQL(q); + List sp = (List) db.getQueryInterface(HQLQueryInterface.class).doHQL(q); return sp; } diff --git a/alitheia/core/src/main/java/eu/sqooss/service/abstractmetric/AbstractMetric.java b/alitheia/core/src/main/java/eu/sqooss/service/abstractmetric/AbstractMetric.java index 73df1f9fb..aa7473d4f 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/abstractmetric/AbstractMetric.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/abstractmetric/AbstractMetric.java @@ -60,6 +60,7 @@ import eu.sqooss.service.db.DBService; import eu.sqooss.service.db.EncapsulationUnitMeasurement; import eu.sqooss.service.db.ExecutionUnitMeasurement; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.MailMessageMeasurement; import eu.sqooss.service.db.MailingListThreadMeasurement; import eu.sqooss.service.db.Metric; @@ -70,6 +71,7 @@ import eu.sqooss.service.db.PluginConfiguration; import eu.sqooss.service.db.ProjectFileMeasurement; import eu.sqooss.service.db.ProjectVersionMeasurement; +import eu.sqooss.service.db.QueryInterface; import eu.sqooss.service.db.StoredProject; import eu.sqooss.service.db.StoredProjectMeasurement; import eu.sqooss.service.db.MetricType.Type; @@ -98,6 +100,7 @@ public abstract class AbstractMetric implements AlitheiaPlugin { /** Reference to the DB service, not to be passed to metric jobs */ protected DBService db; + protected QueryInterface qi; /** * Reference to the plugin administrator service, not to be passed to @@ -231,6 +234,8 @@ protected AbstractMetric(BundleContext bc) { if(db == null) log.error("Could not get a reference to the DB service"); + else + qi = db.getQueryInterface(); pa = AlitheiaCore.getInstance().getPluginAdmin(); @@ -561,7 +566,7 @@ public List getAllSupportedMetrics() { Map params = new HashMap(); params.put("plugin", Plugin.getPluginByHashcode(getUniqueKey())); - return (List)db.doHQL(qry, params); + return (List)db.getQueryInterface(HQLQueryInterface.class).doHQL(qry, params); } /** {@inheritDoc} */ @@ -598,7 +603,7 @@ public boolean install() { HashMap h = new HashMap(); h.put("name", this.getName()); - List plugins = db.findObjectsByProperties(Plugin.class, h); + List plugins = qi.findObjectsByProperties(Plugin.class, h); if (!plugins.isEmpty()) { log.warn("A plugin with name <" + getName() @@ -614,7 +619,7 @@ public boolean install() { p.setVersion(getVersion()); p.setActive(true); p.setHashcode(getUniqueKey()); - boolean result = db.addRecord(p); + boolean result = qi.addRecord(p); //3. Add the metrics for (String mnem :metrics.keySet()) { @@ -623,13 +628,13 @@ public boolean install() { MetricType newType = MetricType.getMetricType(type); if (newType == null) { newType = new MetricType(type); - db.addRecord(newType); + qi.addRecord(newType); m.setMetricType(newType); } m.setMetricType(newType); m.setPlugin(p); - db.addRecord(m); + qi.addRecord(m); } return result; @@ -642,7 +647,7 @@ public boolean install() { */ public boolean remove() { Plugin p = Plugin.getPluginByHashcode(getUniqueKey()); - return db.deleteRecord(p); + return qi.deleteRecord(p); } /** @@ -844,12 +849,12 @@ public PluginConfiguration getConfigurationOption(String config) { */ protected List getResult(DAObject o, Class clazz, Metric m, Result.ResultType type) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + //DBService dbs = AlitheiaCore.getInstance().getDBService(); Map props = new HashMap(); props.put(resultFieldNames.get(clazz), o); props.put("metric", m); - List resultat = dbs.findObjectsByProperties(clazz, props); + List resultat = qi.findObjectsByProperties(clazz, props); if (resultat.isEmpty()) return Collections.EMPTY_LIST; @@ -929,7 +934,7 @@ public Map> getObjectIdsToSync(StoredProject sp throw new MetricActivationException("Metric synchronisation with GENERIC objects not implemented"); } - List objectIds = (List) db.doHQL(q, params); + List objectIds = (List) db.getQueryInterface(HQLQueryInterface.class).doHQL(q, params); TreeSet ids = new TreeSet(); ids.addAll(objectIds); IDs.put(MetricType.fromActivator(at), ids); diff --git a/alitheia/core/src/main/java/eu/sqooss/service/admin/actions/AddProject.java b/alitheia/core/src/main/java/eu/sqooss/service/admin/actions/AddProject.java index 16dbe459b..76ba4f631 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/admin/actions/AddProject.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/admin/actions/AddProject.java @@ -12,6 +12,7 @@ import eu.sqooss.service.db.ConfigOption; import eu.sqooss.service.db.ConfigurationOption; import eu.sqooss.service.db.DBService; +import eu.sqooss.service.db.QueryInterface; import eu.sqooss.service.db.StoredProject; import eu.sqooss.service.tds.BTSAccessor; import eu.sqooss.service.tds.InvalidAccessorException; @@ -79,7 +80,7 @@ public String descr() { public void execute() throws Exception { super.execute(); String name = null, bts = null, scm = null, mail = null, contact = null, web = null; - DBService db = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); TDSService tds = AlitheiaCore.getInstance().getTDSService(); if (args.containsKey("dir")) { @@ -122,7 +123,7 @@ public void execute() throws Exception { // 1. Duplicate project HashMap props = new HashMap(); props.put("name", name); - if (!db.findObjectsByProperties(StoredProject.class, props).isEmpty()) { + if (!qi.findObjectsByProperties(StoredProject.class, props).isEmpty()) { error("project.exists", "A project with the same name already exists"); } @@ -179,7 +180,7 @@ public void execute() throws Exception { StoredProject sp = new StoredProject(name); //The project is now ready to be added - db.addRecord(sp); + qi.addRecord(sp); //Store all known properties to the database for (ConfigOption co : ConfigOption.values()) { diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/Branch.java b/alitheia/core/src/main/java/eu/sqooss/service/db/Branch.java index a58576cd3..4169eb5b1 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/Branch.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/Branch.java @@ -147,20 +147,20 @@ public void setBranchOutgoing(Set branchOutgoing) { } public static Branch fromName(StoredProject sp, String name, boolean create) { - DBService db = AlitheiaCore.getInstance().getDBService(); + HQLQueryInterface hqi = AlitheiaCore.getInstance().getDBService().getQueryInterface(HQLQueryInterface.class); Map params = new HashMap(); params.put("name", name); params.put("project", sp); - List branches = (List)db.doHQL(qBranchByName, params); + List branches = (List)hqi.doHQL(qBranchByName, params); if (branches.isEmpty()) { if (!create) return null; Branch b = new Branch(); b.setProject(sp); b.setName(name); - db.addRecord(b); + hqi.addRecord(b); return fromName(sp, name, false); } @@ -168,12 +168,12 @@ public static Branch fromName(StoredProject sp, String name, boolean create) { } public static String suggestName(StoredProject sp) { - DBService db = AlitheiaCore.getInstance().getDBService(); + HQLQueryInterface hqi = AlitheiaCore.getInstance().getDBService().getQueryInterface(HQLQueryInterface.class); Map params = new HashMap(); params.put("project", sp); - List ids = (List) db.doHQL(qNextSequence, params); + List ids = (List) hqi.doHQL(qNextSequence, params); if (ids.isEmpty()) return "1"; else diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/Bug.java b/alitheia/core/src/main/java/eu/sqooss/service/db/Bug.java index 78b67dad8..722d34bef 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/Bug.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/Bug.java @@ -253,7 +253,7 @@ public static Bug getLastUpdate(StoredProject sp) { Map params = new HashMap(); params.put(paramStoredProject, sp); - List buglist = (List) dbs.doHQL(query, params,1); + List buglist = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, params,1); if (buglist.isEmpty()) return null; @@ -283,7 +283,7 @@ public List getAllReportComments() { params.put(paramBugID, bugID); params.put(paramStoredProject, project); - return (List) dbs.doHQL(query, params); + return (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, params); } /** @@ -305,7 +305,7 @@ public static Bug getBug(String bugID, StoredProject sp) { params.put(paramBugID, bugID); params.put(paramStoredProject, sp); - List bug = (List) dbs.doHQL(query, params, 1); + List bug = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, params, 1); if (bug.isEmpty()) return null; diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/BugPriority.java b/alitheia/core/src/main/java/eu/sqooss/service/db/BugPriority.java index 1dc1419c2..35bd9b0a2 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/BugPriority.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/BugPriority.java @@ -160,12 +160,12 @@ public static BugPriority getBugPriority(Priority s) { * while modifying the DB. */ public static BugPriority getBugPriority(String priority, boolean create) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map params = new HashMap(); params.put("priority", priority); - List st = dbs.findObjectsByProperties(BugPriority.class, + List st = qi.findObjectsByProperties(BugPriority.class, params); if (!st.isEmpty()) { @@ -183,7 +183,7 @@ public static BugPriority getBugPriority(String priority, boolean create) { BugPriority bs = new BugPriority(); bs.setpriority(priority); - if (!dbs.addRecord(bs)) + if (!qi.addRecord(bs)) return null; return bs; diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/BugResolution.java b/alitheia/core/src/main/java/eu/sqooss/service/db/BugResolution.java index 1907e44a9..5b44b2d20 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/BugResolution.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/BugResolution.java @@ -163,12 +163,12 @@ public static BugResolution getBugResolution(BugResolution.Resolution s) { * while modifying the DB. */ public static BugResolution getBugResolution(String resolution, boolean create) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map params = new HashMap(); params.put("resolution", resolution); - List st = dbs.findObjectsByProperties(BugResolution.class, + List st = qi.findObjectsByProperties(BugResolution.class, params); if (!st.isEmpty()) { @@ -186,7 +186,7 @@ public static BugResolution getBugResolution(String resolution, boolean create) BugResolution bs = new BugResolution(); bs.setResolution(resolution); - if (!dbs.addRecord(bs)) + if (!qi.addRecord(bs)) return null; return bs; diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/BugSeverity.java b/alitheia/core/src/main/java/eu/sqooss/service/db/BugSeverity.java index e00652662..121ec6861 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/BugSeverity.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/BugSeverity.java @@ -170,12 +170,12 @@ public static BugSeverity getBugseverity(Severity s) { * while modifying the DB. */ public static BugSeverity getBugSeverity(String severity, boolean create) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map params = new HashMap(); params.put("severity", severity); - List st = dbs.findObjectsByProperties(BugSeverity.class, + List st = qi.findObjectsByProperties(BugSeverity.class, params); if (!st.isEmpty()) { @@ -193,7 +193,7 @@ public static BugSeverity getBugSeverity(String severity, boolean create) { BugSeverity bs = new BugSeverity(); bs.setSeverity(severity); - if (!dbs.addRecord(bs)) + if (!qi.addRecord(bs)) return null; return bs; diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/BugStatus.java b/alitheia/core/src/main/java/eu/sqooss/service/db/BugStatus.java index 6a3e27ff7..990f09898 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/BugStatus.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/BugStatus.java @@ -168,12 +168,12 @@ public static BugStatus getBugStatus(BugStatus.Status s) { * while modifying the DB. */ public static BugStatus getBugStatus(String status, boolean create) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map params = new HashMap(); params.put("status", status); - List st = dbs.findObjectsByProperties(BugStatus.class, + List st = qi.findObjectsByProperties(BugStatus.class, params); if (!st.isEmpty()) { @@ -191,7 +191,7 @@ public static BugStatus getBugStatus(String status, boolean create) { BugStatus bs = new BugStatus(); bs.setStatus(status); - if (!dbs.addRecord(bs)) + if (!qi.addRecord(bs)) return null; return bs; diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/ClusterNode.java b/alitheia/core/src/main/java/eu/sqooss/service/db/ClusterNode.java index 1439add8e..6b277984c 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/ClusterNode.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/ClusterNode.java @@ -109,11 +109,11 @@ public void setProjects(Set projects) { } public static ClusterNode getClusteNodeByName(String name) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map parameterMap = new HashMap(); parameterMap.put("name",name); - List cnList = dbs.findObjectsByProperties(ClusterNode.class, parameterMap); + List cnList = qi.findObjectsByProperties(ClusterNode.class, parameterMap); return (cnList == null || cnList.isEmpty()) ? null : cnList.get(0); } diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/ConfigurationOption.java b/alitheia/core/src/main/java/eu/sqooss/service/db/ConfigurationOption.java index 5ef0c8220..234a7e318 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/ConfigurationOption.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/ConfigurationOption.java @@ -131,7 +131,7 @@ public void setConfigurations(Set configurations) { */ public void setValues(StoredProject sp, List values, boolean overwrite) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + HQLQueryInterface hqi = AlitheiaCore.getInstance().getDBService().getQueryInterface(HQLQueryInterface.class); String paramProject = "paramProject"; String paramConfOpt = "paramConfOpt"; @@ -149,14 +149,14 @@ public void setValues(StoredProject sp, List values, params.put(paramConfOpt, this); List curValues = - (List) dbs.doHQL(query.toString(),params); + (List) hqi.doHQL(query.toString(),params); boolean found = false; if (overwrite) { - dbs.deleteRecords(curValues); + hqi.deleteRecords(curValues); for (String newValue : values) { StoredProjectConfig newspc = new StoredProjectConfig( this, newValue, sp); - dbs.addRecord(newspc); + hqi.addRecord(newspc); } } else { //Merge values for (String newValue : values) { @@ -168,7 +168,7 @@ public void setValues(StoredProject sp, List values, if (!found) { StoredProjectConfig newspc = new StoredProjectConfig( this, newValue, sp); - dbs.addRecord(newspc); + hqi.addRecord(newspc); } } } @@ -197,18 +197,18 @@ public List getValues(StoredProject sp) { params.put(paramProject, sp); params.put(paramConfOpt, this); - return (List) dbs.doHQL(query.toString(), params); + return (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query.toString(), params); } public static ConfigurationOption fromKey(String key) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + HQLQueryInterface hqi = AlitheiaCore.getInstance().getDBService().getQueryInterface(HQLQueryInterface.class); String paramKey = "key"; Map params = new HashMap(); params.put(paramKey, key); - List opts = dbs.findObjectsByProperties(ConfigurationOption.class, params); + List opts = hqi.findObjectsByProperties(ConfigurationOption.class, params); if (opts.isEmpty()) return null; diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/DAObject.java b/alitheia/core/src/main/java/eu/sqooss/service/db/DAObject.java index 752e535fb..6fc8aad66 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/DAObject.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/DAObject.java @@ -64,8 +64,8 @@ public abstract class DAObject { * @return */ public static T loadDAObyId(long id, Class type) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); - return dbs.findObjectById(type, id); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); + return qi.findObjectById(type, id); } } diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/DBService.java b/alitheia/core/src/main/java/eu/sqooss/service/db/DBService.java index bb63dcd9b..5101b621f 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/DBService.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/DBService.java @@ -34,35 +34,32 @@ package eu.sqooss.service.db; import eu.sqooss.core.AlitheiaCoreService; -import eu.sqooss.service.db.DAObject; import eu.sqooss.service.logging.Logger; -import java.sql.SQLException; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import org.hibernate.QueryException; - /** * This is the service providing access to the Alitheia Database, * including project metadata, user management, metrics data... * + * The responsibilities of the DBService are split into multiple interfaces to increase + * cohesion and to narrow down dependencies from other classes. + * * The API includes methods for retrieving data access objects (DAO) by id or by properties, - * and adding/deleting records in the database, and general-purpose querying methods - * for lower-level database access. + * and adding/deleting records in the database, through the QueryInterface provided by the + * getQueryInterface() method. General-purpose querying methods for lower-level database access + * are available through other QueryInterfaces, most notably the HQLQueryInterface. * Access and manipulation of the data is done directly through the DAOs in an object-oriented way. * * All access to the DB service has to be done in the context of a session. You can see the session - * as the connection to the database and the transaction for that connection. - * The method startDBSession() initialises a session, while commitDBSession() and rollbackDBSession() + * as the connection to the database and the transaction for that connection. Methods for database + * session management are provided by the DBSessionManager, obtained through the getSessionManager() + * method. The method startDBSession() initialises a session, while commitDBSession() and rollbackDBSession() * end the session, by committing or cancelling the changes respectively. * You can also query the current state of the session with the method isDBSessionActive(). * - * All the methods in this interface are thread-safe, which means you can call these methods on the - * same DBService object from different threads without needed to protect the access to the object. - * Furthermore, each session is handled within the context of a thread. So if two different threads + * All the methods in this interface and exposed interfaces are thread-safe, which means you can call + * these methods on the same DBService object from different threads without needed to protect the access + * to the object. Furthermore, each session is handled within the context of a thread. So if two different threads * have code that call startDBSession(), they will each start their own, and whatever they do during * the session will be isolated from the other. (ie. no DAO sharing, no changes visible accross threads...) * @@ -80,412 +77,50 @@ * @author Romain Pokrzywka * */ -public interface DBService extends AlitheiaCoreService { - - /** - * Starts a new work session with the DBService for the current thread. - * This method should be called before any other method from DBService, to ensure all resources - * are properly set up and ready, such as database connection, active transaction... - * (the only exception is doSQL, which manages the session internally) - * Only one session per thread can be active at a time, so calling startDBSession with a - * previously started session in the same thread has no effect and will assume usage - * of the existing session. (e.g. if a previous session was not closed properly) - * - * This method is thread-safe, and it creates session for a specific thread only. - * It will also start a database transaction, ensuring that only the current thread has access - * to the database for the duration of the session, therefore simplifying concurrency issues. - * - * @return true if the session was correctly started ; - * false if a session was already started for this thread, - * or if the session couldn't be started - */ - public boolean startDBSession(); - - /** - * Commits the changes made in the current work session into the database and closes the session, - * also releasing the transaction lock on the database. - * - * This method is thread-safe, and it will always close the current session (if any) - * and release any lock on the database, even if an error occurs. - * - * @return true if the commit was successful and the session correctly closed, - * false if there was no active session or if an error occured. - */ - public boolean commitDBSession(); - - /** - * Closes the current work session without committing the changes into the database, - * also releasing the transaction lock on the database. - * - * Note that any DAOs loaded and modified during the session will NOT be reset to - * their state at load-time. In other words, modifications to the DAOs are NOT cancelled, - * however these modifications will not be persisted in the database. - * - * This method is thread-safe, and it will always close the current session (if any) - * and release any lock on the database, even if an error occurs. - * - * @return true if the session was correctly closed, - * false if there was no active session or if an error occured. - */ - public boolean rollbackDBSession(); - - /** - * Flush the current changes in the session to the database and clears the session cache. - * Note that the transaction isn't committed though, so changes will only be visible - * to the current session. - * @return true if the session was correctly flushed, - * false if there was no active session or if an error occured. - */ - public boolean flushDBSession(); - - /** - * Returns the state of the work session for the current thread. - * @return true if a session was started and is still active, - * false otherwise - */ - public boolean isDBSessionActive(); +public interface DBService extends AlitheiaCoreService { - /** - * A generic query method to retrieve a single DAObject subclass using its identifier. - * The return value is parameterized to the actual type of DAObject queried - * so no downcast is needed. - * @param daoClass the actual class of the DAObject. - * @param id the DAObject's identifier - * @return the DAOObject if a match for the class and the identifier was found in the database, - * or null otherwise or if a database access error occured - */ - public T findObjectById(Class daoClass, long id); - - /** - * A generic query method to retrieve a single DAObject subclass using its identifier and - * acquire a pessimistic row-level database lock on it. - * This results in an SQL query with the form "SELECT ... FOR UPDATE". - * You may use this method to ensure that no other session can modify the returned object - * while the current session is active. This can help avoiding database-level deadlocks - * when multiple sessions access and modify the same table in parallel. - * The return value is parameterized to the actual type of DAObject queried - * so no downcast is needed. - * @param daoClass the actual class of the DAObject. - * @param id the DAObject's identifier - * @return the DAOObject if a match for the class and the identifier was found in the database, - * or null otherwise or if a database access error occured - */ - public T findObjectByIdForUpdate(Class daoClass, long id); - - /** - * A generic query method to retrieve a list of DAObjects of a same subclass - * matching a set of properties. - * The returned list contains the objects matching all of the properties specified. - * It is parameterized to the actual type of DAObject queried so no downcast is needed. - * The map key should be the property name as a string, and the value should be a value - * with a matching type for the property. For example, if a class has a String property - * called name (ie. a getName()/setName() accessor pair), then you would use "name" as - * the map key and a String object as the map value. - * If any property in the map isn't valid (either an unknown name or a value of the wrong type) - * the call will fail and an empty list will be returned. - * It uses its own session. - * - * @param daoClass the actual class of the DAObjects - * @param properties a map of property name/value pairs corresponding to properties - * of the DAObject subclass - * @return a list of DAObjects matching the class and the set of properties, - * possibly empty if no match was found in the database or if the properties map - * contains invalid entries or if a database access error occured - */ - public List findObjectsByProperties(Class daoClass, - Map properties ); - - /** - * A generic query method to retrieve a list of DAObjects of a same subclass - * matching a set of properties and acquire a pessimistic row-level database lock - * on each returned object in the list. - * This results in an SQL query with the form "SELECT ... FOR UPDATE". - * You may use this method to ensure that no other session can modify the returned objects - * while the current session is active. This can help avoiding database-level deadlocks - * when multiple sessions access and modify the same table in parallel. - * The returned list contains the objects matching all of the properties specified. - * It is parameterized to the actual type of DAObject queried so no downcast is needed. - * The map key should be the property name as a string, and the value should be a value - * with a matching type for the property. For example, if a class has a String property - * called name (ie. a getName()/setName() accessor pair), then you would use "name" as - * the map key and a String object as the map value. - * If any property in the map isn't valid (either an unknown name or a value of the wrong type) - * the call will fail and an empty list will be returned. - * It uses its own session. - * - * @param daoClass the actual class of the DAObjects - * @param properties a map of property name/value pairs corresponding to properties - * of the DAObject subclass - * @return a list of DAObjects matching the class and the set of properties, - * possibly empty if no match was found in the database or if the properties map - * contains invalid entries or if a database access error occured - */ - public List findObjectsByPropertiesForUpdate(Class daoClass, - Map properties ); - - /** - * Add a new record to the database, including all the associations the record may contain. - * - * @param record the record to persist into the database - * @return true if the record insertion succeeded, false otherwise - */ - public boolean addRecord(DAObject record); /** - * Add multiple new records to the database. - * - * @param records the list of records to persist into the database - * @return true if all the record insertions succeeded, false otherwise - */ - public boolean addRecords(List records); - - /** - * Delete an existing record from the database. - * - * @param record the record to remove from the database - * @return true if the record deletion succeeded, false otherwise - */ - public boolean deleteRecord(DAObject record); - - /** - * Delete multiple existing records from the database. - * - * @param records the list of records to remove from the database - * @return true if all the record deletions succeeded, false otherwise - */ - public boolean deleteRecords(List records); - - /** - * Attach a disconnected object to the current Session. If the corresponding - * row exists, then the returned object will merge the persistent and - * the disconnected object fields. Preference will be given to the field - * values of the detached object. If the detached object contains - * references to other DAOs, the attach operation will cascade. - * - * WARNING : the attached DAO is the returned object, NOT the one you passed as argument ! - * - * @param obj the object to connect - * @return the connected instance of the object - */ - public T attachObjectToDBSession(T obj); - - /** - * Execute a complete SQL query to the database. - * This allows low-level manipulation of the database contents outside of the DAO types. - * To limit risks of SQL injection exploits, please do not execute queries like - * "SELECT * FROM " + tableName. - * If you need dynamic SQL queries, please use the overload with the params argument. - * - * @param sql the sql query string - * @return a list of records. If the query contains multiple columns, - * the results are returned in an instance of Object[] - * @throws SQLException if the query is invalid or a database access error occurs - * - * @see doSQL(String sql, Map params) - * @deprecated - */ - @Deprecated - public List doSQL(String sql) - throws SQLException; - - /** - * Execute a parameterized SQL query to the database. - * This allows low-level manipulation of the database contents outside of the DAO types. - * - * @param sql the sql query string - * @param params the map of parameters to be substituted in the SQL query - * @return a list of records. If the query contains multiple columns, - * the results are returned in an instance of Object[] - * @throws SQLException if the query is invalid or a database access error occurs - * @throws QueryException if some parameters are missing - * @deprecated - */ - @Deprecated - public List doSQL(String sql, Map params) - throws SQLException, QueryException; - - /** - * Execute a named stored procedure. Stored procedures in general should be - * avoided as much as possible as they harm portability and this is why - * this method is marked as deprecated. For the same reason this method only - * returns an integer and not a cursor, as one should expect. - * In some cases however, e.g. when doing large batch updates or when - * moving large volumes, stored procedures can speed up things. To maintain - * portability, there must always be an alternative execution path that - * does not involve calling a stored procedure. - * - * @param sql The name of the procedure to call (case sensitive) - * @param arglist Names for the stored procedure arguments, order must be the - * same as in the stored procedure itself. - * @param params The map of parameters to be substituted in the SQL query - * @return The number of rows affected by the execution of the procedure. - * @throws SQLException if the stored procedure execution fails for some reason. - * @throws QueryException if some parameters are missing - * @deprecated + * Get the logger used by the DB service, to log something DB specific. + * This is the prefered method for DAOs to log things. */ - @Deprecated - public int callProcedure(String procName, List arglist, Map params) - throws SQLException, QueryException; + public Logger logger(); /** - * Execute a complete HQL query to the database. - * To limit risks of HQL injection exploits, please do not execute queries like - * "FROM " + objectClass. - * If you need dynamic HQL queries, please use the overload with the params argument. - * - * @param hql the HQL query string - * @return a list of {@link DAObject}, fetched with a read access lock in the database. - * If the query contains multiple columns, - * the results are returned in an instance of Object[]. - * If the query is invalid or a database access error occurs, - * an empty list will be returned. - * - * @throws QueryException if the query is invalid - * - * @see doHQL(String, Map) + * Get the object responsible for all the session management operations + * like starting, committing and rolling back a database transaction. + * See {@link eu.sqooss.service.db.DBSessionManager}} for more details + * about the available operations. + * @return the instance of the DBSessionManager */ - public List doHQL(String hql) - throws QueryException; + public DBSessionManager getSessionManager(); /** - * Execute a parameterized HQL query to the database. - * - * @param hql the HQL query string - * @param params the map of parameters to be substituted in the HQL query - * @return a list of {@link DAObject}, fetched with a read access lock in the database. - * If the query contains multiple columns, - * the results are returned in an instance of Object[]. - * If the query is invalid or a database access error occurs, - * an empty list will be returned. - * - * @throws QueryException if the query is invalid or if params contains invalid entries - * - * @see doHQL(String, Map, Map) - */ - public List doHQL(String hql, Map params) - throws QueryException; - - /** - * Execute a parameterized HQL query to the database. - * - * @param hql the HQL query string - * @param params the map of parameters to be substituted in the HQL query - * @param limit only retrieve the first n rows - * @return a list of {@link DAObject}, fetched with a read access lock in the database. - * If the query contains multiple columns, - * the results are returned in an instance of Object[] - * If the query is invalid or a database access error occurs, - * an empty list will be returned. - * - * @throws QueryException if the query is invalid or if params contains invalid entries - * - * @see doHQL(String, Map, Map) - */ - public List doHQL(String hql, Map params, int limit) - throws QueryException; - - /** - * Execute a parameterized HQL query to the database. The table whose rows - * should be returned and locked must be aliased as 'foo' for the lock - * mode to work, for example: - *
-     * select foo from Developer as foo, StoredProject sp where foo.project=sp...
-     * 
- * @param hql the HQL query string - * @param params the map of parameters to be substituted in the HQL query - * @param lockForUpdate if true, the generated SQL query will use a "SELECT ... FOR UPDATE" - * statement. Otherwise, a normal "SELECT" will be used. Only one table can be - * locked per query. - * @return a list of {@link DAObject}, with a corresponding lock in the database. - * If the query contains multiple columns, - * the results are returned in an instance of Object[] - * If the query is invalid or a database access error occurs, - * an empty list will be returned. - * - * @throws QueryException if the query is invalid or if params contains invalid entries - * - * @see doHQL(String, Map, Map) - */ - public List doHQL(String hql, Map params, boolean lockForUpdate) - throws QueryException; - - /** - * Execute a parameterized HQL query to the database. - * - * @param hql HQL query string - * @param params the map of parameters to be substituted in the HQL query - * @return a list of {@link DAObject}, fetched with a read access lock in the database. - * If the query contains multiple columns, - * the results are returned in an instance of Object[] - * If the query is invalid or a database access error occurs, - * an empty list will be returned. - * - * @throws QueryException if the query is invalid or if params or collectionParams - * contain invalid entries - */ - public List doHQL(String hql, Map params, - Map collectionParams) - throws QueryException; - - /** - * Execute a parameterized HQL query to the database. - * HQL is very similar to SQL, but differs in a variety of important ways. - * See the hibernate documentation at - * http://www.hibernate.org/hib_docs/reference/en/html/queryhql.html - * for details. As a rule, you do not write 'SELECT *' but only - * 'FROM ' (note: not the table name, the @em class). - * - * The query string may contain named parameters, for which values - * will be substituted from the params and lparams arguments to this - * method. For parameters that expect a single datum, put the mapping - * from name to an object in the params argument. List-based parameters - * (for instance the allowable values in a "IN ( foo, ... )" clause) - * may be placed in the lparams argument. Either may be null if there - * are no paramaters of that kind. - * - * @param hql HQL query string - * @param params the map of parameters to be substituted in the HQL query - * @param lockForUpdate if true, the generated SQL query will use a "SELECT ... FOR UPDATE" - * statement. Otherwise, a normal "SELECT" will be used - * @param start fetch results starting at the specified row - * @param limit only retrieve the specified number of rows - * @return a list of {@link DAObject}, with a corresponding lock in the database. - * If the query contains multiple columns, - * the results are returned in an instance of Object[] - * If the query is invalid or a database access error occurs, - * an empty list will be returned. - * - * @throws QueryException if the query is invalid or if params or collectionParams - * contain invalid entries + * Returns a basic implementation of the QueryInterface used to perform + * simple queries to the database, like adding, deleting and finding + * records. For a complete list of the available operations, see + * {@link eu.sqooss.service.db.QueryInterface}. + * @return a basic QueryInterface instance */ - public List doHQL(String hql, - Map params, - Map collectionParams, - boolean lockForUpdate, - int start, int limit - ) - throws QueryException; + public QueryInterface getQueryInterface(); /** - * Executes a DML-type query. The query forms that HQL supports - * are the following: - *
    - *
  • INSERT INTO ... SELECT ...
  • - *
  • UPDATE ... SET ... WHERE....
  • - *
  • DELETE ... WHERE
  • - *
- * - * @param hql The HQL statement to execute - * @param params the map of parameters to be substituted in the HQL query - * @return The number of rows updated or deleted or -1 in case of error + * This function can be used to retrieve more extended implementations + * of the QueryInterface, for instance an HQLQueryInterface instance. + * @param queryInterfaceType The class of the implementation to be used + * as QueryInterface + * @return an implementation of the QueryInterface interface */ - public int executeUpdate(String hql, Map params); + public T getQueryInterface(Class queryInterfaceType); /** - * Get the logger used by the DB service, to log something DB specific. - * This is the prefered method for DAOs to log things. + * Registers a new QueryInterface by providing a factory that can construct + * an instance of that QueryInterface. + * @param queryInterfaceType the QueryInterface subtype to register + * @param factoryType the QueryInterfaceFactory capable of constructing the QueryInterface */ - public Logger logger(); + public void registerQueryInterface(Class queryInterfaceType, + Class> factoryType); } // vi: ai nosi sw=4 ts=4 expandtab diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/DBSessionManager.java b/alitheia/core/src/main/java/eu/sqooss/service/db/DBSessionManager.java new file mode 100644 index 000000000..5189669f3 --- /dev/null +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/DBSessionManager.java @@ -0,0 +1,84 @@ +package eu.sqooss.service.db; + +/** + * Database service entity that manages the thread-based database sessions. + */ +public interface DBSessionManager { + + /** + * Starts a new work session with the DBService for the current thread. + * This method should be called before any other method from DBService, to ensure all resources + * are properly set up and ready, such as database connection, active transaction... + * Only one session per thread can be active at a time, so calling startDBSession with a + * previously started session in the same thread has no effect and will assume usage + * of the existing session. (e.g. if a previous session was not closed properly) + * + * This method is thread-safe, and it creates session for a specific thread only. + * It will also start a database transaction, ensuring that only the current thread has access + * to the database for the duration of the session, therefore simplifying concurrency issues. + * + * @return true if the session was correctly started ; + * false if a session was already started for this thread, + * or if the session couldn't be started + */ + public boolean startDBSession(); + + /** + * Commits the changes made in the current work session into the database and closes the session, + * also releasing the transaction lock on the database. + * + * This method is thread-safe, and it will always close the current session (if any) + * and release any lock on the database, even if an error occurs. + * + * @return true if the commit was successful and the session correctly closed, + * false if there was no active session or if an error occured. + */ + public boolean commitDBSession(); + + /** + * Closes the current work session without committing the changes into the database, + * also releasing the transaction lock on the database. + * + * Note that any DAOs loaded and modified during the session will NOT be reset to + * their state at load-time. In other words, modifications to the DAOs are NOT cancelled, + * however these modifications will not be persisted in the database. + * + * This method is thread-safe, and it will always close the current session (if any) + * and release any lock on the database, even if an error occurs. + * + * @return true if the session was correctly closed, + * false if there was no active session or if an error occured. + */ + public boolean rollbackDBSession(); + + /** + * Flush the current changes in the session to the database and clears the session cache. + * Note that the transaction isn't committed though, so changes will only be visible + * to the current session. + * @return true if the session was correctly flushed, + * false if there was no active session or if an error occured. + */ + public boolean flushDBSession(); + + /** + * Returns the state of the work session for the current thread. + * @return true if a session was started and is still active, + * false otherwise + */ + public boolean isDBSessionActive(); + + /** + * Attach a disconnected object to the current Session. If the corresponding + * row exists, then the returned object will merge the persistent and + * the disconnected object fields. Preference will be given to the field + * values of the detached object. If the detached object contains + * references to other DAOs, the attach operation will cascade. + * + * WARNING : the attached DAO is the returned object, NOT the one you passed as argument ! + * + * @param obj the object to connect + * @return the connected instance of the object + */ + public T attachObjectToDBSession(T obj); + +} diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/DBSessionValidation.java b/alitheia/core/src/main/java/eu/sqooss/service/db/DBSessionValidation.java new file mode 100644 index 000000000..8d7855428 --- /dev/null +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/DBSessionValidation.java @@ -0,0 +1,32 @@ +package eu.sqooss.service.db; + +import java.sql.SQLException; + +public interface DBSessionValidation { + + /** + * Returns the state of the work session for the current thread, while logging + * any access to an inactive session. Should be called whenever a session is + * required to be active. + * + * @return true if a session was started and is still active, + * false otherwise + */ + public boolean checkSession(); + + /** + * Logs a database-related exception and cleans up the database session of the + * current thread, if it exists. + * + * @param e an exception triggering the termination of the active session + */ + public void logExceptionAndTerminateSession(Exception e); + + /** + * Logs an SQL exception. + * + * @param e the exception to be logged + */ + public void logSQLException(SQLException e); + +} diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/Developer.java b/alitheia/core/src/main/java/eu/sqooss/service/db/Developer.java index 26f99af02..12d8ce655 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/Developer.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/Developer.java @@ -235,7 +235,7 @@ public static Developer getDeveloperByEmail(String email, */ public static synchronized Developer getDeveloperByEmail(String email, StoredProject sp, boolean create){ - DBService dbs = AlitheiaCore.getInstance().getDBService(); + HQLQueryInterface hqi = AlitheiaCore.getInstance().getDBService().getQueryInterface(HQLQueryInterface.class); String paramProject = "project"; String paramEmail = "email"; @@ -250,7 +250,7 @@ public static synchronized Developer getDeveloperByEmail(String email, parameterMap.put(paramEmail, email); parameterMap.put(paramProject, sp); - List devs = (List) dbs.doHQL(q.toString(), parameterMap); + List devs = (List) hqi.doHQL(q.toString(), parameterMap); /* Developer in the DB, return it */ if ( !devs.isEmpty() ) @@ -300,7 +300,7 @@ public static synchronized Developer getDeveloperByEmail(String email, d.setStoredProject(sp); /*Failure here probably indicates non-existing StoredProject*/ - if ( !dbs.addRecord(d) ) + if ( !hqi.addRecord(d) ) return null; d.addAlias(email); @@ -342,13 +342,13 @@ public static Developer getDeveloperByUsername(String username, public static synchronized Developer getDeveloperByUsername(String username, StoredProject sp, boolean create) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map parameterMap = new HashMap(); parameterMap.put("username", username); parameterMap.put("storedProject", sp); - List devs = dbs.findObjectsByProperties(Developer.class, + List devs = qi.findObjectsByProperties(Developer.class, parameterMap); /* @@ -365,7 +365,7 @@ public static synchronized Developer getDeveloperByUsername(String username, * only work with certain databases (tested with mysql, postgres and * derby). */ - /*devs = (List) dbs.doHQL("from Developer as foo where email like " + + /*devs = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL("from Developer as foo where email like " + "'%" +username+ "%' and storedProject.id=" + sp.getId() ); for (Developer d : devs) { @@ -389,7 +389,7 @@ public static synchronized Developer getDeveloperByUsername(String username, d.setStoredProject(sp); /*Failure here probably indicates non-existing StoredProject*/ - if (!dbs.addRecord(d)) + if (!qi.addRecord(d)) return null; return d; @@ -408,13 +408,13 @@ public static synchronized Developer getDeveloperByUsername(String username, public static synchronized Developer getDeveloperByName(String name, StoredProject sp, boolean create) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map params = new HashMap(); params.put("name", name); params.put("storedProject", sp); - List devs = dbs.findObjectsByProperties(Developer.class,params); + List devs = qi.findObjectsByProperties(Developer.class,params); /* This code assumes that each name is unique in a project*/ if (devs.size() > 0) @@ -425,7 +425,7 @@ public static synchronized Developer getDeveloperByName(String name, Developer d = new Developer(); d.setName(name); - if (!dbs.addRecord(d)) + if (!qi.addRecord(d)) return null; return d; diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/Directory.java b/alitheia/core/src/main/java/eu/sqooss/service/db/Directory.java index d84e09068..bad6686e5 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/Directory.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/Directory.java @@ -129,11 +129,11 @@ public boolean isSubDirOf(Directory d) { */ public static synchronized Directory getDirectory(String path, boolean create) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map parameterMap = new HashMap(); parameterMap.put("path", path); - List dirs = dbs.findObjectsByProperties(Directory.class, + List dirs = qi.findObjectsByProperties(Directory.class, parameterMap); /* Dir path in table, return it */ @@ -145,7 +145,7 @@ public static synchronized Directory getDirectory(String path, boolean create) { /* Dir path not in table, create it */ Directory d = new Directory(); d.setPath(path); - if (!dbs.addRecord(d)) { + if (!qi.addRecord(d)) { return null; } diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/HQLQueryInterface.java b/alitheia/core/src/main/java/eu/sqooss/service/db/HQLQueryInterface.java new file mode 100644 index 000000000..a835f424a --- /dev/null +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/HQLQueryInterface.java @@ -0,0 +1,165 @@ +package eu.sqooss.service.db; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.hibernate.QueryException; + +public interface HQLQueryInterface extends QueryInterface { + + /** + * Execute a complete HQL query to the database. + * To limit risks of HQL injection exploits, please do not execute queries like + * "FROM " + objectClass. + * If you need dynamic HQL queries, please use the overload with the params argument. + * + * @param hql the HQL query string + * @return a list of {@link DAObject}, fetched with a read access lock in the database. + * If the query contains multiple columns, + * the results are returned in an instance of Object[]. + * If the query is invalid or a database access error occurs, + * an empty list will be returned. + * + * @throws QueryException if the query is invalid + * + * @see doHQL(String, Map) + */ + public List doHQL(String hql) + throws QueryException; + + /** + * Execute a parameterized HQL query to the database. + * + * @param hql the HQL query string + * @param params the map of parameters to be substituted in the HQL query + * @return a list of {@link DAObject}, fetched with a read access lock in the database. + * If the query contains multiple columns, + * the results are returned in an instance of Object[]. + * If the query is invalid or a database access error occurs, + * an empty list will be returned. + * + * @throws QueryException if the query is invalid or if params contains invalid entries + * + * @see doHQL(String, Map, Map) + */ + public List doHQL(String hql, Map params) + throws QueryException; + + /** + * Execute a parameterized HQL query to the database. + * + * @param hql the HQL query string + * @param params the map of parameters to be substituted in the HQL query + * @param limit only retrieve the first n rows + * @return a list of {@link DAObject}, fetched with a read access lock in the database. + * If the query contains multiple columns, + * the results are returned in an instance of Object[] + * If the query is invalid or a database access error occurs, + * an empty list will be returned. + * + * @throws QueryException if the query is invalid or if params contains invalid entries + * + * @see doHQL(String, Map, Map) + */ + public List doHQL(String hql, Map params, int limit) + throws QueryException; + + /** + * Execute a parameterized HQL query to the database. The table whose rows + * should be returned and locked must be aliased as 'foo' for the lock + * mode to work, for example: + *
+     * select foo from Developer as foo, StoredProject sp where foo.project=sp...
+     * 
+ * @param hql the HQL query string + * @param params the map of parameters to be substituted in the HQL query + * @param lockForUpdate if true, the generated SQL query will use a "SELECT ... FOR UPDATE" + * statement. Otherwise, a normal "SELECT" will be used. Only one table can be + * locked per query. + * @return a list of {@link DAObject}, with a corresponding lock in the database. + * If the query contains multiple columns, + * the results are returned in an instance of Object[] + * If the query is invalid or a database access error occurs, + * an empty list will be returned. + * + * @throws QueryException if the query is invalid or if params contains invalid entries + * + * @see doHQL(String, Map, Map) + */ + public List doHQL(String hql, Map params, boolean lockForUpdate) + throws QueryException; + + /** + * Execute a parameterized HQL query to the database. + * + * @param hql HQL query string + * @param params the map of parameters to be substituted in the HQL query + * @return a list of {@link DAObject}, fetched with a read access lock in the database. + * If the query contains multiple columns, + * the results are returned in an instance of Object[] + * If the query is invalid or a database access error occurs, + * an empty list will be returned. + * + * @throws QueryException if the query is invalid or if params or collectionParams + * contain invalid entries + */ + public List doHQL(String hql, Map params, + Map collectionParams) + throws QueryException; + + /** + * Execute a parameterized HQL query to the database. + * HQL is very similar to SQL, but differs in a variety of important ways. + * See the hibernate documentation at + * http://www.hibernate.org/hib_docs/reference/en/html/queryhql.html + * for details. As a rule, you do not write 'SELECT *' but only + * 'FROM ' (note: not the table name, the @em class). + * + * The query string may contain named parameters, for which values + * will be substituted from the params and lparams arguments to this + * method. For parameters that expect a single datum, put the mapping + * from name to an object in the params argument. List-based parameters + * (for instance the allowable values in a "IN ( foo, ... )" clause) + * may be placed in the lparams argument. Either may be null if there + * are no paramaters of that kind. + * + * @param hql HQL query string + * @param params the map of parameters to be substituted in the HQL query + * @param lockForUpdate if true, the generated SQL query will use a "SELECT ... FOR UPDATE" + * statement. Otherwise, a normal "SELECT" will be used + * @param start fetch results starting at the specified row + * @param limit only retrieve the specified number of rows + * @return a list of {@link DAObject}, with a corresponding lock in the database. + * If the query contains multiple columns, + * the results are returned in an instance of Object[] + * If the query is invalid or a database access error occurs, + * an empty list will be returned. + * + * @throws QueryException if the query is invalid or if params or collectionParams + * contain invalid entries + */ + public List doHQL(String hql, + Map params, + Map collectionParams, + boolean lockForUpdate, + int start, int limit + ) + throws QueryException; + + /** + * Executes a DML-type query. The query forms that HQL supports + * are the following: + *
    + *
  • INSERT INTO ... SELECT ...
  • + *
  • UPDATE ... SET ... WHERE....
  • + *
  • DELETE ... WHERE
  • + *
+ * + * @param hql The HQL statement to execute + * @param params the map of parameters to be substituted in the HQL query + * @return The number of rows updated or deleted or -1 in case of error + */ + public int executeUpdate(String hql, Map params); + +} diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/MailMessage.java b/alitheia/core/src/main/java/eu/sqooss/service/db/MailMessage.java index dfffa7edc..2792755f2 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/MailMessage.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/MailMessage.java @@ -231,10 +231,10 @@ public Set getMeasurements() { * Return a stored mail message based on messageId */ public static MailMessage getMessageById(String messageId) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map properties = new HashMap(1); properties.put("messageId", messageId); - List msgList = dbs.findObjectsByProperties(MailMessage.class, properties); + List msgList = qi.findObjectsByProperties(MailMessage.class, properties); if ((msgList == null) || (msgList.isEmpty())) { return null; @@ -247,10 +247,10 @@ public static MailMessage getMessageById(String messageId) { * Return a stored mail message based on filename */ public static MailMessage getMessageByFileName(String filename) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map properties = new HashMap(1); properties.put("fileName", filename); - List msgList = dbs.findObjectsByProperties(MailMessage.class, properties); + List msgList = qi.findObjectsByProperties(MailMessage.class, properties); if ((msgList == null) || (msgList.isEmpty())) { return null; @@ -275,7 +275,7 @@ public static MailMessage getLatestMailMessage(StoredProject sp) { Map params = new HashMap(); params.put(paramStoredProject, sp); - List mm = (List) dbs.doHQL(query, params, 1); + List mm = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, params, 1); if (!mm.isEmpty()) return mm.get(0); diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/MailingList.java b/alitheia/core/src/main/java/eu/sqooss/service/db/MailingList.java index 1b92720cc..d10883ae4 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/MailingList.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/MailingList.java @@ -161,7 +161,7 @@ public List getMessagesNewerThan(Date d) { params.put(paramDate, d); params.put(paramMailingList, this); - List msgs = (List) dbs.doHQL(query, params); + List msgs = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, params); if (msgs == null || msgs.size() == 0) return Collections.emptyList(); @@ -187,7 +187,7 @@ public MailMessage getLatestEmail() { params.put(paramMailingList, this); - List ml = (List) dbs.doHQL(query, params, 1); + List ml = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, params, 1); if (ml.isEmpty()) return null; @@ -212,7 +212,7 @@ public MailingListThread getLatestThread() { Map params = new HashMap(); params.put(paramMailingList, this); - List ml = (List) dbs.doHQL(query, params, 1); + List ml = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, params, 1); if (ml.isEmpty()) return null; diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/MailingListThread.java b/alitheia/core/src/main/java/eu/sqooss/service/db/MailingListThread.java index 791eda19c..733261e06 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/MailingListThread.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/MailingListThread.java @@ -155,13 +155,13 @@ public void setLastUpdated(Date lastUpdated) { */ public MailMessage getStartingEmail() { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map params = new HashMap(); params.put("thread", this); params.put("depth", 0); - List mm = dbs.findObjectsByProperties(MailMessage.class, + List mm = qi.findObjectsByProperties(MailMessage.class, params); if (!mm.isEmpty()) @@ -188,7 +188,7 @@ public List getMessagesByArrivalOrder() { Map params = new HashMap(1); params.put(paramThread, this); - List mm = (List) dbs.doHQL(query, params); + List mm = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, params); if (mm == null || mm.isEmpty()) return Collections.emptyList(); @@ -212,7 +212,7 @@ public int getThreadDepth() { Map params = new HashMap(1); params.put(paramThread, this); - List mm = (List) dbs.doHQL(query, params, 1); + List mm = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, params, 1); if (mm == null || mm.isEmpty()) return 0; @@ -243,7 +243,7 @@ public List getMessagesAtLevel(int level) { params.put(paramThread, this); params.put(paramDepth, level); - List mm = (List) dbs.doHQL(query, params); + List mm = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, params); if (mm == null || mm.isEmpty()) return Collections.emptyList(); diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/Metric.java b/alitheia/core/src/main/java/eu/sqooss/service/db/Metric.java index a3b9d8bb0..33cb09a1f 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/Metric.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/Metric.java @@ -302,7 +302,7 @@ public boolean isEvaluated (StoredProject p) { params.put("project", p); params.put("metric", this); - if (dbs.doHQL(query.toString(), params, 1).size() >= 1) + if (dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query.toString(), params, 1).size() >= 1) return true; return false; @@ -343,12 +343,12 @@ public String toString() { * provided mnemonic */ public static Metric getMetricByMnemonic(String mnem) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map properties = new HashMap(); properties.put("mnemonic", mnem); - List result = dbs.findObjectsByProperties(Metric.class, + List result = qi.findObjectsByProperties(Metric.class, properties); if (result.size() <= 0) @@ -365,7 +365,7 @@ public static Metric getMetricByMnemonic(String mnem) { */ public static List getAllMetrics() { DBService dbs = AlitheiaCore.getInstance().getDBService(); - return (List) dbs.doHQL("from Metric"); + return (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL("from Metric"); } } diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/MetricType.java b/alitheia/core/src/main/java/eu/sqooss/service/db/MetricType.java index 5b8d0721a..da8cd35c9 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/MetricType.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/MetricType.java @@ -169,10 +169,10 @@ public void setMetrics(Set metrics) { * @return A MetricType DAO representing the metric type */ public static MetricType getMetricType(Type t) { - DBService db = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); HashMap s = new HashMap(); s.put("type", t.toString()); - List result = db.findObjectsByProperties(MetricType.class, s); + List result = qi.findObjectsByProperties(MetricType.class, s); if (result.isEmpty()) { return null; } diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/NameSpace.java b/alitheia/core/src/main/java/eu/sqooss/service/db/NameSpace.java index 56360d423..254cfaa51 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/NameSpace.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/NameSpace.java @@ -156,7 +156,7 @@ public static NameSpace findByVersionName(ProjectVersion pv, String name) { params.put("pv", pv); params.put("name", name); - List ns = (List) dbs.doHQL(nsByVersion, params); + List ns = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(nsByVersion, params); if (ns.isEmpty()) return null; diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/OhlohDeveloper.java b/alitheia/core/src/main/java/eu/sqooss/service/db/OhlohDeveloper.java index 6403bbf5a..14294a5aa 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/OhlohDeveloper.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/OhlohDeveloper.java @@ -144,17 +144,17 @@ public static OhlohDeveloper getByEmailHash(String hash) { } public static List getByUserName(String uname) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map params = new HashMap(); params.put("uname", uname); - return dbs.findObjectsByProperties(OhlohDeveloper.class, params); + return qi.findObjectsByProperties(OhlohDeveloper.class, params); } private static OhlohDeveloper getBy(String name, String value) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map params = new HashMap(); params.put(name, value); - List l = dbs.findObjectsByProperties(OhlohDeveloper.class, params); + List l = qi.findObjectsByProperties(OhlohDeveloper.class, params); if (!l.isEmpty()) return l.get(0); diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/Plugin.java b/alitheia/core/src/main/java/eu/sqooss/service/db/Plugin.java index a1529a2df..424c5501a 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/Plugin.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/Plugin.java @@ -189,10 +189,10 @@ public void setSupportedMetrics(Set supportedMetrics) { } public static List getPluginByName(String name) { - DBService db = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); HashMap s = new HashMap(); s.put("name", name); - return db.findObjectsByProperties(Plugin.class, s); + return qi.findObjectsByProperties(Plugin.class, s); } /** @@ -207,10 +207,10 @@ public static List getPluginByName(String name) { * otherwise */ public static Plugin getPluginByHashcode(String hashcode) { - DBService db = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); HashMap s = new HashMap(); s.put("hashcode", hashcode); - List l = db.findObjectsByProperties(Plugin.class, s); + List l = qi.findObjectsByProperties(Plugin.class, s); if (!l.isEmpty()) return l.get(0); diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/PluginConfiguration.java b/alitheia/core/src/main/java/eu/sqooss/service/db/PluginConfiguration.java index 5456f9885..ba11871f1 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/PluginConfiguration.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/PluginConfiguration.java @@ -126,11 +126,11 @@ public void setMsg(String msg) { * Get a PluginConfiguration entry DAO or null in */ public static PluginConfiguration getConfigurationEntry(Plugin p, HashMap names) { - DBService db = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); names.put("plugin", p); - List l = db.findObjectsByProperties(PluginConfiguration.class, names); + List l = qi.findObjectsByProperties(PluginConfiguration.class, names); if(l.isEmpty()) { return null; @@ -145,7 +145,7 @@ public static PluginConfiguration getConfigurationEntry(Plugin p, HashMap names) { - DBService db = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); PluginConfiguration pc = getConfigurationEntry(p, names); if (pc == null) { @@ -156,7 +156,7 @@ public static boolean updConfigurationEntry(Plugin p, HashMap na names.put("plugin", p); - List l = db.findObjectsByProperties(PluginConfiguration.class, s); + List l = qi.findObjectsByProperties(PluginConfiguration.class, s); if (l.isEmpty()) { return false; diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/ProjectFile.java b/alitheia/core/src/main/java/eu/sqooss/service/db/ProjectFile.java index 399ae78ad..d73554048 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/ProjectFile.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/ProjectFile.java @@ -368,11 +368,11 @@ public String getFileName() { */ public Directory toDirectory() { if ((isDirectory) && (getFileName() != null)) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map props = new HashMap(); props.put("path", getFileName()); List matches = - dbs.findObjectsByProperties(Directory.class, props); + qi.findObjectsByProperties(Directory.class, props); if ((matches != null) && (matches.size() > 0)) return matches.get(0); } @@ -410,7 +410,7 @@ public ProjectFile getPreviousFileVersion() { parameters.put("paramCopyFromName", this.getCopyFrom().getName()); parameters.put("paramCopyFromDir", this.getCopyFrom().getDir().getId()); } - List projectFiles = dbs.doHQL(query, parameters, 1); + List projectFiles = dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, parameters, 1); if (projectFiles.size() == 0) { dbs.logger().warn("No previous versions for " + this + @@ -481,7 +481,7 @@ public static ProjectVersion getDeletionVersion(ProjectFile pf) { params.put(paramProject, pf.getProjectVersion().getProject()); params.put(paramOrder, pf.getProjectVersion().getSequence()); - List pvs = (List) db.doHQL(query, params); + List pvs = (List) db.getQueryInterface(HQLQueryInterface.class).doHQL(query, params); if (pvs.size() <= 0) return null; @@ -525,7 +525,7 @@ public ProjectFile getEnclosingDirectory() { params.put(paramIsDir, true); params.put(paramSequence, this.getProjectVersion().getSequence()); - List pfs = (List) db.doHQL(query, params, 1); + List pfs = (List) db.getQueryInterface(HQLQueryInterface.class).doHQL(query, params, 1); if (pfs.size() <= 0) return null; @@ -563,7 +563,7 @@ public static List getFileModifications(ProjectFile pf) { parameters.put(paramDir, pf.getDir()); parameters.put(paramProject, pf.getProjectVersion().getProject()); - return (List) dbs.doHQL(query, parameters); + return (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, parameters); } /** @@ -634,7 +634,7 @@ public static ProjectFile findFile(Long projectId, String name, parameters.put(paramPath, path); parameters.put(paramVersion, version); - pfs = (List) dbs.doHQL(query.toString(), parameters, 1); + pfs = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query.toString(), parameters, 1); if (pfs.isEmpty()) return null; @@ -647,7 +647,7 @@ public List getChangedExecutionUnits() { Map params = new HashMap(); params.put("file", this); - return (List)dbs.doHQL(qChangedMethods, params); + return (List)dbs.getQueryInterface(HQLQueryInterface.class).doHQL(qChangedMethods, params); } public String toString() { diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/ProjectFileState.java b/alitheia/core/src/main/java/eu/sqooss/service/db/ProjectFileState.java index 612da0404..15849934e 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/ProjectFileState.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/ProjectFileState.java @@ -119,14 +119,15 @@ public static ProjectFileState replaced() { } public static ProjectFileState fromStatus(int status) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = dbs.getQueryInterface(); - if (!dbs.isDBSessionActive()) + if (!dbs.getSessionManager().isDBSessionActive()) return null; Map params = new HashMap(); params.put("status", status); - List pfs = dbs.findObjectsByProperties( + List pfs = qi.findObjectsByProperties( ProjectFileState.class, params); if (!pfs.isEmpty()) { @@ -136,7 +137,7 @@ public static ProjectFileState fromStatus(int status) { ProjectFileState state = new ProjectFileState(); state.setStatus(status); - dbs.addRecord(state); + qi.addRecord(state); return fromStatus(status); } diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/ProjectVersion.java b/alitheia/core/src/main/java/eu/sqooss/service/db/ProjectVersion.java index f32cebc48..56c72e8e5 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/ProjectVersion.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/ProjectVersion.java @@ -460,7 +460,7 @@ public ProjectVersion getPreviousVersion() { parameters.put(paramOrder, this.getSequence()); parameters.put(paramProject, this.getProject().getId()); - List projectVersions = dbs.doHQL(query, parameters, 1); + List projectVersions = dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, parameters, 1); if(projectVersions == null || projectVersions.size() == 0) { return null; @@ -491,7 +491,7 @@ public ProjectVersion getNextVersion() { parameters.put(paramTS, this.getSequence()); parameters.put(paramProject, this.getProject().getId()); - List projectVersions = dbs.doHQL(query, parameters, 1); + List projectVersions = dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, parameters, 1); if(projectVersions == null || projectVersions.size() == 0) { return null; @@ -514,13 +514,13 @@ public ProjectVersion getNextVersion() { * or null if there is none. */ public static ProjectVersion getVersionByRevision(StoredProject project, String revisionId) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map parameters = new HashMap(); parameters.put("project", project); parameters.put("revisionId", revisionId); - List versions = dbs.findObjectsByProperties(ProjectVersion.class, parameters); + List versions = qi.findObjectsByProperties(ProjectVersion.class, parameters); if (versions == null || versions.size() == 0) { return null; } else { @@ -547,13 +547,13 @@ public static ProjectVersion getVersionByRevision(StoredProject project, String */ public static ProjectVersion getVersionByTimestamp( StoredProject project, long timestamp) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map parameters = new HashMap(); parameters.put("project", project); parameters.put("timestamp", timestamp); - List versions = dbs.findObjectsByProperties( + List versions = qi.findObjectsByProperties( ProjectVersion.class, parameters); if (versions == null || versions.size() == 0) { return null; @@ -575,7 +575,7 @@ public static ProjectVersion getFirstProjectVersion(StoredProject sp) { Map parameterMap = new HashMap(); parameterMap.put("sp", sp); - List pvList = dbs.doHQL("from ProjectVersion pv where pv.project=:sp" + List pvList = dbs.getQueryInterface(HQLQueryInterface.class).doHQL("from ProjectVersion pv where pv.project=:sp" + " and pv.sequence = 1", parameterMap); @@ -594,7 +594,7 @@ public static ProjectVersion getLastProjectVersion(StoredProject sp) { Map parameterMap = new HashMap(); parameterMap.put("sp", sp); - List pvList = dbs.doHQL("from ProjectVersion pv where pv.project=:sp" + List pvList = dbs.getQueryInterface(HQLQueryInterface.class).doHQL("from ProjectVersion pv where pv.project=:sp" + " and pv.sequence = (select max(pv2.sequence) from " + " ProjectVersion pv2 where pv2.project=:sp)", parameterMap); @@ -622,7 +622,7 @@ public static ProjectVersion getLastMeasuredVersion(Metric m, StoredProject p) { params.put("metric", m); params.put("project", p); List pv = (List) - AlitheiaCore.getInstance().getDBService().doHQL( query, params, 1); + AlitheiaCore.getInstance().getDBService().getQueryInterface(HQLQueryInterface.class).doHQL( query, params, 1); if (pv.isEmpty()) return null; @@ -651,7 +651,7 @@ public long getFilesCount(ProjectFileState state) { Map parameters = new HashMap(); parameters.put(parVersionId, this); parameters.put(parFileStatus, state); - List queryResult = dbs.doHQL(query, parameters); + List queryResult = dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, parameters); // Return the query's result (if found) if(queryResult != null || queryResult.size() > 0) return (Long) queryResult.get(0); @@ -700,7 +700,7 @@ public long getLiveFilesCount() { params.put(paramIsDirectory, Boolean.FALSE); params.put(paramState, ProjectFileState.deleted()); - return (Long) dbs.doHQL(q.toString(), params).get(0); + return (Long) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(q.toString(), params).get(0); } @@ -762,7 +762,7 @@ private List getVersionFiles(Directory d, int mask) { params.put(paramIsDirectory, isDirectory); } - List projectFiles = (List) dbs.doHQL(q.toString(), params); + List projectFiles = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(q.toString(), params); if (projectFiles == null) return Collections.emptyList(); @@ -876,11 +876,11 @@ public List allFiles() { * Return true if this version's actions generated a tag. */ public boolean isTag() { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map props = new HashMap(); props.put("projectVersion", this); - List tags = dbs.findObjectsByProperties(Tag.class, props); + List tags = qi.findObjectsByProperties(Tag.class, props); if (tags.isEmpty()) return false; diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/QueryInterface.java b/alitheia/core/src/main/java/eu/sqooss/service/db/QueryInterface.java new file mode 100644 index 000000000..65abb0726 --- /dev/null +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/QueryInterface.java @@ -0,0 +1,118 @@ +package eu.sqooss.service.db; + +import java.util.List; +import java.util.Map; + +public interface QueryInterface { + + /** + * A generic query method to retrieve a single DAObject subclass using its identifier. + * The return value is parameterized to the actual type of DAObject queried + * so no downcast is needed. + * @param daoClass the actual class of the DAObject. + * @param id the DAObject's identifier + * @return the DAOObject if a match for the class and the identifier was found in the database, + * or null otherwise or if a database access error occured + */ + public T findObjectById(Class daoClass, long id); + + /** + * A generic query method to retrieve a single DAObject subclass using its identifier and + * acquire a pessimistic row-level database lock on it. + * This results in an SQL query with the form "SELECT ... FOR UPDATE". + * You may use this method to ensure that no other session can modify the returned object + * while the current session is active. This can help avoiding database-level deadlocks + * when multiple sessions access and modify the same table in parallel. + * The return value is parameterized to the actual type of DAObject queried + * so no downcast is needed. + * @param daoClass the actual class of the DAObject. + * @param id the DAObject's identifier + * @return the DAOObject if a match for the class and the identifier was found in the database, + * or null otherwise or if a database access error occured + */ + public T findObjectByIdForUpdate(Class daoClass, long id); + + /** + * A generic query method to retrieve a list of DAObjects of a same subclass + * matching a set of properties. + * The returned list contains the objects matching all of the properties specified. + * It is parameterized to the actual type of DAObject queried so no downcast is needed. + * The map key should be the property name as a string, and the value should be a value + * with a matching type for the property. For example, if a class has a String property + * called name (ie. a getName()/setName() accessor pair), then you would use "name" as + * the map key and a String object as the map value. + * If any property in the map isn't valid (either an unknown name or a value of the wrong type) + * the call will fail and an empty list will be returned. + * It uses its own session. + * + * @param daoClass the actual class of the DAObjects + * @param properties a map of property name/value pairs corresponding to properties + * of the DAObject subclass + * @return a list of DAObjects matching the class and the set of properties, + * possibly empty if no match was found in the database or if the properties map + * contains invalid entries or if a database access error occured + */ + public List findObjectsByProperties(Class daoClass, + Map properties ); + + /** + * A generic query method to retrieve a list of DAObjects of a same subclass + * matching a set of properties and acquire a pessimistic row-level database lock + * on each returned object in the list. + * This results in an SQL query with the form "SELECT ... FOR UPDATE". + * You may use this method to ensure that no other session can modify the returned objects + * while the current session is active. This can help avoiding database-level deadlocks + * when multiple sessions access and modify the same table in parallel. + * The returned list contains the objects matching all of the properties specified. + * It is parameterized to the actual type of DAObject queried so no downcast is needed. + * The map key should be the property name as a string, and the value should be a value + * with a matching type for the property. For example, if a class has a String property + * called name (ie. a getName()/setName() accessor pair), then you would use "name" as + * the map key and a String object as the map value. + * If any property in the map isn't valid (either an unknown name or a value of the wrong type) + * the call will fail and an empty list will be returned. + * It uses its own session. + * + * @param daoClass the actual class of the DAObjects + * @param properties a map of property name/value pairs corresponding to properties + * of the DAObject subclass + * @return a list of DAObjects matching the class and the set of properties, + * possibly empty if no match was found in the database or if the properties map + * contains invalid entries or if a database access error occured + */ + public List findObjectsByPropertiesForUpdate(Class daoClass, + Map properties ); + + /** + * Add a new record to the database, including all the associations the record may contain. + * + * @param record the record to persist into the database + * @return true if the record insertion succeeded, false otherwise + */ + public boolean addRecord(DAObject record); + + /** + * Add multiple new records to the database. + * + * @param records the list of records to persist into the database + * @return true if all the record insertions succeeded, false otherwise + */ + public boolean addRecords(List records); + + /** + * Delete an existing record from the database. + * + * @param record the record to remove from the database + * @return true if the record deletion succeeded, false otherwise + */ + public boolean deleteRecord(DAObject record); + + /** + * Delete multiple existing records from the database. + * + * @param records the list of records to remove from the database + * @return true if all the record deletions succeeded, false otherwise + */ + public boolean deleteRecords(List records); + +} diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/QueryInterfaceFactory.java b/alitheia/core/src/main/java/eu/sqooss/service/db/QueryInterfaceFactory.java new file mode 100644 index 000000000..cfc7eaea4 --- /dev/null +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/QueryInterfaceFactory.java @@ -0,0 +1,18 @@ +package eu.sqooss.service.db; + +import org.hibernate.SessionFactory; + +public interface QueryInterfaceFactory { + + /** + * Constructs a new QueryInterface of type T, with references to internal + * database structures. + * @param dbService the database service + * @param sessionFactory the Hibernate session factory + * @param sessionValidation the database error handling interface + * @return a new QueryInterface + */ + public T build(DBService dbService, SessionFactory sessionFactory, + DBSessionValidation sessionValidation); + +} diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/SQLQueryInterface.java b/alitheia/core/src/main/java/eu/sqooss/service/db/SQLQueryInterface.java new file mode 100644 index 000000000..236778916 --- /dev/null +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/SQLQueryInterface.java @@ -0,0 +1,73 @@ +package eu.sqooss.service.db; + +import java.sql.SQLException; +import java.util.List; +import java.util.Map; + +import org.hibernate.QueryException; + +/** + * NOTE: This QueryInterface is deprecated in favor of HQLQueryInterface. + */ +@Deprecated +public interface SQLQueryInterface extends QueryInterface { + + /** + * Execute a complete SQL query to the database. + * This allows low-level manipulation of the database contents outside of the DAO types. + * To limit risks of SQL injection exploits, please do not execute queries like + * "SELECT * FROM " + tableName. + * If you need dynamic SQL queries, please use the overload with the params argument. + * + * @param sql the sql query string + * @return a list of records. If the query contains multiple columns, + * the results are returned in an instance of Object[] + * @throws SQLException if the query is invalid or a database access error occurs + * + * @see doSQL(String sql, Map params) + * @deprecated + */ + @Deprecated + public List doSQL(String sql) + throws SQLException; + + /** + * Execute a parameterized SQL query to the database. + * This allows low-level manipulation of the database contents outside of the DAO types. + * + * @param sql the sql query string + * @param params the map of parameters to be substituted in the SQL query + * @return a list of records. If the query contains multiple columns, + * the results are returned in an instance of Object[] + * @throws SQLException if the query is invalid or a database access error occurs + * @throws QueryException if some parameters are missing + * @deprecated + */ + @Deprecated + public List doSQL(String sql, Map params) + throws SQLException, QueryException; + + /** + * Execute a named stored procedure. Stored procedures in general should be + * avoided as much as possible as they harm portability and this is why + * this method is marked as deprecated. For the same reason this method only + * returns an integer and not a cursor, as one should expect. + * In some cases however, e.g. when doing large batch updates or when + * moving large volumes, stored procedures can speed up things. To maintain + * portability, there must always be an alternative execution path that + * does not involve calling a stored procedure. + * + * @param sql The name of the procedure to call (case sensitive) + * @param arglist Names for the stored procedure arguments, order must be the + * same as in the stored procedure itself. + * @param params The map of parameters to be substituted in the SQL query + * @return The number of rows affected by the execution of the procedure. + * @throws SQLException if the stored procedure execution fails for some reason. + * @throws QueryException if some parameters are missing + * @deprecated + */ + @Deprecated + public int callProcedure(String procName, List arglist, Map params) + throws SQLException, QueryException; + +} diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/StoredProject.java b/alitheia/core/src/main/java/eu/sqooss/service/db/StoredProject.java index bb9a794d9..3a5424c1d 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/StoredProject.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/StoredProject.java @@ -332,7 +332,7 @@ public void addConfig(ConfigOption co, String value) { private void updateConfigValue (ConfigOption configOpt, String key, String value, boolean update) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); ConfigurationOption co = null; if (configOpt == null) { @@ -340,7 +340,7 @@ private void updateConfigValue (ConfigOption configOpt, String key, if (co == null) { co = new ConfigurationOption(key, ""); - dbs.addRecord(co); + qi.addRecord(co); } } else { co = ConfigurationOption.fromKey(configOpt.getName()); @@ -348,7 +348,7 @@ private void updateConfigValue (ConfigOption configOpt, String key, if (co == null) { co = new ConfigurationOption(configOpt.getName(), configOpt.getDesc()); - dbs.addRecord(co); + qi.addRecord(co); } } @@ -373,11 +373,11 @@ private void updateConfigValue (ConfigOption configOpt, String key, * @return StoredProject object or null if not found */ public static StoredProject getProjectByName(String name) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map parameterMap = new HashMap(); parameterMap.put("name",name); - List prList = dbs.findObjectsByProperties(StoredProject.class, parameterMap); + List prList = qi.findObjectsByProperties(StoredProject.class, parameterMap); return (prList == null || prList.isEmpty()) ? null : prList.get(0); } @@ -388,7 +388,7 @@ public static StoredProject getProjectByName(String name) { */ public static int getProjectCount() { DBService dbs = AlitheiaCore.getInstance().getDBService(); - List l = dbs.doHQL("SELECT COUNT(*) FROM StoredProject"); + List l = dbs.getQueryInterface(HQLQueryInterface.class).doHQL("SELECT COUNT(*) FROM StoredProject"); if ((l == null) || (l.size() < 1)) { return 0; } @@ -408,7 +408,7 @@ public long getVersionsCount() { Map parameterMap = new HashMap(); parameterMap.put("pid", this.getId()); - List pvList = dbs.doHQL("select count(*)" + List pvList = dbs.getQueryInterface(HQLQueryInterface.class).doHQL("select count(*)" + " from ProjectVersion pv" + " where pv.project.id=:pid", parameterMap); @@ -429,7 +429,7 @@ public long getMailsCount() { Map parameterMap = new HashMap(); parameterMap.put("pid", this.getId()); - List res = dbs.doHQL("select count(*)" + List res = dbs.getQueryInterface(HQLQueryInterface.class).doHQL("select count(*)" + " from MailMessage mm, MailingList ml" + " where ml.storedProject.id=:pid" + " and mm.list.id=ml.id", @@ -449,7 +449,7 @@ public long getBugsCount() { Map parameterMap = new HashMap(); parameterMap.put("pid", this.getId()); - List res = dbs.doHQL("select count(*)" + List res = dbs.getQueryInterface(HQLQueryInterface.class).doHQL("select count(*)" + " from Bug bg" + " where bg.project.id=:pid" + " and bg.status.status='" + Status.NEW + "'", diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/StoredProjectConfig.java b/alitheia/core/src/main/java/eu/sqooss/service/db/StoredProjectConfig.java index 7cb8e8942..344c00146 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/StoredProjectConfig.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/StoredProjectConfig.java @@ -115,11 +115,11 @@ public void setValue(String value) { } public static List fromProject(StoredProject sp) { - DBService dbs = AlitheiaCore.getInstance().getDBService(); + QueryInterface qi = AlitheiaCore.getInstance().getDBService().getQueryInterface(); Map params = new HashMap(); params.put("project", sp); - return dbs.findObjectsByProperties(StoredProjectConfig.class, params); + return qi.findObjectsByProperties(StoredProjectConfig.class, params); } } diff --git a/alitheia/core/src/main/java/eu/sqooss/service/db/Tag.java b/alitheia/core/src/main/java/eu/sqooss/service/db/Tag.java index 95d4a59e3..af1b3d113 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/db/Tag.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/db/Tag.java @@ -128,7 +128,7 @@ public static ProjectVersion getProjectVersionForNamedTag(String tagName, parameters.put(paramTagName, tagName); parameters.put(paramProject, sp); - List projectVersions = dbs.doHQL(query, parameters, 1); + List projectVersions = dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, parameters, 1); if (projectVersions == null || projectVersions.size() == 0) { return null; @@ -150,7 +150,7 @@ public static List getTaggedVersions(StoredProject sp) { Map parameters = new HashMap(); parameters.put(paramProject, sp); - return (List) dbs.doHQL(query, parameters); + return (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, parameters); } diff --git a/alitheia/core/src/main/java/eu/sqooss/service/pa/PluginInfo.java b/alitheia/core/src/main/java/eu/sqooss/service/pa/PluginInfo.java index 6ea33d4f5..03365a691 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/pa/PluginInfo.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/pa/PluginInfo.java @@ -40,11 +40,13 @@ import org.osgi.framework.Constants; import org.osgi.framework.ServiceReference; +import eu.sqooss.core.AlitheiaCore; import eu.sqooss.service.abstractmetric.AlitheiaPlugin; import eu.sqooss.service.db.DAObject; import eu.sqooss.service.db.DBService; import eu.sqooss.service.db.Plugin; import eu.sqooss.service.db.PluginConfiguration; +import eu.sqooss.service.db.QueryInterface; import eu.sqooss.service.util.StringUtils; /** @@ -301,7 +303,7 @@ else if (type.equals(ConfigurationType.DOUBLE)) { } // Update the given configuration property - pc = db.attachObjectToDBSession(pc); + pc = db.getSessionManager().attachObjectToDBSession(pc); pc.setValue(newVal); return true; } @@ -412,14 +414,16 @@ public boolean removeConfigEntry( || (ConfigurationType.fromString(type) == null)) { throw new Exception("Invalid type!"); } + + QueryInterface qi = db.getQueryInterface(); // Get the property's Id Long propId = getConfPropId(name, type); if (propId != null) { // Remove the specified configuration property - PluginConfiguration prop = db.findObjectById( + PluginConfiguration prop = qi.findObjectById( PluginConfiguration.class, propId); - if ((prop != null) && (db.deleteRecord(prop))) { + if ((prop != null) && (qi.deleteRecord(prop))) { return true; } } diff --git a/alitheia/core/src/main/java/eu/sqooss/service/scheduler/Job.java b/alitheia/core/src/main/java/eu/sqooss/service/scheduler/Job.java index 62e9745cc..fa59951a5 100644 --- a/alitheia/core/src/main/java/eu/sqooss/service/scheduler/Job.java +++ b/alitheia/core/src/main/java/eu/sqooss/service/scheduler/Job.java @@ -222,9 +222,9 @@ final public long execute() throws Exception { restart(); /*Idiot/bad programmer proofing*/ - assert (!dbs.isDBSessionActive()); - if (dbs.isDBSessionActive()) { - dbs.rollbackDBSession(); + assert (!dbs.getSessionManager().isDBSessionActive()); + if (dbs.getSessionManager().isDBSessionActive()) { + dbs.getSessionManager().rollbackDBSession(); setState(State.Error); //No uncommitted sessions are tolerated } else { if (state() != State.Yielded) @@ -232,8 +232,8 @@ final public long execute() throws Exception { } } catch(Exception e) { - if (dbs.isDBSessionActive()) { - dbs.rollbackDBSession(); + if (dbs.getSessionManager().isDBSessionActive()) { + dbs.getSessionManager().rollbackDBSession(); } // In case of an exception, state becomes Error @@ -505,17 +505,17 @@ public long resume() throws Exception { setState(State.Running); resumePoint.resume(); - assert (!dbs.isDBSessionActive()); - if (dbs.isDBSessionActive()) { - dbs.rollbackDBSession(); + assert (!dbs.getSessionManager().isDBSessionActive()); + if (dbs.getSessionManager().isDBSessionActive()) { + dbs.getSessionManager().rollbackDBSession(); setState(State.Error); //No uncommitted sessions are tolerated } else { setState(State.Finished); } } catch(Exception e) { - if (dbs.isDBSessionActive()) { - dbs.rollbackDBSession(); + if (dbs.getSessionManager().isDBSessionActive()) { + dbs.getSessionManager().rollbackDBSession(); } // In case of an exception, state becomes Error diff --git a/alitheia/core/src/test/java/eu/sqooss/admin/test/AdminServiceImplTest.java b/alitheia/core/src/test/java/eu/sqooss/admin/test/AdminServiceImplTest.java index 9edc33bc6..5400b2426 100644 --- a/alitheia/core/src/test/java/eu/sqooss/admin/test/AdminServiceImplTest.java +++ b/alitheia/core/src/test/java/eu/sqooss/admin/test/AdminServiceImplTest.java @@ -1,10 +1,12 @@ package eu.sqooss.admin.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import java.util.Set; -import org.junit.BeforeClass; +import org.junit.Before; import org.junit.Test; import eu.sqooss.impl.service.admin.AdminServiceImpl; @@ -15,14 +17,29 @@ public class AdminServiceImplTest { - static AdminServiceImpl impl; - static long failid; - static long successid; + private AdminServiceImpl impl; + private long failid; + private long successid; - @BeforeClass - public static void setUp() { + @Before + public void setUp() { impl = new AdminServiceImpl(); } + + private void setUpRunTimeInfo() { + RunTimeInfo rti = new RunTimeInfo(); + impl.registerAdminAction(rti.mnemonic(), RunTimeInfo.class); + } + + private void setUpFailingAction() { + FailingAction fa = new FailingAction(); + impl.registerAdminAction(fa.mnemonic(), FailingAction.class); + } + + private void setUpSucceedingAction() { + SucceedingAction su = new SucceedingAction(); + impl.registerAdminAction(su.mnemonic(), SucceedingAction.class); + } @Test public void testAdminServiceImpl() { @@ -31,21 +48,18 @@ public void testAdminServiceImpl() { @Test public void testRegisterAdminAction() { - RunTimeInfo rti = new RunTimeInfo(); - impl.registerAdminAction(rti.mnemonic(), RunTimeInfo.class); - assertEquals(1, impl.getAdminActions().size()); - - FailingAction fa = new FailingAction(); - impl.registerAdminAction(fa.mnemonic(), FailingAction.class); - assertEquals(2, impl.getAdminActions().size()); - - SucceedingAction su = new SucceedingAction(); - impl.registerAdminAction(su.mnemonic(), SucceedingAction.class); + setUpRunTimeInfo(); + setUpFailingAction(); + setUpSucceedingAction(); assertEquals(3, impl.getAdminActions().size()); } @Test public void testGetAdminActions() { + setUpRunTimeInfo(); + setUpFailingAction(); + setUpSucceedingAction(); + Set actions = impl.getAdminActions(); for (AdminAction aa : actions) assertNotNull (aa); @@ -53,6 +67,8 @@ public void testGetAdminActions() { @Test public void testCreate() { + setUpFailingAction(); + AdminAction fail = impl.create("blah"); assertNull(fail); @@ -70,6 +86,9 @@ public void testCreate() { @Test public void testExecute() { + setUpSucceedingAction(); + setUpFailingAction(); + AdminAction success = impl.create("win"); assertNotNull(success); impl.execute(success); @@ -91,6 +110,7 @@ public void testExecute() { @Test public void testShow() { + testExecute(); AdminAction aa = impl.show(failid); assertNotNull(aa); @@ -100,6 +120,7 @@ public void testShow() { @Test public void testGC() { + testExecute(); try { Thread.sleep (300); } catch (InterruptedException e) {} diff --git a/alitheia/core/src/test/java/eu/sqooss/test/service/db/DBObject.java b/alitheia/core/src/test/java/eu/sqooss/test/service/db/DBObject.java new file mode 100644 index 000000000..df0e4bc0a --- /dev/null +++ b/alitheia/core/src/test/java/eu/sqooss/test/service/db/DBObject.java @@ -0,0 +1,63 @@ +package eu.sqooss.test.service.db; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import eu.sqooss.service.db.DAObject; + +@Entity +@Table(name="DBOBJECT") +public class DBObject extends DAObject { + + @Id + @GeneratedValue(strategy=GenerationType.AUTO) + @Column(name="OBJECT_ID") + private long id; + + @Column(name="OBJECT_NAME") + private String name; + + // Required for Hibernate + public DBObject() { } + + public DBObject(String name) { + this.name = name; + } + + @Override + public long getId() { + return id; + } + + @Override + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof DBObject)) + return false; + + DBObject other = (DBObject)obj; + + if (other.getId() != getId()) + return false; + if (other.getName() == getName()) + return true; + return other.getName() != null && other.getName().equals(this.getName()); + } + +} diff --git a/alitheia/core/src/test/java/eu/sqooss/test/service/db/DBServiceImplTest.java b/alitheia/core/src/test/java/eu/sqooss/test/service/db/DBServiceImplTest.java new file mode 100644 index 000000000..6e3212414 --- /dev/null +++ b/alitheia/core/src/test/java/eu/sqooss/test/service/db/DBServiceImplTest.java @@ -0,0 +1,89 @@ +package eu.sqooss.test.service.db; + +import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; +import static org.mockito.Mockito.*; + +import org.hibernate.SessionFactory; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import eu.sqooss.impl.service.db.DBServiceImpl; +import eu.sqooss.impl.service.db.HQLQueryInterfaceImpl; +import eu.sqooss.impl.service.db.SQLQueryInterfaceImpl; +import eu.sqooss.service.db.DBService; +import eu.sqooss.service.db.DBSessionValidation; +import eu.sqooss.service.db.HQLQueryInterface; +import eu.sqooss.service.db.QueryInterface; +import eu.sqooss.service.db.QueryInterfaceFactory; +import eu.sqooss.service.db.SQLQueryInterface; + +public class DBServiceImplTest { + + private static InMemoryDatabase db; + private static DBServiceImpl dbs; + + @BeforeClass + public static void setUp() { + db = new InMemoryDatabase(new Class[] { DBObject.class }); + dbs = db.getDatabase(); + } + + @AfterClass + public static void tearDown() { + db.close(); + } + + @Test + public void testGetSessionManager_notNull() { + assertNotNull(dbs.getSessionManager()); + } + + @Test + public void testGetQueryInterface_withoutParameter() { + assertThat(dbs.getQueryInterface(), instanceOf(HQLQueryInterfaceImpl.class)); + } + + @Test + public void testGetQueryInterface_queryInterface() { + assertThat(dbs.getQueryInterface(QueryInterface.class), instanceOf(HQLQueryInterfaceImpl.class)); + } + + @Test + public void testGetQueryInterface_hqlQueryInterface() { + assertThat(dbs.getQueryInterface(HQLQueryInterface.class), instanceOf(HQLQueryInterfaceImpl.class)); + } + + @Test + public void testGetQueryInterface_sqlQueryInterface() { + assertThat(dbs.getQueryInterface(SQLQueryInterface.class), instanceOf(SQLQueryInterfaceImpl.class)); + } + + @Test + public void testGetQueryInterface_unknownInterface() { + assertNull(dbs.getQueryInterface(UnknownQueryInterface.class)); + } + + @Test + public void testRegisterQueryInterface() { + dbs.registerQueryInterface(NewQueryInterface.class, NewQueryInterfaceFactory.class); + + assertThat(dbs.getQueryInterface(NewQueryInterface.class), instanceOf(NewQueryInterface.class)); + } + + private static interface UnknownQueryInterface extends QueryInterface { } + + public static interface NewQueryInterface extends QueryInterface { } + + public static class NewQueryInterfaceFactory implements QueryInterfaceFactory { + + @Override + public NewQueryInterface build(DBService dbService, SessionFactory sessionFactory, + DBSessionValidation sessionValidation) { + return mock(NewQueryInterface.class); + } + + } + +} diff --git a/alitheia/core/src/test/java/eu/sqooss/test/service/db/DBTransactionTest.java b/alitheia/core/src/test/java/eu/sqooss/test/service/db/DBTransactionTest.java new file mode 100644 index 000000000..39e291045 --- /dev/null +++ b/alitheia/core/src/test/java/eu/sqooss/test/service/db/DBTransactionTest.java @@ -0,0 +1,392 @@ +package eu.sqooss.test.service.db; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import org.hibernate.HibernateException; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.hibernate.classic.Session; +import org.junit.Before; +import org.junit.Test; + +import eu.sqooss.impl.service.db.DBServiceImpl; +import eu.sqooss.service.logging.Logger; + +public class DBTransactionTest { + + private DBServiceImpl db; + private Logger l; + + @Before + public void setUp() { + db = new DBServiceImpl(); + l = mock(Logger.class); + } + + @Test + public void testStartDBSession_uninitialised() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + db.prepareForTest(s, false, l); + + boolean result = db.getSessionManager().startDBSession(); + + assertFalse(result); + verifyNoMoreInteractions(s); + } + + @Test + public void testStartDBSession_beginTransactionFailure() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + when(ss.beginTransaction()).thenThrow(new HibernateException("Failed to start transaction")); + + db.prepareForTest(s, true, l); + + boolean result = db.getSessionManager().startDBSession(); + + assertFalse(result); + verify(ss).beginTransaction(); + } + + @Test + public void testStartDBSession_success() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + + db.prepareForTest(s, true, l); + + boolean result = db.getSessionManager().startDBSession(); + + assertTrue(result); + verify(ss).beginTransaction(); + } + + @Test + public void testIsDBSessionActive_uninitialised() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + db.prepareForTest(s, false, l); + + boolean result = db.getSessionManager().isDBSessionActive(); + + assertFalse(result); + verifyNoMoreInteractions(s); + } + + @Test + public void testIsDBSessionActive_noTransaction() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + + db.prepareForTest(s, true, l); + + boolean result = db.getSessionManager().isDBSessionActive(); + + assertFalse(result); + } + + @Test + public void testIsDBSessionActive_transactionException() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + when(ss.getTransaction()).thenThrow(new HibernateException("Failed to get transaction")); + + db.prepareForTest(s, true, l); + + boolean result = db.getSessionManager().isDBSessionActive(); + + assertFalse(result); + verify(ss).close(); + } + + @Test + public void testIsDBSessionActive_transactionInactive() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + + // Create an inactive transaction + Transaction t = mock(Transaction.class); + when(ss.getTransaction()).thenReturn(t); + when(t.isActive()).thenReturn(false); + + db.prepareForTest(s, true, l); + + boolean result = db.getSessionManager().isDBSessionActive(); + + assertFalse(result); + } + + @Test + public void testIsDBSessionActive_true() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + + // Create an active transaction + Transaction t = mock(Transaction.class); + when(ss.getTransaction()).thenReturn(t); + when(t.isActive()).thenReturn(true); + + db.prepareForTest(s, true, l); + + boolean result = db.getSessionManager().isDBSessionActive(); + + assertTrue(result); + } + + @Test + public void testCommitDBSession_withoutActiveSession() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + + db.prepareForTest(s, true, l); + + boolean result = db.getSessionManager().commitDBSession(); + + assertFalse(result); + } + + @Test + public void testCommitDBSession_commitException() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + + // Prepare active transaction + Transaction t = mock(Transaction.class); + when(ss.getTransaction()).thenReturn(t); + when(t.isActive()).thenReturn(true); + doThrow(new HibernateException("Failed to commit transaction")).when(t).commit(); + + db.prepareForTest(s, true, l); + + boolean result = db.getSessionManager().commitDBSession(); + + assertFalse(result); + verify(t).commit(); + verify(t).rollback(); + } + + @Test + public void testCommitDBSession_success() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + + // Prepare active transaction + Transaction t = mock(Transaction.class); + when(ss.getTransaction()).thenReturn(t); + when(t.isActive()).thenReturn(true); + + db.prepareForTest(s, true, l); + + boolean result = db.getSessionManager().commitDBSession(); + + assertTrue(result); + verify(t).commit(); + verify(t, atLeastOnce()).isActive(); + verifyNoMoreInteractions(t); + } + + @Test + public void testRollbackDBSession_withoutActiveSession() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + + db.prepareForTest(s, true, l); + + boolean result = db.getSessionManager().rollbackDBSession(); + + assertFalse(result); + } + + @Test + public void testRollbackDBSession_rollbackException() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + + // Prepare active transaction + Transaction t = mock(Transaction.class); + when(ss.getTransaction()).thenReturn(t); + when(t.isActive()).thenReturn(true); + doThrow(new HibernateException("Failed to commit transaction")).when(t).rollback(); + + db.prepareForTest(s, true, l); + + boolean result = db.getSessionManager().rollbackDBSession(); + + assertFalse(result); + verify(t).rollback(); + verify(t, never()).commit(); + } + + @Test + public void testRollbackDBSession_success() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + + // Prepare active transaction + Transaction t = mock(Transaction.class); + when(ss.getTransaction()).thenReturn(t); + when(t.isActive()).thenReturn(true); + + db.prepareForTest(s, true, l); + + boolean result = db.getSessionManager().rollbackDBSession(); + + assertTrue(result); + verify(t).rollback(); + verify(t, never()).commit(); + } + + @Test + public void testFlushDBSession_withoutActiveSession() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + + db.prepareForTest(s, true, l); + + boolean result = db.getSessionManager().flushDBSession(); + + assertFalse(result); + } + + @Test + public void testFlushDBSession_flushException() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + doThrow(new HibernateException("Failed to flush session")).when(ss).flush(); + + // Prepare transaction + Transaction t = mock(Transaction.class); + when(ss.getTransaction()).thenReturn(t); + when(t.isActive()).thenReturn(true); + + db.prepareForTest(s, true, l); + + boolean result = db.getSessionManager().flushDBSession(); + + assertFalse(result); + } + + @Test + public void testFlushDBSession_success() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + + // Prepare transaction + Transaction t = mock(Transaction.class); + when(ss.getTransaction()).thenReturn(t); + when(t.isActive()).thenReturn(true); + + db.prepareForTest(s, true, l); + + boolean result = db.getSessionManager().flushDBSession(); + + assertTrue(result); + verify(ss).flush(); + verify(ss).clear(); + } + + @Test + public void testAttachObjectToDBSession_withoutSession() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + + db.prepareForTest(s, true, l); + + DBObject obj = db.getSessionManager().attachObjectToDBSession(new DBObject("test-object")); + + assertNull(obj); + } + + @Test + public void testAttachObjectToDBSession_notYetAttached() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + + // Prepare transaction + Transaction t = mock(Transaction.class); + when(ss.getTransaction()).thenReturn(t); + when(t.isActive()).thenReturn(true); + + db.prepareForTest(s, true, l); + + DBObject unbound = new DBObject("test-object"); + DBObject merged = new DBObject("merged-object"); + when(ss.contains(unbound)).thenReturn(false); + when(ss.merge(unbound)).thenReturn(merged); + DBObject obj = db.getSessionManager().attachObjectToDBSession(unbound); + + assertEquals(merged, obj); + + verify(ss).merge(unbound); + } + + @Test + public void testAttachObjectToDBSession_alreadyAttached() { + // Prepare session + SessionFactory s = mock(SessionFactory.class); + Session ss = mock(Session.class); + when(s.getCurrentSession()).thenReturn(ss); + + // Prepare transaction + Transaction t = mock(Transaction.class); + when(ss.getTransaction()).thenReturn(t); + when(t.isActive()).thenReturn(true); + + db.prepareForTest(s, true, l); + + DBObject unbound = new DBObject("test-object"); + when(ss.contains(unbound)).thenReturn(true); + DBObject obj = db.getSessionManager().attachObjectToDBSession(unbound); + + assertSame(unbound, obj); + + verify(ss, never()).merge(unbound); + } + +} diff --git a/alitheia/core/src/test/java/eu/sqooss/test/service/db/HQLQueryInterfaceImplTest.java b/alitheia/core/src/test/java/eu/sqooss/test/service/db/HQLQueryInterfaceImplTest.java new file mode 100644 index 000000000..80c6886bd --- /dev/null +++ b/alitheia/core/src/test/java/eu/sqooss/test/service/db/HQLQueryInterfaceImplTest.java @@ -0,0 +1,12 @@ +package eu.sqooss.test.service.db; + +import eu.sqooss.service.db.HQLQueryInterface; + +public class HQLQueryInterfaceImplTest extends HQLQueryInterfaceTest { + + @Override + protected HQLQueryInterface getHQLQueryInterface() { + return getDB().getHQLInterface(); + } + +} diff --git a/alitheia/core/src/test/java/eu/sqooss/test/service/db/HQLQueryInterfaceTest.java b/alitheia/core/src/test/java/eu/sqooss/test/service/db/HQLQueryInterfaceTest.java new file mode 100644 index 000000000..1f51d1f3b --- /dev/null +++ b/alitheia/core/src/test/java/eu/sqooss/test/service/db/HQLQueryInterfaceTest.java @@ -0,0 +1,267 @@ +package eu.sqooss.test.service.db; + +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.either; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.hibernate.QueryException; +import org.junit.Test; + +import eu.sqooss.service.db.HQLQueryInterface; +import eu.sqooss.service.db.QueryInterface; + +public abstract class HQLQueryInterfaceTest extends QueryInterfaceTest { + + protected abstract HQLQueryInterface getHQLQueryInterface(); + + @Override + protected QueryInterface getQueryInterface() { + return getHQLQueryInterface(); + } + + @Test + public void testDoHQL_selectNoObjects() { + // Insert test object + DBObject obj = new DBObject("object"); + getDB().addTestObject(obj); + + // Select a non-existent object + List objs = getHQLQueryInterface().doHQL("select o from DBObject o where o.name = 'unknown'"); + assertThat(objs, is(empty())); + } + + @Test + public void testDoHQL_selectMultipleObjects() { + // Insert test objects + DBObject objA = new DBObject("object"); + DBObject objB = new DBObject("object"); + DBObject objC = new DBObject("other-object"); + getDB().addTestObject(objA); + getDB().addTestObject(objB); + getDB().addTestObject(objC); + + // Select all objects with name "object" + @SuppressWarnings("unchecked") + List objs = (List) getHQLQueryInterface().doHQL("select o from DBObject o where o.name = 'object'"); + + assertThat(objs, containsInAnyOrder(objA, objB)); + } + + @Test + public void testDoHQL_withParameters() { + // Insert test objects + DBObject objA = new DBObject("object"); + DBObject objB = new DBObject("other-object"); + getDB().addTestObject(objA); + getDB().addTestObject(objB); + + // Select second object using a parameter + Map params = new HashMap<>(); + params.put("nameparam", objB.getName()); + @SuppressWarnings("unchecked") + List objs = (List) getHQLQueryInterface().doHQL( + "select o from DBObject o where o.name = :nameparam", params); + + assertThat(objs, contains(objB)); + } + + @Test(expected = QueryException.class) + public void testDoHQL_withMissingParameters() { + // Insert test objects + DBObject objA = new DBObject("object"); + DBObject objB = new DBObject("other-object"); + getDB().addTestObject(objA); + getDB().addTestObject(objB); + + // Execute query without specifying all parameters + getHQLQueryInterface().doHQL("select o from DBObject o where o.name = :nameparam", new HashMap()); + } + + @Test + public void testDoHQL_withZeroLimit() { + // Insert test objects + DBObject objA = new DBObject("object"); + DBObject objB = new DBObject("object"); + getDB().addTestObject(objA); + getDB().addTestObject(objB); + + // Select one object with name "object" + List objs = getHQLQueryInterface().doHQL( + "select o from DBObject o where o.name = 'object'", new HashMap(), 0); + + assertThat(objs, is(empty())); + } + + @Test + public void testDoHQL_withSmallLimit() { + // Insert test objects + DBObject objA = new DBObject("object"); + DBObject objB = new DBObject("object"); + getDB().addTestObject(objA); + getDB().addTestObject(objB); + + // Select one object with name "object" + @SuppressWarnings("unchecked") + List objs = (List) getHQLQueryInterface().doHQL( + "select o from DBObject o where o.name = 'object'", new HashMap(), 1); + + assertThat(objs, hasSize(1)); + assertThat(objs.get(0), either(equalTo(objA)).or(equalTo(objB))); + } + + @Test + public void testDoHQL_withLargeLimit() { + // Insert test objects + DBObject objA = new DBObject("object"); + DBObject objB = new DBObject("object"); + getDB().addTestObject(objA); + getDB().addTestObject(objB); + + // Select one object with name "object" + @SuppressWarnings("unchecked") + List objs = (List) getHQLQueryInterface().doHQL( + "select o from DBObject o where o.name = 'object'", new HashMap(), 3); + + assertThat(objs, containsInAnyOrder(objA, objB)); + } + + @Test + public void testDoHQL_withNegativeLimit() { + // Insert test objects + DBObject objA = new DBObject("object"); + DBObject objB = new DBObject("object"); + getDB().addTestObject(objA); + getDB().addTestObject(objB); + + // Select one object with name "object" + @SuppressWarnings("unchecked") + List objs = (List) getHQLQueryInterface().doHQL( + "select o from DBObject o where o.name = 'object'", new HashMap(), -1); + + assertThat(objs, containsInAnyOrder(objA, objB)); + } + + @Test + public void testDoHQL_withCollectionParameters() { + // Insert test objects + DBObject objA = new DBObject("object-a"); + DBObject objB = new DBObject("object-b"); + DBObject objC = new DBObject("object-c"); + getDB().addTestObject(objA); + getDB().addTestObject(objB); + getDB().addTestObject(objC); + + // Select second object using a parameter + @SuppressWarnings("rawtypes") + Map params = new HashMap<>(); + params.put("namelist", Arrays.asList(objA.getName(), objB.getName())); + @SuppressWarnings("unchecked") + List objs = (List) getHQLQueryInterface().doHQL( + "select o from DBObject o where o.name in (:namelist)", new HashMap(), params); + + assertThat(objs, containsInAnyOrder(objA, objB)); + } + + @SuppressWarnings("rawtypes") + @Test(expected = QueryException.class) + public void testDoHQL_withMissingCollectionParameters() { + // Insert test objects + DBObject objA = new DBObject("object-a"); + DBObject objB = new DBObject("object-b"); + DBObject objC = new DBObject("object-c"); + getDB().addTestObject(objA); + getDB().addTestObject(objB); + getDB().addTestObject(objC); + + // Select second object using a parameter + getHQLQueryInterface().doHQL("select o from DBObject o where o.name in (:namelist)", + new HashMap(), new HashMap()); + } + + @Test(expected = QueryException.class) + public void testExecuteUpdate_missingParameter() { + // Insert test object + DBObject objA = new DBObject("object"); + getDB().addTestObject(objA); + + // Update the name of the test object + getHQLQueryInterface().executeUpdate("update DBObject set object_name = :newname where object_id = :obj_id", null); + } + + @Test + public void testExecuteUpdate_oneObject() { + // Insert test objects + DBObject objA = new DBObject("object"); + DBObject objB = new DBObject("object"); + getDB().addTestObject(objA); + getDB().addTestObject(objB); + + // Update the name of the test object + Map params = new HashMap<>(); + params.put("newname", "changed"); + params.put("obj_id", objA.getId()); + int rows = getHQLQueryInterface().executeUpdate("update DBObject set name = :newname where id = :obj_id", params); + // Commit the change + getDB().getDatabase().getSessionManager().commitDBSession(); + + try { + // Start a new session to read the changes + getDB().getDatabase().getSessionManager().startDBSession(); + + assertThat(rows, equalTo(1)); + assertThat(getDB().getTestObject(DBObject.class, objA.getId()).getName(), equalTo("changed")); + } catch (Exception e) { + throw e; + } finally { + getDB().getDatabase().getSessionManager().startDBSession(); + getHQLQueryInterface().executeUpdate("delete from DBObject", null); + getDB().getDatabase().getSessionManager().commitDBSession(); + } + } + + @Test + public void testExecuteUpdate_multipleObjects() { + // Insert test objects + DBObject objA = new DBObject("object-a"); + DBObject objB = new DBObject("object-b"); + DBObject objC = new DBObject("object-c"); + getDB().addTestObject(objA); + getDB().addTestObject(objB); + getDB().addTestObject(objC); + + // Update the name of the test object + Map params = new HashMap<>(); + params.put("newname", "changed"); + int rows = getHQLQueryInterface().executeUpdate("update DBObject set name = :newname", params); + // Commit the change + getDB().getDatabase().getSessionManager().commitDBSession(); + + try { + // Start a new session to read the changes + getDB().getDatabase().getSessionManager().startDBSession(); + + assertThat(rows, equalTo(3)); + assertThat(getDB().getTestObject(DBObject.class, objA.getId()).getName(), equalTo("changed")); + assertThat(getDB().getTestObject(DBObject.class, objB.getId()).getName(), equalTo("changed")); + assertThat(getDB().getTestObject(DBObject.class, objC.getId()).getName(), equalTo("changed")); + } catch (Exception e) { + throw e; + } finally { + getDB().getDatabase().getSessionManager().startDBSession(); + getHQLQueryInterface().executeUpdate("delete from DBObject", null); + getDB().getDatabase().getSessionManager().commitDBSession(); + } + } + +} diff --git a/alitheia/core/src/test/java/eu/sqooss/test/service/db/InMemoryDatabase.java b/alitheia/core/src/test/java/eu/sqooss/test/service/db/InMemoryDatabase.java new file mode 100644 index 000000000..f0ea854a9 --- /dev/null +++ b/alitheia/core/src/test/java/eu/sqooss/test/service/db/InMemoryDatabase.java @@ -0,0 +1,125 @@ +package eu.sqooss.test.service.db; + +import java.io.Serializable; + +import org.hibernate.SessionFactory; +import org.hibernate.cfg.AnnotationConfiguration; +import org.mockito.Mockito; + +import eu.sqooss.impl.service.db.DBServiceImpl; +import eu.sqooss.impl.service.db.HQLQueryInterfaceImpl; +import eu.sqooss.service.db.*; +import eu.sqooss.service.logging.Logger; + +public final class InMemoryDatabase { + + private SessionFactory sessionFactory; + private DBServiceImpl db; + + private HQLQueryInterfaceImpl hqlInterface; + + public InMemoryDatabase(Class[] annotatedClasses) { + setUpDatabase(annotatedClasses); + + db = new DBServiceImpl(); + db.prepareForTest(sessionFactory, true, Mockito.mock(Logger.class)); + + hqlInterface = new HQLQueryInterfaceImpl(db.getSessionManager(), (DBSessionValidation)db.getSessionManager(), + sessionFactory, Mockito.mock(Logger.class)); + } + + private void setUpDatabase(Class[] annotatedClasses) { + // setup the session factory + AnnotationConfiguration configuration = new AnnotationConfiguration(); + for (Class annotatedClass : annotatedClasses) + configuration.addAnnotatedClass(annotatedClass); + configuration.setProperty("hibernate.dialect", + "org.hibernate.dialect.H2Dialect"); + configuration.setProperty("hibernate.connection.driver_class", + "org.h2.Driver"); + configuration.setProperty("hibernate.connection.url", "jdbc:h2:mem:"); + configuration.setProperty("hibernate.hbm2ddl.auto", "create"); + configuration.setProperty("hibernate.current_session_context_class", "thread"); + + sessionFactory = configuration.buildSessionFactory(); + } + + public void close() { + sessionFactory.close(); + } + + public SessionFactory getSessionFactory() { + return sessionFactory; + } + + public DBServiceImpl getDatabase() { + return db; + } + + public HQLQueryInterfaceImpl getHQLInterface() { + return hqlInterface; + } + + public void addTestObject(Object obj) { + sessionFactory.getCurrentSession().save(obj); + } + + @SuppressWarnings("unchecked") + public T getTestObject(Class clazz, Serializable id) { + return (T)sessionFactory.getCurrentSession().get(clazz, id); + } + + public void startTransaction() { + sessionFactory.getCurrentSession().beginTransaction(); + } + + public void stopTransaction() { + if (sessionFactory.getCurrentSession().getTransaction() != null && + sessionFactory.getCurrentSession().getTransaction().isActive()) + sessionFactory.getCurrentSession().getTransaction().rollback(); + } + + public static InMemoryDatabase createDefault() { + return new InMemoryDatabase(new Class[] { + Bug.class, + BugStatus.class, + BugReportMessage.class, + BugSeverity.class, + BugPriority.class, + BugResolution.class, + MailingList.class, + MailMessage.class, + MailingListThread.class, + ProjectVersion.class, + ProjectFile.class, + ProjectFileState.class, + Developer.class, + DeveloperAlias.class, + Directory.class, + Tag.class, + Branch.class, + StoredProject.class, + StoredProjectConfig.class, + ConfigurationOption.class, + ClusterNode.class, + Plugin.class, + PluginConfiguration.class, + Metric.class, + MetricType.class, + StoredProjectMeasurement.class, + ProjectVersionMeasurement.class, + ProjectFileMeasurement.class, + MailingListThreadMeasurement.class, + MailMessageMeasurement.class, + OhlohDeveloper.class, + ProjectVersionParent.class, + NameSpace.class, + ExecutionUnit.class, + EncapsulationUnit.class, + NameSpaceMeasurement.class, + ExecutionUnitMeasurement.class, + EncapsulationUnitMeasurement.class + }); + } + +} diff --git a/alitheia/core/src/test/java/eu/sqooss/test/service/db/QueryInterfaceTest.java b/alitheia/core/src/test/java/eu/sqooss/test/service/db/QueryInterfaceTest.java new file mode 100644 index 000000000..b1312e861 --- /dev/null +++ b/alitheia/core/src/test/java/eu/sqooss/test/service/db/QueryInterfaceTest.java @@ -0,0 +1,362 @@ +package eu.sqooss.test.service.db; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import eu.sqooss.service.db.QueryInterface; + +public abstract class QueryInterfaceTest { + + private static final String objNameA = "test-object-a"; + private static final String objNameB = "test-object-b"; + private static final String objNameC = "test-object-c"; + private static final String objNameD = "test-object-d"; + + private static InMemoryDatabase db; + + protected InMemoryDatabase getDB() { + return db; + } + + protected abstract QueryInterface getQueryInterface(); + + @BeforeClass + public static void setUp() { + db = new InMemoryDatabase(new Class[] { DBObject.class }); + } + + @AfterClass + public static void tearDown() { + db.close(); + } + + @Before + public void beginTransaction() { + db.startTransaction(); + } + + @After + public void closeTransaction() { + db.stopTransaction(); + } + + @Test + public void testAddRecord() { + DBObject obj = new DBObject(objNameA); + + // Store the object and assert that it succeeded + boolean result = getQueryInterface().addRecord(obj); + assertTrue(result); + + // Retrieve + DBObject storedObj = db.getTestObject(DBObject.class, obj.getId()); + assertEquals(obj, storedObj); + } + + @Test + public void testAddRecord_no_active_session() { + DBObject obj = new DBObject(objNameA); + + // Make sure there is no active transaction + closeTransaction(); + + // Store the object and assert that it succeeded + boolean result = getQueryInterface().addRecord(obj); + assertFalse(result); + + beginTransaction(); //necessary for closeTransaction() to succeed + } + + @Test + public void testAddRecord_multiple() { + DBObject objA = new DBObject(objNameA); + DBObject objB = new DBObject(objNameB); + + // Store both objects and assert that it succeeded + boolean result = getQueryInterface().addRecord(objA); + assertTrue(result); + result = getQueryInterface().addRecord(objB); + assertTrue(result); + + // Check that both objects have different IDs + assertThat(objA.getId(), not(equalTo(objB.getId()))); + + // Attempt to retrieve both objects + DBObject storedObjA = db.getTestObject(DBObject.class, objA.getId()); + DBObject storedObjB = db.getTestObject(DBObject.class, objB.getId()); + assertEquals(objA, storedObjA); + assertEquals(objB, storedObjB); + } + + @Test + public void testDeleteRecord() { + DBObject obj = new DBObject(objNameA); + + // Store the object and assert that it succeeded + boolean result = getQueryInterface().addRecord(obj); + assertTrue(result); + + // Retrieve the object + DBObject storedObj = db.getTestObject(DBObject.class, obj.getId()); + assertEquals(obj, storedObj); + + // Delete the record + result = getQueryInterface().deleteRecord(obj); + assertTrue(result); + + // Check whether it is actually deleted + storedObj = db.getTestObject(DBObject.class, obj.getId()); + assertNull(storedObj); + } + + @Test + public void testDeleteRecord_no_active_session() { + DBObject obj = new DBObject(objNameA); + + // Store the object and assert that it succeeded + boolean result = getQueryInterface().addRecord(obj); + assertTrue(result); + + // Retrieve the object + DBObject storedObj = db.getTestObject(DBObject.class, obj.getId()); + assertEquals(obj, storedObj); + + // Make sure there is no active transaction + closeTransaction(); + + // Delete the record + result = getQueryInterface().deleteRecord(obj); + assertFalse(result); + + beginTransaction(); //necessary for closeTransaction() to succeed + } + + @Test + public void testDeleteRecord_multiple_adds_one_delete() { + DBObject objA = new DBObject(objNameA); + DBObject objB = new DBObject(objNameB); + + // Store both objects and assert that it succeeded + boolean result = getQueryInterface().addRecord(objA); + assertTrue(result); + result = getQueryInterface().addRecord(objB); + assertTrue(result); + + // Attempt to retrieve both objects + DBObject storedObjA = db.getTestObject(DBObject.class, objA.getId()); + DBObject storedObjB = db.getTestObject(DBObject.class, objB.getId()); + assertEquals(objA, storedObjA); + assertEquals(objB, storedObjB); + + // Delete the record for objA + result = getQueryInterface().deleteRecord(objA); + assertTrue(result); + + // Check whether only objA is deleted + storedObjA = db.getTestObject(DBObject.class, objA.getId()); + assertNull(storedObjA); + storedObjB = db.getTestObject(DBObject.class, objB.getId()); + assertEquals(objB, storedObjB); + } + + @Test + public void testFindObjectById_success(){ + DBObject objC = new DBObject(objNameC); + + // Store object and verify it succeeded + boolean result = getQueryInterface().addRecord(objC); + assertTrue(result); + + // Check whether the findObjectById function returns the correct object + DBObject storedObjC = (DBObject)getQueryInterface().findObjectById(DBObject.class, objC.getId()); + assertEquals(objC, storedObjC); + } + + @Test + public void testFindObjectById_no_active_session(){ + DBObject objC = new DBObject(objNameC); + + // Store object and verify it succeeded + boolean result = getQueryInterface().addRecord(objC); + assertTrue(result); + + // Make sure there is no active transaction + closeTransaction(); + + // Check whether the findObjectById function returns null + DBObject storedObjC = (DBObject)getQueryInterface().findObjectById(DBObject.class, objC.getId()); + assertNull(storedObjC); + + beginTransaction(); //necessary for closeTransaction() to succeed + } + + @Test + public void testFindObjectByIdForUpdate(){ + DBObject objD = new DBObject(objNameD); + + // Store object and verify it succeeded + boolean result = getQueryInterface().addRecord(objD); + assertTrue(result); + + // Check whether the findObjectByIdForUpdate function returns the correct object + DBObject storedObjD = (DBObject)getQueryInterface().findObjectByIdForUpdate(DBObject.class, objD.getId()); + assertEquals(objD, storedObjD); + } + + @Test + public void testFindObjectsByProperties_single_property(){ + DBObject objD = new DBObject(objNameD); + + // Store object and verify it succeeded + boolean result = getQueryInterface().addRecord(objD); + assertTrue(result); + + // Create a map with properties of objD + Map properties = new HashMap(); + properties.put("name", objNameD); + + // Check whether the findObjectsByProperties function returns a list with only objD in it + List res = getQueryInterface().findObjectsByProperties(DBObject.class, properties); + assertEquals(1, res.size()); + assertEquals(objD, res.get(0)); + } + + @Test + public void testFindObjectsByProperties_no_active_session(){ + DBObject objD = new DBObject(objNameD); + + // Store object and verify it succeeded + boolean result = getQueryInterface().addRecord(objD); + assertTrue(result); + + // Make sure there is no active transaction + closeTransaction(); + + // Create a map with properties of objD + Map properties = new HashMap(); + properties.put("name", objNameD); + + // Check whether the findObjectsByProperties function returns the empty list + List res = getQueryInterface().findObjectsByProperties(DBObject.class, properties); + assertEquals(Collections.emptyList(),res); + + beginTransaction(); //necessary for closeTransaction() to succeed + } + + @Test + public void testFindObjectsByProperties_multiple_properties(){ + DBObject objD = new DBObject(objNameD); + + // Store object and verify it succeeded + boolean result = getQueryInterface().addRecord(objD); + assertTrue(result); + + // Create a map with properties of objD + Map properties = new HashMap(); + properties.put("id", objD.getId()); + properties.put("name", objNameD); + + // Check whether the findObjectsByProperties function returns a list with only objD in it + List res = getQueryInterface().findObjectsByProperties(DBObject.class, properties); + assertEquals(1, res.size()); + assertEquals(objD, res.get(0)); + } + + @Test + public void testFindObjectsByProperties_multiple_results(){ + DBObject objD = new DBObject(objNameD); + DBObject objD2 = new DBObject(objNameD); + + // Store objects and verify it succeeded + boolean result = getQueryInterface().addRecord(objD); + assertTrue(result); + result = getQueryInterface().addRecord(objD2); + assertTrue(result); + + // Create a map with the common name property of objD and objD2 + Map properties = new HashMap(); + properties.put("name", objNameD); + + // Check whether the findObjectsByProperties function returns a list with only objD and objD2 in it + List res = getQueryInterface().findObjectsByProperties(DBObject.class, properties); + assertEquals(2, res.size()); + assertTrue(res.contains(objD)); + assertTrue(res.contains(objD2)); + } + + @Test + public void testFindObjectsByPropertiesForUpdate_single_property(){ + DBObject objD = new DBObject(objNameD); + + // Store object and verify it succeeded + boolean result = getQueryInterface().addRecord(objD); + assertTrue(result); + + // Create a map with properties of objD + Map properties = new HashMap(); + properties.put("name", objNameD); + + // Check whether the findObjectsByPropertiesForUpdate function returns a list with only objD in it + List res = getQueryInterface().findObjectsByPropertiesForUpdate(DBObject.class, properties); + assertEquals(1, res.size()); + assertEquals(objD, res.get(0)); + } + + @Test + public void testFindObjectsByPropertiesForUpdate_multiple_properties(){ + DBObject objD = new DBObject(objNameD); + + // Store object and verify it succeeded + boolean result = getQueryInterface().addRecord(objD); + assertTrue(result); + + // Create a map with properties of objD + Map properties = new HashMap(); + properties.put("id", objD.getId()); + properties.put("name", objNameD); + + // Check whether the findObjectsByPropertiesForUpdate function returns a list with only objD in it + List res = getQueryInterface().findObjectsByPropertiesForUpdate(DBObject.class, properties); + assertEquals(1, res.size()); + assertEquals(objD, res.get(0)); + } + + @Test + public void testFindObjectsByPropertiesForUpdate_multiple_results(){ + DBObject objD = new DBObject(objNameD); + DBObject objD2 = new DBObject(objNameD); + + // Store objects and verify it succeeded + boolean result = getQueryInterface().addRecord(objD); + assertTrue(result); + result = getQueryInterface().addRecord(objD2); + assertTrue(result); + + // Create a map with the common name property of objD and objD2 + Map properties = new HashMap(); + properties.put("name", objNameD); + + // Check whether the findObjectsByPropertiesForUpdate function returns a list with only objD and objD2 in it + List res = getQueryInterface().findObjectsByPropertiesForUpdate(DBObject.class, properties); + assertEquals(2, res.size()); + assertTrue(res.contains(objD)); + assertTrue(res.contains(objD2)); + } + +} diff --git a/alitheia/core/src/test/java/eu/sqooss/test/service/db/objects/ConfigurationOptionTest.java b/alitheia/core/src/test/java/eu/sqooss/test/service/db/objects/ConfigurationOptionTest.java new file mode 100644 index 000000000..18d30767b --- /dev/null +++ b/alitheia/core/src/test/java/eu/sqooss/test/service/db/objects/ConfigurationOptionTest.java @@ -0,0 +1,240 @@ +package eu.sqooss.test.service.db.objects; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; +import static org.hamcrest.Matchers.*; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import eu.sqooss.core.AlitheiaCore; +import eu.sqooss.service.db.*; +import eu.sqooss.test.service.db.InMemoryDatabase; + +public class ConfigurationOptionTest { + + private static DBService db; + private static QueryInterface qi; + + @BeforeClass + public static void initializeDatabase() { + db = InMemoryDatabase.createDefault().getDatabase(); + qi = db.getQueryInterface(); + AlitheiaCore ac = mock(AlitheiaCore.class); + + when(ac.getDBService()).thenReturn(db); + + AlitheiaCore.setTestInstance(ac); + } + + @AfterClass + public static void tearDown() { + db.shutDown(); + } + + @Before + public void beginTransaction() { + db.getSessionManager().startDBSession(); + } + + @After + public void closeTransaction() { + db.getSessionManager().rollbackDBSession(); + } + + @Test + public void testGetValues_nonExistentProject() { + // Create test objects + ConfigurationOption opt = new ConfigurationOption("opt", "A sample option"); + qi.addRecord(opt); + + // Read the test object from the database, and look up its values + ConfigurationOption cfgOpt = qi.findObjectById(ConfigurationOption.class, opt.getId()); + List values = cfgOpt.getValues(new StoredProject()); + + assertThat(values, is(empty())); + } + + @Test + public void testSetValues_singleProjectNoValues() { + // Create test objects + ConfigurationOption opt = new ConfigurationOption("opt", "A sample option"); + StoredProject sp = new StoredProject("sp1"); + qi.addRecord(opt); + qi.addRecord(sp); + + // Add no values + opt.setValues(sp, Collections. emptyList(), false); + + // Read the test object from the database, and look up its values + ConfigurationOption cfgOpt = qi.findObjectById(ConfigurationOption.class, opt.getId()); + List values = cfgOpt.getValues(sp); + + assertThat(values, is(empty())); + } + + @Test + public void testSetValues_singleProjectSomeValues() { + // Create test objects + ConfigurationOption opt = new ConfigurationOption("opt", "A sample option"); + StoredProject sp = new StoredProject("sp1"); + qi.addRecord(opt); + qi.addRecord(sp); + + // Add some values + List values = Arrays.asList("valueA", "valueB"); + opt.setValues(sp, values, false); + + // Read the test object from the database, and look up its values + ConfigurationOption cfgOpt = qi.findObjectById(ConfigurationOption.class, opt.getId()); + List readValues = cfgOpt.getValues(sp); + + assertThat(readValues, containsInAnyOrder(values.toArray(new String[2]))); + } + + @Test + public void testSetValues_singleProjectMultipleTimes() { + // Create test objects + ConfigurationOption opt = new ConfigurationOption("opt", "A sample option"); + StoredProject sp = new StoredProject("sp1"); + qi.addRecord(opt); + qi.addRecord(sp); + + // Add some values + List values = Arrays.asList("valueA", "valueB"); + opt.setValues(sp, values, false); + // Add some more values + List moreValues = Arrays.asList("valueC", "valueD"); + opt.setValues(sp, moreValues, false); + + // Read the test object from the database, and look up its values + ConfigurationOption cfgOpt = qi.findObjectById(ConfigurationOption.class, opt.getId()); + List readValues = cfgOpt.getValues(sp); + + assertThat(readValues, containsInAnyOrder("valueA", "valueB", "valueC", "valueD")); + } + + @Test + public void testSetValues_singleProjectMultipleTimesWithOverlap() { + // Create test objects + ConfigurationOption opt = new ConfigurationOption("opt", "A sample option"); + StoredProject sp = new StoredProject("sp1"); + qi.addRecord(opt); + qi.addRecord(sp); + + // Add some values + List values = Arrays.asList("valueA", "valueB", "valueD"); + opt.setValues(sp, values, false); + // Add some more values + List moreValues = Arrays.asList("valueC", "valueD"); + opt.setValues(sp, moreValues, false); + + // Read the test object from the database, and look up its values + ConfigurationOption cfgOpt = qi.findObjectById(ConfigurationOption.class, opt.getId()); + List readValues = cfgOpt.getValues(sp); + + assertThat(readValues, containsInAnyOrder("valueA", "valueB", "valueC", "valueD")); + } + + @Test + public void testSetValues_multipleProjectsSomeValues() { + // Create test objects + ConfigurationOption opt = new ConfigurationOption("opt", "A sample option"); + StoredProject sp1 = new StoredProject("sp1"); + StoredProject sp2 = new StoredProject("sp2"); + qi.addRecord(opt); + qi.addRecord(sp1); + qi.addRecord(sp2); + + // Add some values + List values1 = Arrays.asList("valueA", "valueD"); + List values2 = Arrays.asList("valueB", "valueC", "valueE"); + opt.setValues(sp1, values1, false); + opt.setValues(sp2, values2, false); + + // Read the test object from the database, and look up its values + ConfigurationOption cfgOpt = qi.findObjectById(ConfigurationOption.class, opt.getId()); + List readValues1 = cfgOpt.getValues(sp1); + List readValues2 = cfgOpt.getValues(sp2); + + assertThat(readValues1, containsInAnyOrder(values1.toArray(new String[2]))); + assertThat(readValues2, containsInAnyOrder(values2.toArray(new String[3]))); + } + + @Test + public void testSetValues_overwriteNoNewValues() { + // Create test objects + ConfigurationOption opt = new ConfigurationOption("opt", "A sample option"); + StoredProject sp = new StoredProject("sp1"); + qi.addRecord(opt); + qi.addRecord(sp); + + // Add some values + List values = Arrays.asList("valueA", "valueB"); + opt.setValues(sp, values, false); + // Overwrite with no values + opt.setValues(sp, Collections.emptyList(), true); + + // Read the test object from the database, and look up its values + ConfigurationOption cfgOpt = qi.findObjectById(ConfigurationOption.class, opt.getId()); + List readValues = cfgOpt.getValues(sp); + + assertThat(readValues, is(empty())); + } + + @Test + public void testSetValues_overwriteSomeNewValues() { + // Create test objects + ConfigurationOption opt = new ConfigurationOption("opt", "A sample option"); + StoredProject sp = new StoredProject("sp1"); + qi.addRecord(opt); + qi.addRecord(sp); + + // Add some values + List values = Arrays.asList("valueA", "valueB", "valueC"); + opt.setValues(sp, values, false); + // Overwrite with some new values + List newValues = Arrays.asList("valueD", "valueB", "valueE"); + opt.setValues(sp, newValues, true); + + // Read the test object from the database, and look up its values + ConfigurationOption cfgOpt = qi.findObjectById(ConfigurationOption.class, opt.getId()); + List readValues = cfgOpt.getValues(sp); + + assertThat(readValues, containsInAnyOrder(newValues.toArray(new String[3]))); + } + + @Test + public void testFromKey_notFound() { + // Create test object + ConfigurationOption opt = new ConfigurationOption("opt", "A sample option"); + qi.addRecord(opt); + + // Look up a non-existent key + ConfigurationOption found = ConfigurationOption.fromKey("unknown-opt"); + + assertNull(found); + } + + @Test + public void testFromKey_success() { + // Create test object + ConfigurationOption opt = new ConfigurationOption("opt", "A sample option"); + qi.addRecord(opt); + + // Look up a non-existent key + ConfigurationOption found = ConfigurationOption.fromKey("opt"); + + assertNotNull(found); + assertEquals(found.getId(), opt.getId()); + assertEquals(found.getDescription(), opt.getDescription()); + } + +} diff --git a/alitheia/core/src/test/java/eu/sqooss/test/service/db/objects/MetricTest.java b/alitheia/core/src/test/java/eu/sqooss/test/service/db/objects/MetricTest.java new file mode 100644 index 000000000..0a7c104ae --- /dev/null +++ b/alitheia/core/src/test/java/eu/sqooss/test/service/db/objects/MetricTest.java @@ -0,0 +1,196 @@ +package eu.sqooss.test.service.db.objects; + +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isOneOf; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.List; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import eu.sqooss.core.AlitheiaCore; +import eu.sqooss.service.db.DBService; +import eu.sqooss.service.db.Metric; +import eu.sqooss.service.db.MetricType; +import eu.sqooss.service.db.NameSpace; +import eu.sqooss.service.db.NameSpaceMeasurement; +import eu.sqooss.service.db.ProjectVersion; +import eu.sqooss.service.db.QueryInterface; +import eu.sqooss.service.db.StoredProject; +import eu.sqooss.test.service.db.InMemoryDatabase; + +public class MetricTest { + + private static DBService db; + private static QueryInterface qi; + + private static final String metric_mnemonic = "test-metric"; + private static final String test_project_name = "test-project"; + private static final String metric_type_string = "NAMESPACE"; + private static final String test_measurement_result = "test-result"; + + @BeforeClass + public static void initializeDatabase() { + db = InMemoryDatabase.createDefault().getDatabase(); + qi = db.getQueryInterface(); + AlitheiaCore ac = mock(AlitheiaCore.class); + + when(ac.getDBService()).thenReturn(db); + + AlitheiaCore.setTestInstance(ac); + } + + @AfterClass + public static void tearDown() { + db.shutDown(); + } + + @Before + public void beginTransaction() { + db.getSessionManager().startDBSession(); + } + + @After + public void closeTransaction() { + db.getSessionManager().rollbackDBSession(); + } + + @Test + public void testIsEvaluated(){ + // Create necessary objects + Metric metr = new Metric(); + MetricType type = new MetricType(); + StoredProject project = new StoredProject(test_project_name); + ProjectVersion version = new ProjectVersion(project); + NameSpaceMeasurement meas = new NameSpaceMeasurement(); + NameSpace namespace = new NameSpace(); + + // Set required properties of the objects + type.setType(metric_type_string); + metr.setMetricType(type); + metr.setMnemonic(metric_mnemonic); + namespace.setChangeVersion(version); + meas.setMetric(metr); + meas.setNamespace(namespace); + meas.setResult(test_measurement_result); + + // Add the objects to the database + qi.addRecord(type); + qi.addRecord(metr); + qi.addRecord(project); + qi.addRecord(version); + qi.addRecord(namespace); + qi.addRecord(meas); + + // Call the method and check its result + boolean result = metr.isEvaluated(project); + assertTrue(result); + } + + @Test + public void testIsEvaluated_not_evaluated(){ + Metric metr = new Metric(); + MetricType type = new MetricType(); + type.setType(metric_type_string); + metr.setMetricType(type); + StoredProject project = new StoredProject(test_project_name); + qi.addRecord(type); + qi.addRecord(metr); + qi.addRecord(project); + + boolean result = metr.isEvaluated(project); + assertFalse(result); + } + + @Test + public void testGetMetricByMnemonic_no_results(){ + // Add the metric to the database + Metric obj = new Metric(); + qi.addRecord(obj); + + // Retrieve metric based on mnemonic and check properties + Metric result = Metric.getMetricByMnemonic(metric_mnemonic); + assertNull(result); + } + + @Test + public void testGetMetricByMnemonic_single_result(){ + // Add the metric to the database + Metric obj = new Metric(); + obj.setMnemonic(metric_mnemonic); + qi.addRecord(obj); + + // Retrieve metric based on mnemonic and check properties + Metric result = Metric.getMetricByMnemonic(metric_mnemonic); + assertNotNull(result); + assertEquals(obj.getId(), result.getId()); + assertEquals(obj.getMnemonic(), result.getMnemonic()); + assertEquals(metric_mnemonic, result.getMnemonic()); + } + + @Test + public void testGetMetricByMnemonic_multiple_results(){ + // Add the metrics to the database + Metric obj1 = new Metric(); + Metric obj2 = new Metric(); + obj1.setMnemonic(metric_mnemonic); + obj2.setMnemonic(metric_mnemonic); + qi.addRecord(obj1); + qi.addRecord(obj2); + + // Retrieve metric based on mnemonic and check properties + Metric result = Metric.getMetricByMnemonic(metric_mnemonic); + assertNotNull(result); + assertEquals(metric_mnemonic, result.getMnemonic()); + assertThat(result, isOneOf(obj1,obj2)); + } + + @Test + public void testGetAllMetrics_no_metrics(){ + // Retrieve all metrics and check properties + List results = Metric.getAllMetrics(); + assertThat(results, is(empty())); + } + + @Test + public void testGetAllMetrics_single_metric(){ + // Add the metric to the database + Metric obj = new Metric(); + qi.addRecord(obj); + + // Retrieve all metrics and check properties + List results = Metric.getAllMetrics(); + assertThat(results, is(not(empty()))); + assertEquals(1, results.size()); + assertEquals(obj, results.get(0)); + } + + @Test + public void testGetAllMetrics_multiple_metrics(){ + // Add the metrics to the database + Metric obj1 = new Metric(); + Metric obj2 = new Metric(); + qi.addRecord(obj1); + qi.addRecord(obj2); + + // Retrieve all metrics and check properties + List results = Metric.getAllMetrics(); + assertThat(results, is(not(empty()))); + assertEquals(2, results.size()); + assertThat(results, contains(obj1,obj2)); + } +} diff --git a/metrics/contrib/src/main/java/eu/sqooss/metrics/contrib/ContributionMetricImpl.java b/metrics/contrib/src/main/java/eu/sqooss/metrics/contrib/ContributionMetricImpl.java index 5d6042bef..bbca76cd8 100644 --- a/metrics/contrib/src/main/java/eu/sqooss/metrics/contrib/ContributionMetricImpl.java +++ b/metrics/contrib/src/main/java/eu/sqooss/metrics/contrib/ContributionMetricImpl.java @@ -67,16 +67,17 @@ import eu.sqooss.service.db.DAObject; import eu.sqooss.service.db.DBService; import eu.sqooss.service.db.Developer; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.MailMessage; import eu.sqooss.service.db.MailingList; import eu.sqooss.service.db.MailingListThread; import eu.sqooss.service.db.Metric; import eu.sqooss.service.db.MetricType; +import eu.sqooss.service.db.MetricType.Type; import eu.sqooss.service.db.PluginConfiguration; import eu.sqooss.service.db.ProjectFile; import eu.sqooss.service.db.ProjectVersion; import eu.sqooss.service.db.StoredProject; -import eu.sqooss.service.db.MetricType.Type; import eu.sqooss.service.fds.FileTypeMatcher; import eu.sqooss.service.metricactivator.MetricActivationException; import eu.sqooss.service.pa.PluginInfo; @@ -121,7 +122,7 @@ public boolean remove() { "ContribActionType"}; for (String tablename : tables) { - result &= db.deleteRecords((List) db.doHQL( + result &= db.getQueryInterface().deleteRecords((List) db.getQueryInterface(HQLQueryInterface.class).doHQL( "from " + tablename)); } @@ -160,10 +161,10 @@ private boolean cleanupResource (Collection c, params.put("changedResourceId", o.getId()); params.put("actionCategory", ac.toString()); List pas = - db.findObjectsByProperties(ContribAction.class, params); + db.getQueryInterface(HQLQueryInterface.class).findObjectsByProperties(ContribAction.class, params); if (!pas.isEmpty()) { for (ContribAction pa : pas) { - result &= db.deleteRecord(pa); + result &= db.getQueryInterface().deleteRecord(pa); } } params.clear(); @@ -179,19 +180,19 @@ public Map> getObjectIdsToSync(StoredProject sp params.put("sp", sp); String qVersionIDs = "select pv.id from ProjectVersion pv where pv.id not in (select ca.changedResourceId from ContribAction ca where developer.storedProject =:sp and ca.contribActionType.actionCategory='C') and pv.project = :sp order by pv.sequence"; - List objectIds = (List) db.doHQL(qVersionIDs, params); + List objectIds = (List) db.getQueryInterface(HQLQueryInterface.class).doHQL(qVersionIDs, params); TreeSet ids = new TreeSet(); ids.addAll(objectIds); IDs.put(MetricType.Type.PROJECT_VERSION, ids); String qThreadIDs = "select mlt.id from MailingListThread mlt where mlt.id not in (select ca.changedResourceId from ContribAction ca where developer.storedProject =:sp and ca.contribActionType.actionCategory='M') and mlt.list.storedProject = :sp order by mlt.lastUpdated"; - objectIds = (List) db.doHQL(qThreadIDs, params); + objectIds = (List) db.getQueryInterface(HQLQueryInterface.class).doHQL(qThreadIDs, params); ids = new TreeSet(); ids.addAll(objectIds); IDs.put(MetricType.Type.MAILTHREAD, ids); String qBugIDs = "select b.id from Bug b where b.id not in (select ca.changedResourceId from ContribAction ca where developer.storedProject =:sp and ca.contribActionType.actionCategory='B') and b.project = :sp order by b.updateRun"; - objectIds = (List) db.doHQL(qBugIDs, params); + objectIds = (List) db.getQueryInterface(HQLQueryInterface.class).doHQL(qBugIDs, params); ids = new TreeSet(); ids.addAll(objectIds); IDs.put(MetricType.Type.BUG, ids); @@ -250,7 +251,7 @@ private ContribAction getResult(DAObject o) { parameters.put(paramActionCategory, ActionCategory.B.toString()); } - List lp = (List) db.doHQL(query, parameters, 1); + List lp = (List) db.getQueryInterface(HQLQueryInterface.class).doHQL(query, parameters, 1); if (lp == null || lp.isEmpty()) { return null; @@ -553,7 +554,7 @@ private void updateField(DAObject o, Developer dev, isPositive); if (at == null) { - db.rollbackDBSession(); + db.getSessionManager().rollbackDBSession(); return; } @@ -577,7 +578,7 @@ else if (o instanceof Bug) else a.setChangedResourceTimestamp(null); //Make it fail - db.addRecord(a); + db.getQueryInterface().addRecord(a); } else { a.setTotal(a.getTotal() + value); } diff --git a/metrics/contrib/src/main/java/eu/sqooss/metrics/contrib/db/ContribAction.java b/metrics/contrib/src/main/java/eu/sqooss/metrics/contrib/db/ContribAction.java index e079a1340..66db72ed3 100644 --- a/metrics/contrib/src/main/java/eu/sqooss/metrics/contrib/db/ContribAction.java +++ b/metrics/contrib/src/main/java/eu/sqooss/metrics/contrib/db/ContribAction.java @@ -44,6 +44,7 @@ import eu.sqooss.service.db.DAObject; import eu.sqooss.service.db.DBService; import eu.sqooss.service.db.Developer; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.StoredProject; public class ContribAction extends DAObject { @@ -113,7 +114,7 @@ public static ContribAction getContribAction(Developer dev, properties.put("changedResourceId", resourceId); properties.put("contribActionType", actionType); - List pa = dbs.findObjectsByProperties(ContribAction.class, properties); + List pa = dbs.getQueryInterface().findObjectsByProperties(ContribAction.class, properties); return pa.isEmpty() ? null : pa.get(0); } @@ -138,7 +139,7 @@ public static Long getDevActionsPerType(Developer dev, params.put(paramContribActionType, actionType); - List result = (List) dbs.doHQL(q.toString(),params); + List result = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(q.toString(),params); if (!result.isEmpty()) { if (result.get(0) != null) @@ -169,7 +170,7 @@ public static Long getTotalActionsPerTypePerProject(StoredProject sp, params.put(paramProject, sp); params.put(paramContribActionType, actionType); - List result = (List) dbs.doHQL(q.toString(),params); + List result = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(q.toString(),params); if (!result.isEmpty()) { if (result.get(0) != null) @@ -187,7 +188,7 @@ public static long getTotalActions(){ String query = "select sum(total) from ContribAction" ; - List totalActions = dbs.doHQL(query); + List totalActions = dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query); if(totalActions == null || totalActions.size() == 0 || totalActions.get(0) == null) { @@ -210,7 +211,7 @@ public static long getTotalActionsPerCategory(ActionCategory ac) { Map parameters = new HashMap(); parameters.put(paramCategory, ac.toString()); - List totalActions = dbs.doHQL(query, parameters); + List totalActions = dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, parameters); if(totalActions == null || totalActions.size() == 0 || totalActions.get(0) == null) { @@ -234,7 +235,7 @@ public static long getTotalActionsPerType( Map parameters = new HashMap(); parameters.put(paramType, actionType.toString()); - List totalActions = dbs.doHQL(query, parameters); + List totalActions = dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, parameters); if(totalActions == null || totalActions.size() == 0 || totalActions.get(0) == null) { @@ -261,7 +262,7 @@ public static long getTotalActionsPerTypePerDeveloper(ActionType actionType, parameters.put(paramType, actionType.toString()); parameters.put(paramDeveloper, dev); - List totalActions = dbs.doHQL(query, parameters); + List totalActions = dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, parameters); if(totalActions == null || totalActions.size() == 0 || totalActions.get(0) == null) { diff --git a/metrics/contrib/src/main/java/eu/sqooss/metrics/contrib/db/ContribActionType.java b/metrics/contrib/src/main/java/eu/sqooss/metrics/contrib/db/ContribActionType.java index e3f60cf08..810b7b2b8 100644 --- a/metrics/contrib/src/main/java/eu/sqooss/metrics/contrib/db/ContribActionType.java +++ b/metrics/contrib/src/main/java/eu/sqooss/metrics/contrib/db/ContribActionType.java @@ -42,6 +42,7 @@ import eu.sqooss.core.AlitheiaCore; import eu.sqooss.service.db.DAObject; import eu.sqooss.service.db.DBService; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.StoredProject; public class ContribActionType extends DAObject { @@ -126,7 +127,7 @@ public static List getProjectActionTypes(StoredProject sp, params.put(paramBefore, before); //params.put(paramCat, ac); - return (List) dbs.doHQL(q.toString(),params); + return (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(q.toString(),params); } public static ContribActionType getContribActionType( @@ -138,7 +139,7 @@ public static ContribActionType getContribActionType( Map parameterMap = new HashMap(); parameterMap.put("actionType", actionType.toString()); - List atl = dbs.findObjectsByProperties( + List atl = dbs.getQueryInterface().findObjectsByProperties( ContribActionType.class, parameterMap); if (!atl.isEmpty()) @@ -152,7 +153,7 @@ public static ContribActionType getContribActionType( at.setType(actionType); at.setIsPositive(isPositive); - if (!dbs.addRecord(at)) { + if (!dbs.getQueryInterface().addRecord(at)) { return null; } return at; diff --git a/metrics/developermetrics/src/main/java/eu/sqooss/metrics/developermetrics/Developermetrics.java b/metrics/developermetrics/src/main/java/eu/sqooss/metrics/developermetrics/Developermetrics.java index a91916044..3ac1e236c 100644 --- a/metrics/developermetrics/src/main/java/eu/sqooss/metrics/developermetrics/Developermetrics.java +++ b/metrics/developermetrics/src/main/java/eu/sqooss/metrics/developermetrics/Developermetrics.java @@ -45,6 +45,7 @@ import eu.sqooss.service.abstractmetric.Result.ResultType; import eu.sqooss.service.db.Developer; import eu.sqooss.service.db.Directory; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.Metric; import eu.sqooss.service.db.ProjectDirectory; import eu.sqooss.service.db.ProjectFile; @@ -107,17 +108,17 @@ public void run(ProjectVersion v) throws AlreadyProcessingException { Metric m = Metric.getMetricByMnemonic(MNEM_TEAMSIZE1); ProjectVersionMeasurement pvmOne = new ProjectVersionMeasurement( m, v, String.valueOf(commSize(v, oneMonth))); - db.addRecord(pvmOne); + db.getQueryInterface().addRecord(pvmOne); m = Metric.getMetricByMnemonic(MNEM_TEAMSIZE3); ProjectVersionMeasurement pvmThree = new ProjectVersionMeasurement( m, v, String.valueOf(commSize(v, threeMonths))); - db.addRecord(pvmThree); + db.getQueryInterface().addRecord(pvmThree); m = Metric.getMetricByMnemonic(MNEM_TEAMSIZE6); ProjectVersionMeasurement pvmSix = new ProjectVersionMeasurement( m, v, String.valueOf(commSize(v, sixMonths))); - db.addRecord(pvmSix); + db.getQueryInterface().addRecord(pvmSix); } private long commSize(ProjectVersion v, long ts) { @@ -126,7 +127,7 @@ private long commSize(ProjectVersion v, long ts) { params.put("paramOld", ts); params.put("paramProject", v.getProject()); - return (Long) db.doHQL(activeLast, params).get(0); + return (Long) db.getQueryInterface(HQLQueryInterface.class).doHQL(activeLast, params).get(0); } public List getResult(ProjectFile pf, Metric m) { @@ -156,7 +157,7 @@ public void run(ProjectFile a) throws AlreadyProcessingException { ProjectFileMeasurement pfm = new ProjectFileMeasurement(m, a, String.valueOf(eyeballs)); - db.addRecord(pfm); + db.getQueryInterface().addRecord(pfm); } private List fileEyeballs(ProjectFile a) { @@ -166,7 +167,7 @@ private List fileEyeballs(ProjectFile a) { params.put("paramProject", a.getProjectVersion().getProject()); params.put("paramFileId", a.getId()); - return (List) db.doHQL(fileEyeballs, params); + return (List) db.getQueryInterface(HQLQueryInterface.class).doHQL(fileEyeballs, params); } } diff --git a/metrics/discussionheat/src/main/java/eu/sqooss/metrics/discussionheat/DiscussionHeat.java b/metrics/discussionheat/src/main/java/eu/sqooss/metrics/discussionheat/DiscussionHeat.java index af3c91300..f3a87cbd0 100644 --- a/metrics/discussionheat/src/main/java/eu/sqooss/metrics/discussionheat/DiscussionHeat.java +++ b/metrics/discussionheat/src/main/java/eu/sqooss/metrics/discussionheat/DiscussionHeat.java @@ -48,6 +48,7 @@ import eu.sqooss.service.abstractmetric.MetricMismatchException; import eu.sqooss.service.abstractmetric.Result; import eu.sqooss.service.db.DBService; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.MailMessage; import eu.sqooss.service.db.MailingListThread; import eu.sqooss.service.db.MailingListThreadMeasurement; @@ -107,8 +108,8 @@ public void run(MailingListThread m) throws AlreadyProcessingException { Map params = new HashMap(); params.put("lst", m.getList()); - List thrDepths = (List)db.doHQL(thrDepth, params); - List mailsPerList = (List)db.doHQL(numMails, params); + List thrDepths = (List)db.getQueryInterface(HQLQueryInterface.class).doHQL(thrDepth, params); + List mailsPerList = (List)db.getQueryInterface(HQLQueryInterface.class).doHQL(numMails, params); //Get one day's worth of messages List msgs = m.getMessagesByArrivalOrder(); @@ -137,7 +138,7 @@ public void run(MailingListThread m) throws AlreadyProcessingException { MailingListThreadMeasurement mm = new MailingListThreadMeasurement( hotness, m, String.valueOf(score)); - dbs.addRecord(mm); + dbs.getQueryInterface().addRecord(mm); if (score < 6) return; @@ -155,7 +156,7 @@ public void run(MailingListThread m) throws AlreadyProcessingException { MailingListThreadMeasurement mltm = new MailingListThreadMeasurement( hoteffect, m, String.valueOf(result)); - dbs.addRecord(mltm); + dbs.getQueryInterface().addRecord(mltm); } private int getLocsForVersions(List versions) throws AlreadyProcessingException { @@ -219,7 +220,7 @@ private ProjectVersion getVersionByDate(Date ts, StoredProject sp) { Map params = new HashMap(); params.put("ts", ts.getTime()); params.put("sp", sp); - List vers = (List) dbs.doHQL(getPVbyDate, params, 1); + List vers = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(getPVbyDate, params, 1); if (vers.size() > 0) return vers.get(0); @@ -283,7 +284,7 @@ public void run(ProjectVersion pv) throws AlreadyProcessingException { ProjectVersionMeasurement pvm = new ProjectVersionMeasurement(m, pv, String.valueOf(linesChanged)); - dbs.addRecord(pvm); + dbs.getQueryInterface().addRecord(pvm); } private int getLOCResult(ProjectFile pf, AlitheiaPlugin plugin, diff --git a/metrics/findbugs/src/main/java/gr/aueb/metrics/findbugs/FindbugsMetrics.java b/metrics/findbugs/src/main/java/gr/aueb/metrics/findbugs/FindbugsMetrics.java index a31d5395c..909ff7ef7 100644 --- a/metrics/findbugs/src/main/java/gr/aueb/metrics/findbugs/FindbugsMetrics.java +++ b/metrics/findbugs/src/main/java/gr/aueb/metrics/findbugs/FindbugsMetrics.java @@ -502,8 +502,8 @@ private void storeResults(Map > results, versionMeasurements.add(new ProjectVersionMeasurement(m, pv, bugTotal.toString())); } } - db.addRecords(fileMeasurements); - db.addRecords(versionMeasurements); + db.getQueryInterface().addRecords(fileMeasurements); + db.getQueryInterface().addRecords(versionMeasurements); } private boolean pvMeasurementExists(ProjectVersion pv, Metric m) { @@ -516,7 +516,7 @@ private boolean pvMeasurementExists(ProjectVersion pv, Metric m) { parameters.put("metric", m); parameters.put("version", pv); - return db.doHQL(q, parameters).size() > 0; + return db.getQueryInterface(HQLQueryInterface.class).doHQL(q, parameters).size() > 0; } private ProjectFile findFile(List files, String path) { diff --git a/metrics/javametrics/src/main/java/eu/sqooss/metrics/java/JavaMetrics.java b/metrics/javametrics/src/main/java/eu/sqooss/metrics/java/JavaMetrics.java index e0ee2a7fc..cc3a78979 100644 --- a/metrics/javametrics/src/main/java/eu/sqooss/metrics/java/JavaMetrics.java +++ b/metrics/javametrics/src/main/java/eu/sqooss/metrics/java/JavaMetrics.java @@ -86,7 +86,7 @@ public void run(ExecutionUnit eu) throws Exception { public void run(ProjectVersion pv) throws Exception { db = AlitheiaCore.getInstance().getDBService(); - pv = db.attachObjectToDBSession(pv); + pv = db.getSessionManager().attachObjectToDBSession(pv); this.pv = pv; Pattern p = Pattern.compile("([^\\s]+(\\.(?i)(java))$)"); @@ -107,18 +107,18 @@ public void run(ProjectVersion pv) throws Exception { reducer = new ConcurrentHashMap(); for (ProjectFile pf : pv.getFiles(p)) try { - if(!db.isDBSessionActive()) db.startDBSession(); + if(!db.getSessionManager().isDBSessionActive()) db.getSessionManager().startDBSession(); parseFile(pf); } catch (Exception e) { } finally { - if(db.isDBSessionActive()) db.commitDBSession(); + if(db.getSessionManager().isDBSessionActive()) db.getSessionManager().commitDBSession(); } List changedClasses = new ArrayList(); for (ProjectFile pf : changedFiles) { - pf = db.attachObjectToDBSession(pf); + pf = db.getSessionManager().attachObjectToDBSession(pf); changedClasses.addAll(pf.getEncapsulationUnits()); } @@ -140,12 +140,12 @@ public void run(ProjectVersion pv) throws Exception { noc++; EncapsulationUnitMeasurement eum = new EncapsulationUnitMeasurement(clazz, DIT, String.valueOf(dit)); - db.addRecord(eum); + db.getQueryInterface().addRecord(eum); eum = new EncapsulationUnitMeasurement(clazz, NOC, String.valueOf(dit)); - db.addRecord(eum); + db.getQueryInterface().addRecord(eum); } - db.commitDBSession(); + db.getSessionManager().commitDBSession(); } protected void parseFile(ProjectFile pf) throws Exception { @@ -224,12 +224,12 @@ protected void parseFile(ProjectFile pf) throws Exception { ExecutionUnitMeasurement eum = new ExecutionUnitMeasurement( method, Metric.getMetricByMnemonic("MCCABE"), res.toString()); - db.addRecord(eum); + db.getQueryInterface().addRecord(eum); } EncapsulationUnitMeasurement eum = new EncapsulationUnitMeasurement(clazz, m, wmc.toString()); - db.addRecord(eum); + db.getQueryInterface().addRecord(eum); } // NUMM results @@ -238,7 +238,7 @@ protected void parseFile(ProjectFile pf) throws Exception { new EncapsulationUnitMeasurement(clazz, Metric.getMetricByMnemonic("NUMM"), clazz.getExecUnits().toString()); - db.addRecord(eum); + db.getQueryInterface().addRecord(eum); } } @@ -254,7 +254,7 @@ private void writeClassResults(Set classes, } EncapsulationUnitMeasurement eum = new EncapsulationUnitMeasurement(clazz, m, res.toString()); - db.addRecord(eum); + db.getQueryInterface().addRecord(eum); } } diff --git a/metrics/mi/src/main/java/eu/sqooss/metrics/mi/Mi.java b/metrics/mi/src/main/java/eu/sqooss/metrics/mi/Mi.java index 580de8aed..7738b171c 100644 --- a/metrics/mi/src/main/java/eu/sqooss/metrics/mi/Mi.java +++ b/metrics/mi/src/main/java/eu/sqooss/metrics/mi/Mi.java @@ -45,6 +45,7 @@ import eu.sqooss.service.abstractmetric.Result; import eu.sqooss.service.db.DAObject; import eu.sqooss.service.db.Directory; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.Metric; import eu.sqooss.service.db.ProjectDirectory; import eu.sqooss.service.db.ProjectFile; @@ -99,7 +100,7 @@ public List getResult(ProjectFile pf, Metric m) { public void run(ProjectFile pf) throws AlreadyProcessingException { - pf = db.attachObjectToDBSession(pf); + pf = db.getSessionManager().attachObjectToDBSession(pf); /*MI works at the module level for src directories*/ if (!pf.getIsDirectory()) @@ -208,7 +209,7 @@ public void run(ProjectFile pf) throws AlreadyProcessingException { Metric m = Metric.getMetricByMnemonic(MNEMONIC_MODMI); ProjectFileMeasurement pfm = new ProjectFileMeasurement(m, pf, String.valueOf(MI)); - db.addRecord(pfm); + db.getQueryInterface().addRecord(pfm); } public List getResult(ProjectVersion pv, Metric m) { @@ -264,7 +265,7 @@ public void run(ProjectVersion pv) throws AlreadyProcessingException { // Get the list of folders which exist in this project version. List srcDirs = - (List) db.doHQL(q.toString(), params); + (List) db.getQueryInterface(HQLQueryInterface.class).doHQL(q.toString(), params); // Calculate the metric results double miTotal = 0; @@ -284,7 +285,7 @@ public void run(ProjectVersion pv) throws AlreadyProcessingException { metric, pv, String.valueOf(0)); ams.setResult(String.valueOf(((float) (miTotal / srcDirs.size())))); - db.addRecord(ams); + db.getQueryInterface().addRecord(ams); } } diff --git a/metrics/modulemetrics/src/main/java/eu/sqooss/metrics/modulemetrics/ModuleMetricsImplementation.java b/metrics/modulemetrics/src/main/java/eu/sqooss/metrics/modulemetrics/ModuleMetricsImplementation.java index 33c4eaaef..3244121e8 100644 --- a/metrics/modulemetrics/src/main/java/eu/sqooss/metrics/modulemetrics/ModuleMetricsImplementation.java +++ b/metrics/modulemetrics/src/main/java/eu/sqooss/metrics/modulemetrics/ModuleMetricsImplementation.java @@ -49,6 +49,7 @@ import eu.sqooss.service.abstractmetric.MetricDeclarations; import eu.sqooss.service.abstractmetric.Result; import eu.sqooss.service.db.Directory; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.Metric; import eu.sqooss.service.db.ProjectDirectory; import eu.sqooss.service.db.ProjectFile; @@ -136,17 +137,17 @@ public void run(ProjectFile pf) throws AlreadyProcessingException { Metric m = Metric.getMetricByMnemonic(MET_ISSRCMOD); ProjectFileMeasurement pfm = new ProjectFileMeasurement(m, pf, String.valueOf(1)); - db.addRecord(pfm); + db.getQueryInterface().addRecord(pfm); m = Metric.getMetricByMnemonic(MET_MNOL); pfm = new ProjectFileMeasurement(m, pf, String.valueOf(mnol)); - db.addRecord(pfm); + db.getQueryInterface().addRecord(pfm); m = Metric.getMetricByMnemonic(MET_MNOF); pfm = new ProjectFileMeasurement(m, pf, String.valueOf(mnof)); - db.addRecord(pfm); + db.getQueryInterface().addRecord(pfm); } } @@ -198,7 +199,7 @@ public void run(ProjectVersion pv) throws AlreadyProcessingException { // Get the list of folders which exist in this project version. List srcDirs = - (List) db.doHQL(q.toString(), params); + (List) db.getQueryInterface(HQLQueryInterface.class).doHQL(q.toString(), params); // Calculate the metric results int locs = 0; @@ -219,7 +220,7 @@ public void run(ProjectVersion pv) throws AlreadyProcessingException { metric, pv, String.valueOf(0)); ams.setResult(String.valueOf(((float) (locs / srcDirs.size())))); - db.addRecord(ams); + db.getQueryInterface().addRecord(ams); } } diff --git a/metrics/structural/src/main/java/eu/sqooss/metrics/structural/Structural.java b/metrics/structural/src/main/java/eu/sqooss/metrics/structural/Structural.java index ab12f9050..d2bb62dcb 100644 --- a/metrics/structural/src/main/java/eu/sqooss/metrics/structural/Structural.java +++ b/metrics/structural/src/main/java/eu/sqooss/metrics/structural/Structural.java @@ -177,7 +177,7 @@ public void run(ProjectFile pf) { return; } - pf = db.attachObjectToDBSession(pf); + pf = db.getSessionManager().attachObjectToDBSession(pf); this.fileDAO.set(pf); FDSService fds = AlitheiaCore.getInstance().getFDSService(); @@ -621,7 +621,7 @@ private Set uniq(List arlList) { private void addRecord(String mnem, ProjectFile pf, String value) { Metric m = Metric.getMetricByMnemonic(mnem); ProjectFileMeasurement pfm = new ProjectFileMeasurement(m, pf, value); - db.addRecord(pfm); + db.getQueryInterface().addRecord(pfm); } } diff --git a/metrics/testability/src/main/java/eu/sqooss/metrics/testability/TestabilityImplementation.java b/metrics/testability/src/main/java/eu/sqooss/metrics/testability/TestabilityImplementation.java index f3efba83a..d5380b6e6 100644 --- a/metrics/testability/src/main/java/eu/sqooss/metrics/testability/TestabilityImplementation.java +++ b/metrics/testability/src/main/java/eu/sqooss/metrics/testability/TestabilityImplementation.java @@ -151,7 +151,7 @@ public void run(ProjectFile pf) { Metric metric = Metric.getMetricByMnemonic(MNEMONIC_NCASES); ProjectFileMeasurement ncases = new ProjectFileMeasurement( metric,pf,String.valueOf(numTestCases)); - db.addRecord(ncases); + db.getQueryInterface().addRecord(ncases); } catch (IOException e) { log.error(this.getClass().getName() + " IO Error <" + e + "> while measuring: " + pf.getFileName()); diff --git a/metrics/wc/src/main/java/eu/sqooss/metrics/wc/WcImplementation.java b/metrics/wc/src/main/java/eu/sqooss/metrics/wc/WcImplementation.java index 6a5b630d3..bff808864 100644 --- a/metrics/wc/src/main/java/eu/sqooss/metrics/wc/WcImplementation.java +++ b/metrics/wc/src/main/java/eu/sqooss/metrics/wc/WcImplementation.java @@ -53,6 +53,7 @@ import eu.sqooss.service.abstractmetric.MetricDecl; import eu.sqooss.service.abstractmetric.MetricDeclarations; import eu.sqooss.service.abstractmetric.Result; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.Metric; import eu.sqooss.service.db.ProjectFile; import eu.sqooss.service.db.ProjectFileMeasurement; @@ -120,7 +121,7 @@ public List getResult(ProjectFile a, Metric m) { filter.put("projectFile", a); filter.put("metric", m); List measurement = - db.findObjectsByProperties(ProjectFileMeasurement.class, filter); + db.getQueryInterface().findObjectsByProperties(ProjectFileMeasurement.class, filter); for (ProjectFileMeasurement pfm : measurement) results.add(new Result(a, m, pfm.getResult(), Result.ResultType.INTEGER)); @@ -252,25 +253,25 @@ public void run(ProjectFile pf) { Metric metric = Metric.getMetricByMnemonic(MNEMONIC_WC_LOC); ProjectFileMeasurement locm = new ProjectFileMeasurement( metric,pf,String.valueOf(results[0])); - db.addRecord(locm); + db.getQueryInterface().addRecord(locm); toUpdate.add(metric); metric = Metric.getMetricByMnemonic(MNEMONIC_WC_LOCOM); ProjectFileMeasurement locc = new ProjectFileMeasurement( metric,pf,String.valueOf(results[1])); - db.addRecord(locc); + db.getQueryInterface().addRecord(locc); toUpdate.add(metric); metric = Metric.getMetricByMnemonic(MNEMONIC_WC_LONB); ProjectFileMeasurement lonb = new ProjectFileMeasurement( metric,pf,String.valueOf(results[2])); - db.addRecord(lonb); + db.getQueryInterface().addRecord(lonb); toUpdate.add(metric); metric = Metric.getMetricByMnemonic(MNEMONIC_WC_WORDS); ProjectFileMeasurement words_measure = new ProjectFileMeasurement( metric,pf,String.valueOf(results[3])); - db.addRecord(words_measure); + db.getQueryInterface().addRecord(words_measure); toUpdate.add(metric); } @@ -390,7 +391,7 @@ public List getResult(ProjectVersion p, Metric m) { filter.put("projectVersion", p); filter.put("metric", m); List measurement = - db.findObjectsByProperties(ProjectVersionMeasurement.class, filter); + db.getQueryInterface().findObjectsByProperties(ProjectVersionMeasurement.class, filter); for (ProjectVersionMeasurement pfm : measurement) results.add(new Result(p, m, pfm.getResult(), Result.ResultType.INTEGER)); @@ -440,7 +441,7 @@ public void run(ProjectVersion v) throws AlreadyProcessingException { params.put(paramState, ProjectFileState.deleted()); List results = - (List) db.doHQL(q.toString(), params); + (List) db.getQueryInterface(HQLQueryInterface.class).doHQL(q.toString(), params); long nof = 0; //Number of files int nosf = 0; //Number of source code files @@ -488,7 +489,7 @@ private Metric addPVMeasurement(String s, ProjectVersion pv, int value) { Metric m = Metric.getMetricByMnemonic(s); ProjectVersionMeasurement pvm = new ProjectVersionMeasurement(m , pv, String.valueOf(value)); - db.addRecord(pvm); + db.getQueryInterface().addRecord(pvm); return m; } } diff --git a/plug-ins/bugzilla/src/main/java/eu/sqooss/plugins/bugzilla/BugzillaUpdater.java b/plug-ins/bugzilla/src/main/java/eu/sqooss/plugins/bugzilla/BugzillaUpdater.java index 0a9849965..0332dd81e 100644 --- a/plug-ins/bugzilla/src/main/java/eu/sqooss/plugins/bugzilla/BugzillaUpdater.java +++ b/plug-ins/bugzilla/src/main/java/eu/sqooss/plugins/bugzilla/BugzillaUpdater.java @@ -87,8 +87,8 @@ public int progress() { @Override public void update() throws Exception { jobCounter = new AtomicInteger(); - dbs.startDBSession(); - project = dbs.attachObjectToDBSession(project); + dbs.getSessionManager().startDBSession(); + project = dbs.getSessionManager().attachObjectToDBSession(project); Scheduler s = AlitheiaCore.getInstance().getScheduler(); @@ -124,8 +124,8 @@ public void update() throws Exception { } catch(InterruptedException ignored){} } - if (dbs.isDBSessionActive()) - dbs.commitDBSession(); + if (dbs.getSessionManager().isDBSessionActive()) + dbs.getSessionManager().commitDBSession(); } @Override diff --git a/plug-ins/bugzilla/src/main/java/eu/sqooss/plugins/bugzilla/BugzillaXMLJob.java b/plug-ins/bugzilla/src/main/java/eu/sqooss/plugins/bugzilla/BugzillaXMLJob.java index 56eecbd2f..8279ec156 100644 --- a/plug-ins/bugzilla/src/main/java/eu/sqooss/plugins/bugzilla/BugzillaXMLJob.java +++ b/plug-ins/bugzilla/src/main/java/eu/sqooss/plugins/bugzilla/BugzillaXMLJob.java @@ -79,11 +79,11 @@ public long priority() { @Override protected void run() throws Exception { - if (!dbs.isDBSessionActive()) - dbs.startDBSession(); + if (!dbs.getSessionManager().isDBSessionActive()) + dbs.getSessionManager().startDBSession(); BTSAccessor bts = AlitheiaCore.getInstance().getTDSService().getAccessor( project.getId()).getBTSAccessor(); - project = dbs.attachObjectToDBSession(project); + project = dbs.getSessionManager().attachObjectToDBSession(project); Bug bug = BTSEntryToBug(bts.getBug(bugID)); @@ -117,9 +117,9 @@ protected void run() throws Exception { bug.setReportMessages(toadd); } - dbs.addRecord(bug); + dbs.getQueryInterface().addRecord(bug); logger.debug(project.getName() + ": Added bug " + bugID); - dbs.commitDBSession(); + dbs.getSessionManager().commitDBSession(); } @@ -204,7 +204,7 @@ private boolean bugExists(StoredProject sp, String bugId) { params.put("project", sp); params.put("bugID", bugId); - List buglist = dbs.findObjectsByProperties(Bug.class, params); + List buglist = dbs.getQueryInterface().findObjectsByProperties(Bug.class, params); if (buglist.isEmpty()) return false; diff --git a/plug-ins/devmatcher/src/main/java/eu/sqooss/plugins/devmatcher/DeveloperMatcher.java b/plug-ins/devmatcher/src/main/java/eu/sqooss/plugins/devmatcher/DeveloperMatcher.java index 027696d5d..37fae92c3 100644 --- a/plug-ins/devmatcher/src/main/java/eu/sqooss/plugins/devmatcher/DeveloperMatcher.java +++ b/plug-ins/devmatcher/src/main/java/eu/sqooss/plugins/devmatcher/DeveloperMatcher.java @@ -41,6 +41,7 @@ import eu.sqooss.service.db.DBService; import eu.sqooss.service.db.Developer; import eu.sqooss.service.db.DeveloperAlias; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.StoredProject; import eu.sqooss.service.logging.Logger; import eu.sqooss.service.updater.MetadataUpdater; @@ -92,12 +93,12 @@ public void setUpdateParams(StoredProject arg0, Logger arg1) { @Override public void update() throws Exception { - dbs.startDBSession(); - project = dbs.attachObjectToDBSession(project); + dbs.getSessionManager().startDBSession(); + project = dbs.getSessionManager().attachObjectToDBSession(project); DoubleMetaphone dm = new DoubleMetaphone(); Map params = new HashMap(); params.put("storedProject", project); - List devs = dbs.findObjectsByPropertiesForUpdate(Developer.class, params); + List devs = dbs.getQueryInterface().findObjectsByPropertiesForUpdate(Developer.class, params); long ts = System.currentTimeMillis(); //Fill in indices for (Developer d : devs) { @@ -211,13 +212,13 @@ public void update() throws Exception { } for (String upd : updates) { - long lines = dbs.executeUpdate(upd, updParam); + long lines = dbs.getQueryInterface(HQLQueryInterface.class).executeUpdate(upd, updParam); debug(upd + " old:" + byEmail + " new:" + byUsrName + " " + lines + " changed"); } for (String del : deletes) { - long lines = dbs.executeUpdate(del, delParam); + long lines = dbs.getQueryInterface(HQLQueryInterface.class).executeUpdate(del, delParam); debug(del + " old:" + byEmail.getId() + lines + " changed"); } @@ -227,7 +228,7 @@ public void update() throws Exception { info("Matched " + matches.size() + " developers in " + (System.currentTimeMillis() - ts) + "ms"); - dbs.commitDBSession(); + dbs.getSessionManager().commitDBSession(); progress = 100; } diff --git a/plug-ins/git/src/main/java/eu/sqooss/plugins/updater/git/GitUpdater.java b/plug-ins/git/src/main/java/eu/sqooss/plugins/updater/git/GitUpdater.java index 00ad047e2..b91c99de5 100644 --- a/plug-ins/git/src/main/java/eu/sqooss/plugins/updater/git/GitUpdater.java +++ b/plug-ins/git/src/main/java/eu/sqooss/plugins/updater/git/GitUpdater.java @@ -150,8 +150,8 @@ public void setUpdateParams(StoredProject sp, Logger l) { public void update() throws Exception { - dbs.startDBSession(); - project = dbs.attachObjectToDBSession(project); + dbs.getSessionManager().startDBSession(); + project = dbs.getSessionManager().attachObjectToDBSession(project); info("Running source update for project " + project.getName() @@ -167,7 +167,7 @@ public void update() throws Exception { if (r.compareTo(git.newRevision(latestVersion.getRevisionId())) <= 0) { info("Project is already at the newest version: " + r.getUniqueId()); - dbs.commitDBSession(); + dbs.getSessionManager().commitDBSession(); return; } next = git.newRevision(latestVersion.getRevisionId()); @@ -188,7 +188,7 @@ public void updateFromTo(Revision from, Revision to) int numRevisions = 0; CommitLog commitLog = git.getCommitLog("", from, to); - if(!dbs.isDBSessionActive()) dbs.startDBSession(); + if(!dbs.getSessionManager().isDBSessionActive()) dbs.getSessionManager().startDBSession(); for (Revision entry : commitLog) { if (ProjectVersion.getVersionByRevision(project, entry.getUniqueId()) != null) { @@ -206,12 +206,12 @@ public void updateFromTo(Revision from, Revision to) updateValidUntil(pv, pv.getVersionFiles()); - if (!dbs.commitDBSession()) { + if (!dbs.getSessionManager().commitDBSession()) { warn("Intermediate commit failed, failing update"); return; } - dbs.startDBSession(); + dbs.getSessionManager().startDBSession(); progress = (float) (((double)numRevisions / (double)commitLog.size()) * 100); numRevisions++; @@ -236,14 +236,14 @@ private ProjectVersion processOneRevision(Revision entry) pv.setCommitMsg(commitMsg); pv.setSequence(Integer.MAX_VALUE); - dbs.addRecord(pv); + dbs.getQueryInterface().addRecord(pv); //Tags String tag = git.allTags().get(entry.getUniqueId()); if (tag != null) { Tag t = new Tag(pv); t.setName(tag); - dbs.addRecord(t); + dbs.getQueryInterface().addRecord(t); pv.getTags().add(t); } @@ -263,7 +263,7 @@ private ProjectVersion processOneRevision(Revision entry) //Parent is a branch if (git.getCommitChidren(parentId).length > 1) { Branch b = new Branch(project, Branch.suggestName(project)); - dbs.addRecord(b); + dbs.getQueryInterface().addRecord(b); parent.getOutgoingBranches().add(b); pv.getIncomingBranches().add(b); } else { @@ -279,7 +279,7 @@ private ProjectVersion processOneRevision(Revision entry) //New line of development if (entry.getParentIds().size() == 0) { Branch b = new Branch(project, Branch.suggestName(project)); - dbs.addRecord(b); + dbs.getQueryInterface().addRecord(b); pv.getOutgoingBranches().add(b); } else { pv.getOutgoingBranches().addAll(pv.getIncomingBranches()); diff --git a/plug-ins/git/src/test/java/eu/sqooss/plugins/git/test/TestGitUpdater.java b/plug-ins/git/src/test/java/eu/sqooss/plugins/git/test/TestGitUpdater.java index c156b2c65..9ded015f6 100644 --- a/plug-ins/git/src/test/java/eu/sqooss/plugins/git/test/TestGitUpdater.java +++ b/plug-ins/git/src/test/java/eu/sqooss/plugins/git/test/TestGitUpdater.java @@ -99,11 +99,11 @@ public static void setup() throws IOException, URISyntaxException { AlitheiaCore.testInstance(); db = new DBServiceImpl(conProp, config.toURL() , l); - db.startDBSession(); + db.getSessionManager().startDBSession(); sp = new StoredProject(); sp.setName(projectName); - db.addRecord(sp); - db.commitDBSession(); + db.getQueryInterface().addRecord(sp); + db.getSessionManager().commitDBSession(); } @Before @@ -115,7 +115,7 @@ public void setUp() throws AccessorException, URISyntaxException { @Test public void testGetAuthor() { - db.startDBSession(); + db.getSessionManager().startDBSession(); //Test a properly formatted name Developer d = updater.getAuthor(sp, "Papa Smurf "); @@ -159,7 +159,7 @@ public void testGetAuthor() { assertNull(d.getName()); assertEquals(1, d.getAliases().size()); - db.rollbackDBSession(); + db.getSessionManager().rollbackDBSession(); } @Test @@ -184,8 +184,8 @@ public void testUpdate() throws Exception { tw.addTree(commit.getTree()); tw.setRecursive(true); - db.startDBSession(); - sp = db.attachObjectToDBSession(sp); + db.getSessionManager().startDBSession(); + sp = db.getSessionManager().attachObjectToDBSession(sp); ProjectVersion pv = ProjectVersion.getVersionByRevision(sp, from.getUniqueId()); assertNotNull(pv); @@ -216,7 +216,7 @@ public void testUpdate() throws Exception { } } - db.commitDBSession(); + db.getSessionManager().commitDBSession(); tw.release(); rw.release(); from = to; diff --git a/plug-ins/javaparser/src/main/java/eu/sqooss/plugins/javaparser/JavaUpdater.java b/plug-ins/javaparser/src/main/java/eu/sqooss/plugins/javaparser/JavaUpdater.java index 149cfc9cf..e540aed3c 100644 --- a/plug-ins/javaparser/src/main/java/eu/sqooss/plugins/javaparser/JavaUpdater.java +++ b/plug-ins/javaparser/src/main/java/eu/sqooss/plugins/javaparser/JavaUpdater.java @@ -9,6 +9,7 @@ import eu.sqooss.core.AlitheiaCore; import eu.sqooss.service.db.DBService; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.Language; import eu.sqooss.service.db.ProjectVersion; import eu.sqooss.service.db.StoredProject; @@ -58,11 +59,11 @@ public void setUpdateParams(StoredProject sp, Logger l) { } public void update() throws Exception { - db.startDBSession(); + db.getSessionManager().startDBSession(); Map params = new HashMap(); params.put("sp", sp); - List toProcess = (List) db.doHQL(notProcessed, params); + List toProcess = (List) db.getQueryInterface(HQLQueryInterface.class).doHQL(notProcessed, params); if (toProcess.size() == 0) { log.info("No versions to process"); @@ -87,7 +88,7 @@ public void update() throws Exception { } catch(InterruptedException ignored){} } - if (db.isDBSessionActive())db.commitDBSession(); + if (db.getSessionManager().isDBSessionActive())db.getSessionManager().commitDBSession(); } public void jobStateChanged(Job j, State newState) { diff --git a/plug-ins/javaparser/src/main/java/eu/sqooss/plugins/javaparser/JavaUpdaterJob.java b/plug-ins/javaparser/src/main/java/eu/sqooss/plugins/javaparser/JavaUpdaterJob.java index 7e3f0b058..1660b90d6 100644 --- a/plug-ins/javaparser/src/main/java/eu/sqooss/plugins/javaparser/JavaUpdaterJob.java +++ b/plug-ins/javaparser/src/main/java/eu/sqooss/plugins/javaparser/JavaUpdaterJob.java @@ -62,9 +62,9 @@ public long priority() { @Override protected void run() throws Exception { - db.startDBSession(); - sp = db.attachObjectToDBSession(sp); - pv = db.attachObjectToDBSession(pv); + db.getSessionManager().startDBSession(); + sp = db.getSessionManager().attachObjectToDBSession(sp); + pv = db.getSessionManager().attachObjectToDBSession(pv); Pattern p = Pattern.compile(".*\\.java$"); FDSService fds = AlitheiaCore.getInstance().getFDSService(); @@ -125,7 +125,7 @@ protected void run() throws Exception { ns.setName(ee.getPackageName()); ns.setChangeVersion(pf.getProjectVersion()); ns.setLang(Language.JAVA); - db.addRecord(ns); + db.getQueryInterface().addRecord(ns); } for (String clazz : ee.getResults().keySet()) { @@ -134,7 +134,7 @@ protected void run() throws Exception { eu.setName(clazz); eu.setNamespace(ns); eu.setFile(pf); - db.addRecord(eu); + db.getQueryInterface().addRecord(eu); for (CodeFragment fragment : ee.getResults().get(clazz)) { ExecutionUnit exu = new ExecutionUnit(eu); @@ -148,11 +148,11 @@ protected void run() throws Exception { pf.getProjectVersion().toString()); exu.setChanged(true); } - db.addRecord(exu); + db.getQueryInterface().addRecord(exu); } } } - db.commitDBSession(); + db.getSessionManager().commitDBSession(); } private List getChangedMethods(EntityExtractor ee, ProjectFile pf, diff --git a/plug-ins/maildir/src/main/java/eu/sqooss/plugins/maildir/MailDirUpdater.java b/plug-ins/maildir/src/main/java/eu/sqooss/plugins/maildir/MailDirUpdater.java index f902e82b2..25dea6cf1 100644 --- a/plug-ins/maildir/src/main/java/eu/sqooss/plugins/maildir/MailDirUpdater.java +++ b/plug-ins/maildir/src/main/java/eu/sqooss/plugins/maildir/MailDirUpdater.java @@ -97,7 +97,7 @@ public void update() throws Exception { List listIds = Collections.emptyList(); try { //Process mailing lists first - dbs.startDBSession(); + dbs.getSessionManager().startDBSession(); listIds = processMailingLists(mailAccessor); for (Long mlId : listIds) { @@ -107,7 +107,7 @@ public void update() throws Exception { } if (total == 0) { - dbs.commitDBSession(); + dbs.getSessionManager().commitDBSession(); return; } @@ -145,7 +145,7 @@ private List processMailingLists(MailAccessor mailAccessor) { MailingList nml = new MailingList(); nml.setListId(listId); nml.setStoredProject(project); - dbs.addRecord(nml); + dbs.getQueryInterface().addRecord(nml); } } List listIds = new ArrayList(); @@ -161,7 +161,7 @@ private List processMailingLists(MailAccessor mailAccessor) { private List getMailingLists(StoredProject sp) { Map params = new HashMap(); params.put("storedProject", sp); - return dbs.findObjectsByProperties(MailingList.class, params); + return dbs.getQueryInterface().findObjectsByProperties(MailingList.class, params); } @Override diff --git a/plug-ins/maildir/src/main/java/eu/sqooss/plugins/maildir/MailMessageJob.java b/plug-ins/maildir/src/main/java/eu/sqooss/plugins/maildir/MailMessageJob.java index 11af8e2fc..a6497c426 100644 --- a/plug-ins/maildir/src/main/java/eu/sqooss/plugins/maildir/MailMessageJob.java +++ b/plug-ins/maildir/src/main/java/eu/sqooss/plugins/maildir/MailMessageJob.java @@ -81,9 +81,9 @@ public long priority() { protected void run() throws Exception { DBService dbs = AlitheiaCore.getInstance().getDBService(); - dbs.startDBSession(); + dbs.getSessionManager().startDBSession(); - ml = dbs.attachObjectToDBSession(ml); + ml = dbs.getSessionManager().attachObjectToDBSession(ml); project = ml.getStoredProject(); ProjectAccessor spAccessor = AlitheiaCore.getInstance().getTDSService().getAccessor(project.getId()); @@ -188,10 +188,10 @@ protected void run() throws Exception { mmsg.setSubject(subject); mmsg.setFilename(fileName); - dbs.addRecord(mmsg); + dbs.getQueryInterface().addRecord(mmsg); debug("Adding message " + mm.getMessageID()); - if (dbs.commitDBSession()) { + if (dbs.getSessionManager().commitDBSession()) { if (!mailAccessor.markMessageAsSeen(ml.getListId(), fileName)) warn("Failed to mark message <" + fileName diff --git a/plug-ins/mailthreadresolver/src/main/java/eu/sqooss/plugins/mailthreadresolver/MailThreadResolver.java b/plug-ins/mailthreadresolver/src/main/java/eu/sqooss/plugins/mailthreadresolver/MailThreadResolver.java index ffc502be8..651222269 100755 --- a/plug-ins/mailthreadresolver/src/main/java/eu/sqooss/plugins/mailthreadresolver/MailThreadResolver.java +++ b/plug-ins/mailthreadresolver/src/main/java/eu/sqooss/plugins/mailthreadresolver/MailThreadResolver.java @@ -37,8 +37,11 @@ import javax.mail.internet.MimeMessage; +import org.hibernate.hql.ast.HqlASTFactory; + import eu.sqooss.core.AlitheiaCore; import eu.sqooss.service.db.DBService; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.MailMessage; import eu.sqooss.service.db.MailingList; import eu.sqooss.service.db.MailingListThread; @@ -88,14 +91,14 @@ public void setUpdateParams(StoredProject sp, Logger l) { @Override public void update() throws Exception { dbs = AlitheiaCore.getInstance().getDBService(); - dbs.startDBSession(); - sp = dbs.attachObjectToDBSession(sp); + dbs.getSessionManager().startDBSession(); + sp = dbs.getSessionManager().attachObjectToDBSession(sp); lists = sp.getMailingLists(); for (MailingList l : lists) { this.ml = l; realupdate(); } - if (dbs.isDBSessionActive())dbs.commitDBSession(); + if (dbs.getSessionManager().isDBSessionActive())dbs.getSessionManager().commitDBSession(); } @Override @@ -104,8 +107,8 @@ public int progress() { } private void realupdate() throws Exception { - if (!dbs.isDBSessionActive()) dbs.startDBSession(); - ml = dbs.attachObjectToDBSession(ml); + if (!dbs.getSessionManager().isDBSessionActive()) dbs.getSessionManager().startDBSession(); + ml = dbs.getSessionManager().attachObjectToDBSession(ml); int newThreads = 0, updatedThreads = 0, processedEmails = 0; MailMessage lastEmail = null; lastEmail = ml.getLatestEmail(); @@ -113,7 +116,7 @@ private void realupdate() throws Exception { if (lastEmail == null) { info("No mail messages for list " + ml); - dbs.commitDBSession(); + dbs.getSessionManager().commitDBSession(); return; //No messages for this mailing list } @@ -128,17 +131,17 @@ private void realupdate() throws Exception { Map params = new HashMap(1); params.put(paramMl, ml); - List mmList = (List) dbs.doHQL(query, params); + List mmList = (List) dbs.getQueryInterface(HQLQueryInterface.class).doHQL(query, params); if (mmList.isEmpty()) { info("No unprocessed mail messages found for list " + ml); - dbs.commitDBSession(); + dbs.getSessionManager().commitDBSession(); return; } for (Long mailId : mmList) { - if (!dbs.isDBSessionActive()) - dbs.startDBSession(); + if (!dbs.getSessionManager().isDBSessionActive()) + dbs.getSessionManager().startDBSession(); MailMessage mail = MailMessage.loadDAObyId(mailId, MailMessage.class); // Message has been already added to thread @@ -267,7 +270,7 @@ private void realupdate() throws Exception { /* Create a new thread */ mlt = new MailingListThread(ml, mail.getSendDate()); - dbs.addRecord(mlt); + dbs.getQueryInterface().addRecord(mlt); mail.setThread(mlt); mail.setDepth(0); debug("Adding new thread " + mlt.getId()); @@ -276,16 +279,16 @@ private void realupdate() throws Exception { if (mail.getThread() == null) warn("Mail message " + mail + " was not assigned any thread"); - dbs.commitDBSession(); + dbs.getSessionManager().commitDBSession(); processedEmails ++; progress = (float)((double)processedEmails / (double)mmList.size()) * 100; } - dbs.startDBSession(); + dbs.getSessionManager().startDBSession(); info("Mail thread updater - " + ml.getListId() + " " + processedEmails + " new emails, " + newThreads + " new threads, " + updatedThreads + " thread updates" ); - if (dbs.isDBSessionActive()) dbs.commitDBSession(); + if (dbs.getSessionManager().isDBSessionActive()) dbs.getSessionManager().commitDBSession(); } @Override diff --git a/plug-ins/moduleresolver/src/main/java/eu/sqooss/plugins/moduleresolver/ModuleResolver.java b/plug-ins/moduleresolver/src/main/java/eu/sqooss/plugins/moduleresolver/ModuleResolver.java index 78bee23d3..844a0edef 100644 --- a/plug-ins/moduleresolver/src/main/java/eu/sqooss/plugins/moduleresolver/ModuleResolver.java +++ b/plug-ins/moduleresolver/src/main/java/eu/sqooss/plugins/moduleresolver/ModuleResolver.java @@ -7,6 +7,7 @@ import eu.sqooss.core.AlitheiaCore; import eu.sqooss.service.db.DBService; import eu.sqooss.service.db.Directory; +import eu.sqooss.service.db.HQLQueryInterface; import eu.sqooss.service.db.ProjectFile; import eu.sqooss.service.db.ProjectVersion; import eu.sqooss.service.db.StoredProject; @@ -45,11 +46,11 @@ public void setUpdateParams(StoredProject sp, Logger l) { @Override public void update() throws Exception { - db.startDBSession(); + db.getSessionManager().startDBSession(); Map params = new HashMap(); params.put("sp", sp); - List toProcess = (List) db.doHQL(notProcessed, params); + List toProcess = (List) db.getQueryInterface(HQLQueryInterface.class).doHQL(notProcessed, params); if (toProcess.size() == 0) { log.info("No versions to process"); @@ -59,8 +60,8 @@ public void update() throws Exception { int i = 0; for (ProjectVersion pv : toProcess) { i ++; - if (!db.isDBSessionActive()) db.startDBSession(); - pv = db.attachObjectToDBSession(pv); + if (!db.getSessionManager().isDBSessionActive()) db.getSessionManager().startDBSession(); + pv = db.getSessionManager().attachObjectToDBSession(pv); log.info("ModuleResolver: Processing version: " + pv); for (ProjectFile pf : pv.allDirs()) { @@ -82,7 +83,7 @@ public void update() throws Exception { pf.setModule(false); } progress = ((float)i / (float)toProcess.size()); - db.commitDBSession(); + db.getSessionManager().commitDBSession(); } } diff --git a/plug-ins/svn/src/main/java/eu/sqooss/plugins/updater/svn/SVNUpdaterImpl.java b/plug-ins/svn/src/main/java/eu/sqooss/plugins/updater/svn/SVNUpdaterImpl.java index 32e1a05a5..139569e45 100644 --- a/plug-ins/svn/src/main/java/eu/sqooss/plugins/updater/svn/SVNUpdaterImpl.java +++ b/plug-ins/svn/src/main/java/eu/sqooss/plugins/updater/svn/SVNUpdaterImpl.java @@ -172,8 +172,8 @@ public int progress() { @Override public void update() throws Exception { - dbs.startDBSession(); - project = dbs.attachObjectToDBSession(project); + dbs.getSessionManager().startDBSession(); + project = dbs.getSessionManager().attachObjectToDBSession(project); init(); @@ -195,7 +195,7 @@ public void update() throws Exception { if (r.compareTo(scm.newRevision(latestVersion.getRevisionId())) <= 0) { info("Project is already at the newest version " + r.getUniqueId()); - dbs.commitDBSession(); + dbs.getSessionManager().commitDBSession(); return; } } else { @@ -206,7 +206,7 @@ public void update() throws Exception { zero.setCommitMsg("Artificial revision to include / directory"); zero.setRevisionId("0"); zero.setSequence(0); - dbs.addRecord(zero); + dbs.getQueryInterface().addRecord(zero); ProjectFile root = new ProjectFile(zero); root.setIsDirectory(true); root.setDir(getDirectory("/", true)); @@ -214,9 +214,9 @@ public void update() throws Exception { root.setState(ProjectFileState.added()); root.setValidFrom(zero); root.setValidUntil(zero); - dbs.addRecord(root); - dbs.commitDBSession(); - dbs.startDBSession(); + dbs.getQueryInterface().addRecord(root); + dbs.getSessionManager().commitDBSession(); + dbs.getSessionManager().startDBSession(); latestVersion = ProjectVersion.getLastProjectVersion(project); } commitLog = scm.getCommitLog("", scm.getNextRevision( @@ -274,8 +274,8 @@ public void update() throws Exception { } else { debug(msg + ". Removing"); //dbs.deleteRecord(curVersion); - dbs.rollbackDBSession(); - dbs.startDBSession(); + dbs.getSessionManager().rollbackDBSession(); + dbs.getSessionManager().startDBSession(); continue; } } @@ -283,19 +283,19 @@ public void update() throws Exception { /* * Add files to the database */ - dbs.addRecords(versionFiles); + dbs.getQueryInterface().addRecords(versionFiles); updateValidUntil(curVersion); numRevisions++; dirCache.clear(); - if (!dbs.commitDBSession()) { + if (!dbs.getSessionManager().commitDBSession()) { warn("Intermediate commit failed, failing update"); //restart(); return; } - dbs.startDBSession(); + dbs.getSessionManager().startDBSession(); progress = (float) (((double)numRevisions / (double)commitLog.size()) * 100); } info("Processed " + numRevisions + " revisions"); @@ -306,7 +306,7 @@ public void update() throws Exception { err("Not such repository revision:" + e.getMessage()); throw e; } - dbs.commitDBSession(); + dbs.getSessionManager().commitDBSession(); } private void init() { @@ -387,12 +387,12 @@ private ProjectVersion processCommit(SCMAccessor scm, Revision entry) { curVersion.setCommitMsg(commitMsg); curVersion.setSequence(Integer.MAX_VALUE); - dbs.addRecord(curVersion); + dbs.getQueryInterface().addRecord(curVersion); ProjectVersion prev = curVersion.getPreviousVersion(); curVersion.setSequence(prev.getSequence() + 1); ProjectVersionParent pvp = new ProjectVersionParent(curVersion, prev); - dbs.addRecord(pvp); + dbs.getQueryInterface().addRecord(pvp); debug("Got version " + curVersion.getRevisionId() + " ID " + curVersion.getId()); @@ -424,13 +424,13 @@ private ProjectVersion processCommit(SCMAccessor scm, Revision entry) { Branch b = new Branch(project, FileUtils.basename(copyOp.toPath())); b.getBranchIncoming().add(prev); b.getBranchOutgoing().add(curVersion); - dbs.addRecord(b); + dbs.getQueryInterface().addRecord(b); } if (dirname.equals(tagsPath) || dirname.equals(tagsPath + "/")) { Tag tag = new Tag(curVersion); tag.setName(FileUtils.basename(copyOp.toPath())); - dbs.addRecord(tag); + dbs.getQueryInterface().addRecord(tag); } } diff --git a/pom.xml b/pom.xml index 12683f1ee..988922e5f 100644 --- a/pom.xml +++ b/pom.xml @@ -246,6 +246,8 @@ maven-surefire-plugin 2.7.1 + + ${surefireArgLine} false