Index: lams_common/src/java/org/lamsfoundation/lams/usermanagement/service/UserManagementService.java =================================================================== diff -u -r7828086c1601ca9e307e9c1758a2be3fe7773943 -rc1c22cae1f9de439732bbb93eed949b583917af9 --- lams_common/src/java/org/lamsfoundation/lams/usermanagement/service/UserManagementService.java (.../UserManagementService.java) (revision 7828086c1601ca9e307e9c1758a2be3fe7773943) +++ lams_common/src/java/org/lamsfoundation/lams/usermanagement/service/UserManagementService.java (.../UserManagementService.java) (revision c1c22cae1f9de439732bbb93eed949b583917af9) @@ -645,14 +645,13 @@ UserOrganisation uo = getUserOrganisation(user.getUserId(), org.getOrganisationId()); if (uo == null) { + if (rolesList.isEmpty()) { + // user has no roles and shoud have none, so nothing to do + return; + } uo = new UserOrganisation(user, org); save(uo); log.debug("added " + user.getLogin() + " to " + org.getName()); - Set uos; - if ((uos = org.getUserOrganisations()) == null) { - uos = new HashSet(); - } - uos.add(uo); } // if user is to be added to a class, make user a member of parent @@ -701,8 +700,12 @@ } } } - uo.setUserOrganisationRoles(uors); - saveUser(user); + if (uors.isEmpty()) { + delete(uo); + } else { + uo.setUserOrganisationRoles(uors); + save(uo); + } // make sure group managers have monitor and learner in each subgroup checkGroupManager(user, org); } Index: lams_common/src/java/org/lamsfoundation/lams/web/session/SessionManager.java =================================================================== diff -u -r7f420dcfde4984d32bb8acedde964ca613c1cb6c -rc1c22cae1f9de439732bbb93eed949b583917af9 --- lams_common/src/java/org/lamsfoundation/lams/web/session/SessionManager.java (.../SessionManager.java) (revision 7f420dcfde4984d32bb8acedde964ca613c1cb6c) +++ lams_common/src/java/org/lamsfoundation/lams/web/session/SessionManager.java (.../SessionManager.java) (revision c1c22cae1f9de439732bbb93eed949b583917af9) @@ -202,13 +202,20 @@ } /** - * Returns number of sessions stored in the container. + * Returns number of all sessions stored in the container. */ - public static int getSessionCount() { + public static int getSessionTotalCount() { return SessionManager.sessionIdMapping.size(); } /** + * Returns number of authenticated sessions stored in the container. + */ + public static int getSessionUserCount() { + return SessionManager.loginMapping.size(); + } + + /** * Lists all logins with their assigned sessions */ public static Map> getLoginToSessionIDMappings() { Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/NodeFactory.java =================================================================== diff -u -r1df79e8f3202227e5d076d5823aa74c58c48504c -rc1c22cae1f9de439732bbb93eed949b583917af9 --- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/NodeFactory.java (.../NodeFactory.java) (revision 1df79e8f3202227e5d076d5823aa74c58c48504c) +++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/NodeFactory.java (.../NodeFactory.java) (revision c1c22cae1f9de439732bbb93eed949b583917af9) @@ -21,6 +21,7 @@ * **************************************************************** */ + package org.lamsfoundation.lams.contentrepository.service; import java.io.InputStream; @@ -36,11 +37,11 @@ import org.lamsfoundation.lams.contentrepository.IValue; import org.lamsfoundation.lams.contentrepository.NodeType; import org.lamsfoundation.lams.contentrepository.PropertyName; +import org.lamsfoundation.lams.contentrepository.dao.INodeDAO; import org.lamsfoundation.lams.contentrepository.exception.FileException; import org.lamsfoundation.lams.contentrepository.exception.InvalidParameterException; import org.lamsfoundation.lams.contentrepository.exception.ItemNotFoundException; import org.lamsfoundation.lams.contentrepository.exception.ValueFormatException; -import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; @@ -59,11 +60,15 @@ protected Logger log = Logger.getLogger(NodeFactory.class); private BeanFactory beanFactory = null; - private IUserManagementService userManagementService = null; + private INodeDAO nodeDAO = null; + public NodeFactory() { + super(); + } + /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#createFileNode(org.lamsfoundation.lams. * contentrepository.CrWorkspace, org.lamsfoundation.lams.contentrepository.service.SimpleVersionedNode, * java.lang.String, java.io.InputStream, java.lang.String, java.lang.String, java.lang.String) @@ -82,7 +87,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#createPackageNode(org.lamsfoundation.lams. * contentrepository.CrWorkspace, java.lang.String, java.lang.String) */ @@ -99,7 +104,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#createDataNode(org.lamsfoundation.lams. * contentrepository.CrWorkspace, org.lamsfoundation.lams.contentrepository.service.SimpleVersionedNode, * java.lang.String) @@ -139,7 +144,7 @@ /* * (non-Javadoc) - * + * * @see * org.lamsfoundation.lams.contentrepository.service.INodeFactory#getNode(org.lamsfoundation.lams.contentrepository. * CrNode, java.lang.Long) @@ -154,7 +159,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#getNode(java.lang.Long, java.lang.Long, * java.lang.Long) */ @@ -171,7 +176,7 @@ CrNode node = null; - node = (CrNode) getUserManagementService().findById(CrNode.class, uuid); + node = (CrNode) nodeDAO.find(CrNode.class, uuid); if (node == null) { throw new ItemNotFoundException("Node " + uuid + " not found."); @@ -189,7 +194,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#getNode(java.lang.Long, java.lang.Long, * java.lang.Long, java.lang.String) */ @@ -215,7 +220,7 @@ /* * (non-Javadoc) - * + * * @see * org.lamsfoundation.lams.contentrepository.service.INodeFactory#copy(org.lamsfoundation.lams.contentrepository. * service.SimpleVersionedNode) @@ -230,7 +235,7 @@ /** * Private method to handle the recursive copy. The parent node is needed to set up the * node -> parent link in the CrNode object. - * + * * @param originalNode * @param parentNode * @return new Node @@ -263,7 +268,7 @@ } } - // copy any attached file. don't actually copy the file - set up + // copy any attached file. don't actually copy the file - set up // and input stream and the file will be copied when the node is saved. // this is likely to recopy the Filename and Mimetype properties. if (originalNode.isNodeType(NodeType.FILENODE)) { @@ -293,10 +298,31 @@ * ********************************************************** */ + /* + * (non-Javadoc) + * + * @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#getNodeDAO() + */ + @Override + public INodeDAO getNodeDAO() { + return nodeDAO; + } + + /* + * (non-Javadoc) + * + * @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#setNodeDAO(org.lamsfoundation.lams. + * contentrepository.dao.INodeDAO) + */ + @Override + public void setNodeDAO(INodeDAO nodeDAO) { + this.nodeDAO = nodeDAO; + } + /* **** Method for BeanFactoryAware interface *****************/ /* * (non-Javadoc) - * + * * @see * org.lamsfoundation.lams.contentrepository.service.INodeFactory#setBeanFactory(org.springframework.beans.factory. * BeanFactory) @@ -306,12 +332,4 @@ this.beanFactory = beanFactory; } - public IUserManagementService getUserManagementService() { - // this can not be done by injection as bean factory is not fully initialised when it happens and we get an exception on start up - if (userManagementService == null) { - userManagementService = beanFactory.getBean("userManagementService", IUserManagementService.class); - } - return userManagementService; - } - -} \ No newline at end of file +} Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/SimpleVersionedNode.java =================================================================== diff -u -r1df79e8f3202227e5d076d5823aa74c58c48504c -rc1c22cae1f9de439732bbb93eed949b583917af9 --- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/SimpleVersionedNode.java (.../SimpleVersionedNode.java) (revision 1df79e8f3202227e5d076d5823aa74c58c48504c) +++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/SimpleVersionedNode.java (.../SimpleVersionedNode.java) (revision c1c22cae1f9de439732bbb93eed949b583917af9) @@ -21,6 +21,7 @@ * **************************************************************** */ + package org.lamsfoundation.lams.contentrepository.service; import java.io.ByteArrayInputStream; @@ -54,13 +55,14 @@ import org.lamsfoundation.lams.contentrepository.NodeType; import org.lamsfoundation.lams.contentrepository.PropertyName; import org.lamsfoundation.lams.contentrepository.PropertyType; +import org.lamsfoundation.lams.contentrepository.dao.IFileDAO; +import org.lamsfoundation.lams.contentrepository.dao.INodeDAO; import org.lamsfoundation.lams.contentrepository.exception.FileException; import org.lamsfoundation.lams.contentrepository.exception.InvalidParameterException; import org.lamsfoundation.lams.contentrepository.exception.ItemNotFoundException; import org.lamsfoundation.lams.contentrepository.exception.RepositoryRuntimeException; import org.lamsfoundation.lams.contentrepository.exception.ValidationException; import org.lamsfoundation.lams.contentrepository.exception.ValueFormatException; -import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; import org.lamsfoundation.lams.util.FileUtil; /** @@ -105,11 +107,10 @@ private ITicket ticket = null; // transient data - using for grouping nodes in a session /* Spring configured varibles */ - private IRepositoryService repositoryService; - private IUserManagementService userManagementService; + private INodeDAO nodeDAO = null; + private IFileDAO fileDAO = null; + private INodeFactory nodeFactory = null; - private INodeFactory nodeFactory; - // TODO This is a case for AOP! /** * Check that all the necessary objects exists - node, nodeVersion, nodeDAO and fileDAO @@ -125,10 +126,13 @@ throw new RepositoryRuntimeException("Node details missing (nodeVersion=null). " + specialisedMessage); } - if (repositoryService == null) { - throw new RepositoryRuntimeException( - "Node details missing (repositoryService=null). " + specialisedMessage); + if (nodeDAO == null) { + throw new RepositoryRuntimeException("Node details missing (nodeDAO=null). " + specialisedMessage); } + + if (fileDAO == null) { + throw new RepositoryRuntimeException("Node details missing (fileDAO=null). " + specialisedMessage); + } } /** Add a child to the node. To be used by SimpleVersionedNode and the NodeFactory only */ @@ -146,7 +150,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, java.lang.String, * int) */ @@ -158,7 +162,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, java.lang.String) */ @Override @@ -169,7 +173,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, boolean) */ @Override @@ -180,7 +184,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, double) */ @Override @@ -191,7 +195,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, long) */ @Override @@ -202,7 +206,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, java.util.Calendar) */ @Override @@ -269,7 +273,7 @@ /** * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#isNodeType(java.lang.String) */ @Override @@ -282,7 +286,7 @@ * Get the history for this node. Quite intensive operation * as it has to build all the data structures. Can't be easily * cached. - * + * * @return SortedSet of IVersionDetail objects, ordered by version */ @Override @@ -378,7 +382,7 @@ * of the caller to close the stream. Note: this should only be * called once the node is saved - do not call it directly after * setting the file stream - * + * * If the node is a package node, it will get the input stream * of the first file. */ @@ -388,7 +392,7 @@ if (isNodeType(NodeType.FILENODE)) { - return repositoryService.daoGetFile(node.getNodeId(), nodeVersion.getVersionId()); + return fileDAO.getFile(node.getNodeId(), nodeVersion.getVersionId()); } else if (isNodeType(NodeType.PACKAGENODE)) { @@ -414,7 +418,7 @@ /** * Set the file, passed in as an inputstream. The stream will be closed * when the file is saved. Only nodes of type FILENODE can have a file! - * + * * @param iStream * mandatory * @param filename @@ -490,7 +494,7 @@ * we could just be doing a setProperty save, in which case the file * will already exist. *
  • Package nodes must not have a file, must have a INITIALPATH property - * + * * @throws ValidationException * if problems exist. */ @@ -522,7 +526,7 @@ // if it is a new node or a new version then it must have a file, otherwise check on disk. // version id will always be set. uuid isn't set until the record is written to the db, // but don't want to rely on that if we can help it in case it changes in future. - if (newIStream == null && (uuid == null || !repositoryService.daoFileExists(uuid, versionId))) { + if (newIStream == null && (uuid == null || !fileDAO.fileExists(uuid, versionId))) { errors = errors + "\nNode is a file node but the file is missing. "; } } catch (FileException fe) { @@ -553,19 +557,19 @@ * Save the changes to this node. This method must be called when saving a file * or package node for the first time - it does both the database and the file * saves. - * + * * If it is a file node, then it writes out the db changes and then saves * the file. - * + * * If is is a package node, then it writes out the db changes for all the nodes, * then saves all the file. Why do it this way - we want to do all the file * changes at the end as they cannot be rolled back if there is a db error. - * + * * This method only works as we know that we have two levels of nodes - the * childNodes can't have their own childNodes. If this is no longer the case, * this method and copy() will need to be changed. + * * - * * TODO This needs a lot of testing */ protected Long save() throws ValidationException, FileException { @@ -618,7 +622,7 @@ SimpleVersionedNode element = (SimpleVersionedNode) writtenIter.next(); int delStatus = -1; try { - delStatus = repositoryService.daoDelete(element.getUUID(), element.getVersion()); + delStatus = fileDAO.delete(element.getUUID(), element.getVersion()); } catch (Exception e2) { // things are getting bad - throwing exceptions on the delete! } @@ -627,8 +631,7 @@ : element.getFilePath(); } else { failedDeleted = failedDeleted != null - ? failedDeleted + File.pathSeparator + element.getFilePath() - : element.getFilePath(); + ? failedDeleted + File.pathSeparator + element.getFilePath() : element.getFilePath(); } } String msg = "Result of rolling back file changes:"; @@ -663,7 +666,7 @@ // nodeDAO to take care of insert or update (uses saveOrUpdate) // the nodeVersion and nodeVersionProperty collections cascade // updates and deletes, so we can just save the node! - userManagementService.save(node); + nodeDAO.saveOrUpdate(node); // child nodes are done manually as the set is lazy loaded // and can't work out how to do that properly using the DAO template! @@ -672,21 +675,21 @@ Iterator iter = childNodes.iterator(); while (iter.hasNext()) { SimpleVersionedNode node = (SimpleVersionedNode) iter.next(); - userManagementService.save(node.getNode()); + nodeDAO.saveOrUpdate(node.getNode()); } } } /** * Write the file out (if one exists). Sets the private attribute filePath. - * + * * @return the path to which the file was written */ private void writeFile() throws FileException { String filePath = null; if (newIStream != null) { - filePath = repositoryService.daoWriteFile(node.getNodeId(), nodeVersion.getVersionId(), newIStream); + filePath = fileDAO.writeFile(node.getNodeId(), nodeVersion.getVersionId(), newIStream); } setFilePath(filePath); } @@ -708,7 +711,7 @@ /** * Another case for the factory? - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#getNode(String relPath) */ @Override @@ -720,7 +723,7 @@ log.debug("getNode for path " + relPath + " start."); } - CrNode childNode = repositoryService.daoFindChildNode(nodeVersion, relPath); + CrNode childNode = nodeDAO.findChildNode(nodeVersion, relPath); if (childNode != null) { return nodeFactory.getNode(childNode, null); @@ -732,12 +735,12 @@ /** * If no nodes are found, returns an empty set. - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#getChildNodes() */ @Override public Set getChildNodes() { - List childCrNodes = repositoryService.daoFindChildNodes(nodeVersion); + List childCrNodes = nodeDAO.findChildNodes(nodeVersion); Set childNodes = new HashSet(); if (childCrNodes != null) { @@ -788,20 +791,20 @@ */ @Override public boolean hasNodes() { - List childNodes = repositoryService.daoFindChildNodes(nodeVersion); + List childNodes = nodeDAO.findChildNodes(nodeVersion); return (childNodes != null && childNodes.size() > 0); } /** * Delete all versions of this node, returning the number of nodes * deleted. If it is a package node, all child nodes will be deleted. - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNodeAdmin#deleteNode() */ @Override public List deleteNode() { - // first make a list of all the versions to delete. + // first make a list of all the versions to delete. // don't iterate over the set, deleting as we go so that // we can't run into any issues trying to access something // that is deleted or belongs to an iterator. @@ -835,16 +838,16 @@ // doing file system changes if the db would fail later. deleteVersionFromDB(nodeKeysDeleted); - // now delete the files. If it fails due to the file not being found, then + // now delete the files. If it fails due to the file not being found, then // that's fine. ArrayList failedList = new ArrayList(); Iterator iter = nodeKeysDeleted.iterator(); while (iter.hasNext()) { NodeKey nk = (NodeKey) iter.next(); try { - int delStatus = repositoryService.daoDelete(nk.getUuid(), nk.getVersion()); + int delStatus = fileDAO.delete(nk.getUuid(), nk.getVersion()); if (delStatus == -1) { - failedList.add(repositoryService.daoGetFilePath(nk.getUuid(), nk.getVersion())); + failedList.add(fileDAO.getFilePath(nk.getUuid(), nk.getVersion())); } } catch (FileException e) { log.error("FileException occured while deleting files for " + nodeDescription, e); @@ -895,15 +898,15 @@ // if this was the last version for the node, delete the node if (node.getCrNodeVersions() == null || node.getCrNodeVersions().size() == 0) { - userManagementService.delete(node); + nodeDAO.delete(node); } } /** * Process files in the package. Create a List of file nodes but do not persist * the nodes. - * + * * @param dirPath: * the directory from which to get files. Mandatory. * @param packageNode: @@ -1022,11 +1025,11 @@ /** * Copy the supplied node/version to a new node. Does not copy the history * of the node. Copies any child nodes of the current version. All files are duplicated. - * + * * This method only works as we know that we have two levels of nodes - the * childNodes can't have their own childNodes. If this is no longer the case, * this method and SimpleVersionedNode.save() will need to be changed. - * + * * @throws FileException * will occur if there is a problem reading a file from the repository * @throws InvalidParameterException @@ -1077,19 +1080,45 @@ * ********************************************************** */ - public void setRepositoryService(IRepositoryService repositoryService) { - this.repositoryService = repositoryService; + /** + * @return Returns the nodeDAO. + */ + public INodeDAO getNodeDAO() { + return nodeDAO; } - public void setNodeFactory(INodeFactory nodeFactory) { - this.nodeFactory = nodeFactory; + /** + * @param nodeDAO + * The nodeDAO to set. + */ + public void setNodeDAO(INodeDAO nodeDAO) { + this.nodeDAO = nodeDAO; } - public void setUserManagementService(IUserManagementService userManagementService) { - this.userManagementService = userManagementService; + /** + * @return Returns the fileDAO. + */ + public IFileDAO getFileDAO() { + return fileDAO; } /** + * @param fileDAO + * The fileDAO to set. + */ + public void setFileDAO(IFileDAO fileDAO) { + this.fileDAO = fileDAO; + } + + public INodeFactory getNodeFactory() { + return nodeFactory; + } + + public void setNodeFactory(INodeFactory nodeFactory) { + this.nodeFactory = nodeFactory; + } + + /** * Clean up any resources that will not be cleaned up by the garbage * collector after this object is destroyed. At present, all it does is * close the filestream if needed @@ -1104,4 +1133,5 @@ log.debug("Unable to close stream - was it already closed perhaps?", e); } } -} \ No newline at end of file + +}