Index: lams_admin/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -r98a578d20f9f5ede0b519f4c3a8671bc76e29672 -rb7008b95e3f3054ee6f3696a0579e34a197201ca --- lams_admin/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 98a578d20f9f5ede0b519f4c3a8671bc76e29672) +++ lams_admin/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision b7008b95e3f3054ee6f3696a0579e34a197201ca) @@ -244,6 +244,12 @@ msg.importv1.please.wait =Please wait while creating new users and groups... msg.importv1.only.members =Only import users that are members of organisations/session classes to be imported label.login.as =Login as +sysadmin.import.groups.title = Import Groups +heading.import.results = Import Results +table.heading.organisation.id = Organisation ID +import.groups.intro = Use this screen to bulk import groups and subgroups using an Excel spreadsheet. +import.groups.instructions = When creating a group, make sure the row above it is empty. When creating a subgroup, place it directly under it's parent group. +import.groups.download = Download the groups template to create groups and subgroups. #======= End labels: Exported 238 labels for en AU ===== Index: lams_admin/conf/language/lams/ApplicationResources_en_AU.properties =================================================================== diff -u -r98a578d20f9f5ede0b519f4c3a8671bc76e29672 -rb7008b95e3f3054ee6f3696a0579e34a197201ca --- lams_admin/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision 98a578d20f9f5ede0b519f4c3a8671bc76e29672) +++ lams_admin/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision b7008b95e3f3054ee6f3696a0579e34a197201ca) @@ -244,6 +244,11 @@ msg.importv1.please.wait =Please wait while creating new users and groups... msg.importv1.only.members =Only import users that are members of organisations/session classes to be imported label.login.as =Login as +sysadmin.import.groups.title = Import Groups +heading.import.results = Import Results +table.heading.organisation.id = Organisation ID +import.groups.intro = Use this screen to bulk import groups and subgroups using an Excel spreadsheet. +import.groups.instructions = When creating a group, make sure the row above it is empty. When creating a subgroup, place it directly under it's parent group. +import.groups.download = Download the groups template to create groups and subgroups. - #======= End labels: Exported 238 labels for en AU ===== Index: lams_admin/conf/xdoclet/struts-forms.xml =================================================================== diff -u -r558aecb906b5902a2bfa566c2e68abf2f97352a9 -rb7008b95e3f3054ee6f3696a0579e34a197201ca --- lams_admin/conf/xdoclet/struts-forms.xml (.../struts-forms.xml) (revision 558aecb906b5902a2bfa566c2e68abf2f97352a9) +++ lams_admin/conf/xdoclet/struts-forms.xml (.../struts-forms.xml) (revision b7008b95e3f3054ee6f3696a0579e34a197201ca) @@ -111,4 +111,9 @@ - \ No newline at end of file + + + \ No newline at end of file Index: lams_admin/src/java/org/lamsfoundation/lams/admin/service/IImportService.java =================================================================== diff -u -rf8ae5239ffcb6ac62937458e9750b3780528dc9f -rb7008b95e3f3054ee6f3696a0579e34a197201ca --- lams_admin/src/java/org/lamsfoundation/lams/admin/service/IImportService.java (.../IImportService.java) (revision f8ae5239ffcb6ac62937458e9750b3780528dc9f) +++ lams_admin/src/java/org/lamsfoundation/lams/admin/service/IImportService.java (.../IImportService.java) (revision b7008b95e3f3054ee6f3696a0579e34a197201ca) @@ -41,6 +41,7 @@ public static final String SEPARATOR = "|"; public static final String IMPORT_HELP_PAGE = "Import+Users"; public static final String IMPORTV1_HELP_PAGE = "Import+LAMS+1+Users"; + public static final String IMPORT_GROUPS_HELP_PAGE = "Import+Groups"; /** * Returns true if spreadsheet contains user data. @@ -67,6 +68,14 @@ public List parseSpreadsheet(FormFile fileItem) throws IOException; /** + * + * @param fileItem + * @return + * @throws IOException + */ + public List parseGroupSpreadsheet(FormFile fileItem) throws IOException; + + /** * Returns list of V1 users and orgs after parsing the output of a mysql dump. * @param fileItem * @return Index: lams_admin/src/java/org/lamsfoundation/lams/admin/service/ImportService.java =================================================================== diff -u -rf8ae5239ffcb6ac62937458e9750b3780528dc9f -rb7008b95e3f3054ee6f3696a0579e34a197201ca --- lams_admin/src/java/org/lamsfoundation/lams/admin/service/ImportService.java (.../ImportService.java) (revision f8ae5239ffcb6ac62937458e9750b3780528dc9f) +++ lams_admin/src/java/org/lamsfoundation/lams/admin/service/ImportService.java (.../ImportService.java) (revision b7008b95e3f3054ee6f3696a0579e34a197201ca) @@ -47,16 +47,20 @@ import org.lamsfoundation.lams.themes.CSSThemeVisualElement; import org.lamsfoundation.lams.usermanagement.AuthenticationMethod; import org.lamsfoundation.lams.usermanagement.Organisation; +import org.lamsfoundation.lams.usermanagement.OrganisationState; import org.lamsfoundation.lams.usermanagement.OrganisationType; import org.lamsfoundation.lams.usermanagement.Role; import org.lamsfoundation.lams.usermanagement.SupportedLocale; import org.lamsfoundation.lams.usermanagement.User; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; import org.lamsfoundation.lams.util.Configuration; import org.lamsfoundation.lams.util.ConfigurationKeys; import org.lamsfoundation.lams.util.HashUtil; import org.lamsfoundation.lams.util.MessageService; import org.lamsfoundation.lams.util.audit.IAuditService; +import org.lamsfoundation.lams.web.session.SessionManager; +import org.lamsfoundation.lams.web.util.AttributeNames; /** *

@@ -124,10 +128,22 @@ private static final short ORGANISATION = 1; private static final short ROLES = 2; + // spreadsheet column indexes for groups spreadsheet + private static final short NAME = 0; + private static final short CODE = 1; + private static final short DESCRIPTION = 2; + private static final short LOCALE_ID = 3; + private static final short ORGANISATION_STATE = 4; + private static final short ADMIN_ADD_NEW_USERS = 5; + private static final short ADMIN_BROWSE_ALL_USERS = 6; + private static final short ADMIN_CHANGE_STATUS = 7; + + // class-wide variables ArrayList results = new ArrayList(); ArrayList rowResult = new ArrayList(); private boolean emptyRow; private boolean hasError; + private Organisation parentOrg; private HSSFSheet getSheet(FormFile fileItem) throws IOException { POIFSFileSystem fs = new POIFSFileSystem(fileItem.getInputStream()); @@ -158,6 +174,107 @@ return new ArrayList(); } + // returns x size list where x is number of orgs. + // each item in the list lists the id, name, and parent's id of that org; otherwise + // the items in the list are error messages. + public List parseGroupSpreadsheet(FormFile fileItem) throws IOException { + results = new ArrayList(); + parentOrg = service.getRootOrganisation(); + HSSFSheet sheet = getSheet(fileItem); + int startRow = sheet.getFirstRowNum(); + int endRow = sheet.getLastRowNum(); + + log.debug("sheet rows: "+startRow+".."+endRow); + + UserDTO user = (UserDTO) SessionManager.getSession().getAttribute(AttributeNames.USER); + + HSSFRow row; + Organisation org = null; + for (int i = startRow + 1; i < endRow + 1; i++) { + log.debug("starting row: "+i); + emptyRow = true; + hasError = false; + rowResult = new ArrayList(); + row = sheet.getRow(i); + if (row != null) { + org = parseGroup(row, i); + } + + // an empty row signifies a new group + if (emptyRow) { + log.debug("emptyRow: "+emptyRow); + parentOrg = service.getRootOrganisation(); + continue; + } + if (hasError) { + log.debug("hasError: "+hasError); + results.add(rowResult); + continue; + } else { + //try { + org = service.saveOrganisation(org, user.getUserID()); + rowResult.add(org.getOrganisationId().toString()); + rowResult.add(org.getName()); + rowResult.add(org.getParentOrganisation().getOrganisationId().toString()); + rowResult.add(org.getOrganisationType().getOrganisationTypeId().toString()); + writeOrgAuditLog(org); + // if we just added a group, then the rows under it become it's subgroups + if (parentOrg.getOrganisationType().getOrganisationTypeId().equals(OrganisationType.ROOT_TYPE)) { + parentOrg = org; + } + //} catch (Exception e) { + // log.debug(e); + // rowResult.add(messageService.getMessage("error.fail.add")); + //} + results.add(rowResult); + } + } + log.debug("found "+results.size()+" orgs in spreadsheet."); + return results; + } + + + private Organisation parseGroup(HSSFRow row, int rowIndex) { + Organisation org = new Organisation(); + String[] args = new String[1]; + + String name = parseStringCell(row.getCell(NAME)); + if (name==null || name=="") { + rowResult.add(messageService.getMessage("error.name.required")); + hasError = true; + return null; + } + org.setName(name); + org.setCode(parseStringCell(row.getCell(CODE))); + org.setDescription(parseStringCell(row.getCell(DESCRIPTION))); + + String localeId = parseStringCell(row.getCell(LOCALE_ID)); + SupportedLocale locale = getLocale(localeId); + if (locale==null) { + args[0] = "("+localeId+")"; + rowResult.add(messageService.getMessage("error.locale.invalid", args)); + hasError = true; + } else { + org.setLocale(locale); + } + + String orgStateText = parseStringCell(row.getCell(ORGANISATION_STATE)); + OrganisationState orgState = getOrganisationState(orgStateText); + org.setOrganisationState(orgState); + + org.setOrganisationType((OrganisationType)service.findById(OrganisationType.class, + parentOrg.getOrganisationType().getOrganisationTypeId().equals(OrganisationType.ROOT_TYPE) + ? OrganisationType.COURSE_TYPE : OrganisationType.CLASS_TYPE)); + + org.setParentOrganisation(parentOrg); + org.setCourseAdminCanAddNewUsers(parseBooleanCell(row.getCell(ADMIN_ADD_NEW_USERS))); + org.setCourseAdminCanBrowseAllUsers(parseBooleanCell(row.getCell(ADMIN_BROWSE_ALL_USERS))); + org.setCourseAdminCanChangeStatusOfCourse(parseBooleanCell(row.getCell(ADMIN_CHANGE_STATUS))); + + return (hasError ? null : org); + } + + public List parseV1UsersFile(FormFile fileItem, boolean includeIntegrated) throws IOException { ArrayList users = new ArrayList(); ArrayList orgs = new ArrayList(); @@ -533,6 +650,32 @@ /* * the methods below return legible data from individual cells */ + private boolean parseBooleanCell(HSSFCell cell){ + if (cell!=null) { + String value; + try { + cell.setCellType(HSSFCell.CELL_TYPE_STRING); + if (cell.getStringCellValue()!= null) { + if (cell.getStringCellValue().trim().length()!= 0) { + emptyRow = false; + } + } else { + return false; + } + value = cell.getStringCellValue().trim(); + } catch(Exception e) { + cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC); + double d = cell.getNumericCellValue(); + emptyRow = false; + value = new Long(new Double(d).longValue()).toString(); + } + if (StringUtils.equals(value, "1") || StringUtils.equalsIgnoreCase(value, "true")) { + return true; + } + } + return false; + } + private String parseStringCell(HSSFCell cell){ if (cell!=null) { try { @@ -544,13 +687,13 @@ } else { return null; } - //log.debug("string cell value: "+cell.getStringCellValue().trim()); + log.debug("string cell value: '"+cell.getStringCellValue().trim()+"'"); return cell.getStringCellValue().trim(); } catch(Exception e) { cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC); double d = cell.getNumericCellValue(); emptyRow = false; - //log.debug("numeric cell value: "+d); + log.debug("numeric cell value: '"+d+"'"); return (new Long(new Double(d).longValue()).toString()); } } @@ -689,11 +832,30 @@ } } + // set organisation state to active if cell is empty + private OrganisationState getOrganisationState(String orgStateText) { + if (StringUtils.equals(orgStateText, "hidden")) { + return (OrganisationState)service.findById(OrganisationState.class, OrganisationState.HIDDEN); + } else if (StringUtils.equals(orgStateText, "archived")) { + return (OrganisationState)service.findById(OrganisationState.class, OrganisationState.ARCHIVED); + } else { + return (OrganisationState)service.findById(OrganisationState.class, OrganisationState.ACTIVE); + } + } + private void writeAuditLog(User user) { String[] args = new String[2]; args[0] = user.getLogin()+"("+user.getUserId()+")"; args[1] = user.getFullName(); String message = messageService.getMessage("audit.user.create", args); auditService.log(AdminConstants.MODULE_NAME, message); } + + private void writeOrgAuditLog(Organisation org) { + String[] args = new String[2]; + args[0] = org.getName()+"("+org.getOrganisationId()+")"; + args[1] = org.getOrganisationType().getName(); + String message = messageService.getMessage("audit.organisation.create", args); + auditService.log(AdminConstants.MODULE_NAME, message); + } } Index: lams_admin/src/java/org/lamsfoundation/lams/admin/web/action/ImportGroupsAction.java =================================================================== diff -u --- lams_admin/src/java/org/lamsfoundation/lams/admin/web/action/ImportGroupsAction.java (revision 0) +++ lams_admin/src/java/org/lamsfoundation/lams/admin/web/action/ImportGroupsAction.java (revision b7008b95e3f3054ee6f3696a0579e34a197201ca) @@ -0,0 +1,79 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.admin.web.action; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.struts.action.Action; +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; +import org.apache.struts.upload.FormFile; +import org.lamsfoundation.lams.admin.service.AdminServiceProxy; +import org.lamsfoundation.lams.admin.service.IImportService; +import org.lamsfoundation.lams.admin.web.ImportExcelForm; + +/** + * @author jliew + * + * @struts:action path="/importgroups" + * name="ImportGroupsForm" + * scope="request" + * validate="false" + * + * @struts:action-forward name="importGroups" path=".importGroups" + * @struts:action-forward name="sysadmin" path="/sysadminstart.do" + * + */ +public class ImportGroupsAction extends Action { + + public ActionForward execute(ActionMapping mapping, + ActionForm form, + HttpServletRequest request, + HttpServletResponse response) throws Exception { + + if (isCancelled(request)) { + return mapping.findForward("sysadmin"); + } + + IImportService importService = AdminServiceProxy.getImportService(getServlet().getServletContext()); + ImportExcelForm importForm = (ImportExcelForm)form; + importForm.setOrgId(0); + FormFile file = importForm.getFile(); + + // validation + if (file==null || file.getFileSize()<=0) { + return mapping.findForward("importGroups"); + } + + List results = importService.parseGroupSpreadsheet(file); + request.setAttribute("results", results); + + return mapping.findForward("importGroups"); + } + +} Index: lams_admin/src/java/org/lamsfoundation/lams/admin/web/action/SysAdminStartAction.java =================================================================== diff -u -r558aecb906b5902a2bfa566c2e68abf2f97352a9 -rb7008b95e3f3054ee6f3696a0579e34a197201ca --- lams_admin/src/java/org/lamsfoundation/lams/admin/web/action/SysAdminStartAction.java (.../SysAdminStartAction.java) (revision 558aecb906b5902a2bfa566c2e68abf2f97352a9) +++ lams_admin/src/java/org/lamsfoundation/lams/admin/web/action/SysAdminStartAction.java (.../SysAdminStartAction.java) (revision b7008b95e3f3054ee6f3696a0579e34a197201ca) @@ -62,6 +62,7 @@ links.add(new LinkBean("config.do", "sysadmin.config.settings.edit")); links.add(new LinkBean("toolcontentlist.do", "sysadmin.edit.default.tool.content")); links.add(new LinkBean("usersearch.do", "admin.user.find")); + links.add(new LinkBean("importgroups.do", "sysadmin.import.groups.title")); links.add(new LinkBean("importexcel.do", "admin.user.import")); links.add(new LinkBean("importv1.do", "admin.importv1.title")); links.add(new LinkBean("disabledmanage.do", "admin.list.disabled.users")); @@ -75,6 +76,7 @@ } else if (service.isUserGlobalGroupAdmin()) { LinkBean linkBean = new LinkBean("usersearch.do", "admin.user.find"); links.add(linkBean); + links.add(new LinkBean("importgroups.do", "sysadmin.import.groups.title")); links.add(new LinkBean("importexcel.do", "admin.user.import")); links.add(new LinkBean("importv1.do", "admin.importv1.title")); links.add(new LinkBean("disabledmanage.do", "admin.list.disabled.users")); Index: lams_admin/web/WEB-INF/tiles/tiles-defs.xml =================================================================== diff -u -r421ce205a9ac39deba7996da169dbbc637c4d20c -rb7008b95e3f3054ee6f3696a0579e34a197201ca --- lams_admin/web/WEB-INF/tiles/tiles-defs.xml (.../tiles-defs.xml) (revision 421ce205a9ac39deba7996da169dbbc637c4d20c) +++ lams_admin/web/WEB-INF/tiles/tiles-defs.xml (.../tiles-defs.xml) (revision b7008b95e3f3054ee6f3696a0579e34a197201ca) @@ -1,6 +1,11 @@ + + + + + Index: lams_admin/web/file/lams_groups_template.xls =================================================================== diff -u Binary files differ Index: lams_admin/web/import/importGroups.jsp =================================================================== diff -u --- lams_admin/web/import/importGroups.jsp (revision 0) +++ lams_admin/web/import/importGroups.jsp (revision b7008b95e3f3054ee6f3696a0579e34a197201ca) @@ -0,0 +1,78 @@ +<%@ include file="/taglibs.jsp"%> +<%@ page import="org.lamsfoundation.lams.admin.service.IImportService" %> +<%@ page import="java.util.List" %> +<%@ page import="org.lamsfoundation.lams.usermanagement.OrganisationType" %> + +

+ + : +

+ + + +

 

+ + +

+ + + <% + List results = (List)request.getAttribute("results"); + for (int i=0; i"); + List rowResult = (List)results.get(i); + if (rowResult != null && rowResult.size() >= 4) { + if (rowResult.get(3).equals(OrganisationType.COURSE_TYPE.toString())) { + out.print(""); + out.print(""); + } else if (rowResult.get(3).equals(OrganisationType.CLASS_TYPE.toString())) { + out.print(""); + out.print(""); + } + } else { // it's an error message + out.print(""); + } + out.println(""); + } + %> +
"+rowResult.get(0)+""+rowResult.get(1)+""+rowResult.get(0)+""+rowResult.get(1)+""); + for (int j=0; j"); + } + out.print("
+

 

+
+
+ +

+

+

+

+

+ + + + + + + + + +
+

+   + +

+ +
\ No newline at end of file