Index: lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java =================================================================== diff -u -r146c434b9071ee5a83366cc892327193aa8b18b9 -r5caa0c70153ab564c5d8e347c4af4baf53b01fd0 --- lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java (.../ObjectExtractor.java) (revision 146c434b9071ee5a83366cc892327193aa8b18b9) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java (.../ObjectExtractor.java) (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -91,6 +91,7 @@ import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.WorkspaceFolder; import org.lamsfoundation.lams.util.AuthoringJsonTags; +import org.lamsfoundation.lams.util.CommonConstants; import org.lamsfoundation.lams.util.Configuration; import org.lamsfoundation.lams.util.ConfigurationKeys; import org.lamsfoundation.lams.util.DateUtil; @@ -113,9 +114,6 @@ */ public class ObjectExtractor implements IObjectExtractor { - public static final Integer DEFAULT_COORD = new Integer(10); // default coordinate used if the entry came from Flash - // is 0 or less. - protected IBaseDAO baseDAO = null; protected ILearningDesignDAO learningDesignDAO = null; protected IActivityDAO activityDAO = null; @@ -1077,7 +1075,7 @@ // the coordinate can be Integer or Double in JSON, need to be ready for any Number number = (Number) JsonUtil.opt(details, tag); Integer coord = number == null ? null : number.intValue(); - return (coord == null) || (coord >= 0) ? coord : ObjectExtractor.DEFAULT_COORD; + return (coord == null) || (coord >= 0) ? coord : CommonConstants.DEFAULT_COORD; } private void clearGrouping(Activity activity) { Index: lams_central/src/java/org/lamsfoundation/lams/authoring/service/AuthoringService.java =================================================================== diff -u -r471b903caa3365758fbdec0a22440b1b0b3f2947 -r5caa0c70153ab564c5d8e347c4af4baf53b01fd0 --- lams_central/src/java/org/lamsfoundation/lams/authoring/service/AuthoringService.java (.../AuthoringService.java) (revision 471b903caa3365758fbdec0a22440b1b0b3f2947) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/service/AuthoringService.java (.../AuthoringService.java) (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -112,14 +112,15 @@ import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; +import org.lamsfoundation.lams.workspace.dto.FolderContentDTO; import org.lamsfoundation.lams.workspace.service.IWorkspaceManagementService; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; /** * @author Manpreet Minhas */ -public class AuthoringService implements IAuthoringService, BeanFactoryAware { +public class AuthoringService implements IAuthoringFullService, BeanFactoryAware { protected Logger log = Logger.getLogger(AuthoringService.class); @@ -354,21 +355,13 @@ } /** - * @see org.lamsfoundation.lams.authoring.service.IAuthoringService#getLearningDesign(java.lang.Long) + * @see org.lamsfoundation.lams.authoring.service.IAuthoringFullService#getLearningDesign(java.lang.Long) */ @Override public LearningDesign getLearningDesign(Long learningDesignID) { return learningDesignDAO.getLearningDesignById(learningDesignID); } - /** - * @see org.lamsfoundation.lams.authoring.service.IAuthoringService#saveLearningDesign(org.lamsfoundation.lams.learningdesign.LearningDesign) - */ - @Override - public void saveLearningDesign(LearningDesign learningDesign) { - learningDesignDAO.insertOrUpdate(learningDesign); - } - public BeanFactory getBeanFactory() { return beanFactory; } @@ -394,7 +387,7 @@ } /** - * @see org.lamsfoundation.lams.authoring.service.IAuthoringService#getToolOutputDefinitions(java.lang.Long, int) + * @see org.lamsfoundation.lams.authoring.service.IAuthoringFullService#getToolOutputDefinitions(java.lang.Long, int) */ @Override public List getToolOutputDefinitions(Long toolContentID, int definitionType) { @@ -411,7 +404,7 @@ } /** - * @see org.lamsfoundation.lams.authoring.service.IAuthoringService#setupEditOnFlyLock(LearningDesign, + * @see org.lamsfoundation.lams.authoring.service.IAuthoringFullService#setupEditOnFlyLock(LearningDesign, * java.lang.Integer) */ @SuppressWarnings("unchecked") @@ -463,7 +456,7 @@ } /** - * @see org.lamsfoundation.lams.authoring.service.IAuthoringService#setupEditOnFlyGate(java.lang.Long, + * @see org.lamsfoundation.lams.authoring.service.IAuthoringFullService#setupEditOnFlyGate(java.lang.Long, * java.lang.Integer) */ @@ -839,7 +832,7 @@ } /** - * @see org.lamsfoundation.lams.authoring.service.IAuthoringService#copyLearningDesign(org.lamsfoundation.lams.learningdesign.LearningDesign, + * @see org.lamsfoundation.lams.authoring.service.IAuthoringFullService#copyLearningDesign(org.lamsfoundation.lams.learningdesign.LearningDesign, * java.lang.Integer, org.lamsfoundation.lams.usermanagement.User, * org.lamsfoundation.lams.usermanagement.WorkspaceFolder, java.lang.Boolean, java.lang.String) */ @@ -893,7 +886,7 @@ * @throws UserException * @throws WorkspaceFolderException * @throws IOException - * @see org.lamsfoundation.lams.authoring.service.IAuthoringService#insertLearningDesign(java.lang.Long, + * @see org.lamsfoundation.lams.authoring.service.IAuthoringFullService#insertLearningDesign(java.lang.Long, * java.lang.Long, java.lang.Integer, java.lang.Boolean, java.lang.String, java.lang.Integer) */ @Override @@ -968,7 +961,7 @@ } /** - * @see org.lamsfoundation.lams.authoring.service.IAuthoringService#copyLearningDesignToolContent(org.lamsfoundation.lams.learningdesign.LearningDesign, + * @see org.lamsfoundation.lams.authoring.service.IAuthoringFullService#copyLearningDesignToolContent(org.lamsfoundation.lams.learningdesign.LearningDesign, * org.lamsfoundation.lams.learningdesign.LearningDesign, java.lang.Integer) */ private LearningDesign copyLearningDesignToolContent(LearningDesign design, LearningDesign originalLearningDesign, @@ -1594,7 +1587,7 @@ } /** - * @see org.lamsfoundation.lams.authoring.service.IAuthoringService#getAvailableLicenses() + * @see org.lamsfoundation.lams.authoring.service.IAuthoringFullService#getAvailableLicenses() */ @Override public Vector getAvailableLicenses() { @@ -1821,4 +1814,9 @@ access.setAccessDate(new Date()); learningDesignDAO.insertOrUpdate(access); } + + @Override + public FolderContentDTO getUserWorkspaceFolder(Integer userID) throws IOException { + return workspaceManagementService.getUserWorkspaceFolder(userID); + } } \ No newline at end of file Index: lams_central/src/java/org/lamsfoundation/lams/authoring/service/IAuthoringFullService.java =================================================================== diff -u --- lams_central/src/java/org/lamsfoundation/lams/authoring/service/IAuthoringFullService.java (revision 0) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/service/IAuthoringFullService.java (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -0,0 +1,209 @@ +/*************************************************************************** + * 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 + * ************************************************************************ + */ + +package org.lamsfoundation.lams.authoring.service; + +import java.io.IOException; +import java.text.ParseException; +import java.util.List; +import java.util.Vector; + +import org.apache.tomcat.util.json.JSONException; +import org.apache.tomcat.util.json.JSONObject; +import org.lamsfoundation.lams.authoring.IAuthoringService; +import org.lamsfoundation.lams.authoring.ObjectExtractorException; +import org.lamsfoundation.lams.learningdesign.Grouping; +import org.lamsfoundation.lams.learningdesign.LearningDesign; +import org.lamsfoundation.lams.learningdesign.LearningDesignAccess; +import org.lamsfoundation.lams.learningdesign.License; +import org.lamsfoundation.lams.learningdesign.dto.AuthoringActivityDTO; +import org.lamsfoundation.lams.learningdesign.dto.ValidationErrorDTO; +import org.lamsfoundation.lams.learningdesign.exception.LearningDesignException; +import org.lamsfoundation.lams.tool.dto.ToolOutputDefinitionDTO; +import org.lamsfoundation.lams.usermanagement.User; +import org.lamsfoundation.lams.usermanagement.WorkspaceFolder; +import org.lamsfoundation.lams.usermanagement.exception.UserException; +import org.lamsfoundation.lams.usermanagement.exception.WorkspaceFolderException; +import org.lamsfoundation.lams.util.MessageService; + +/** + * @author Manpreet Minhas + */ +public interface IAuthoringFullService extends IAuthoringService { + + /** Message key returned by the storeLearningDesignDetails() method */ + public static final String STORE_LD_MESSAGE_KEY = "storeLearningDesignDetails"; + + public static final String INSERT_LD_MESSAGE_KEY = "insertLearningDesign"; + + public static final String START_EDIT_ON_FLY_MESSAGE_KEY = "startEditOnFly"; + + public static final String COPY_TOOL_CONTENT_MESSAGE_KEY = "copyMultipleToolContent"; + + /** + * Returns a populated LearningDesign object corresponding to the given learningDesignID + * + * @param learningDesignID + * The learning_design_id of the design which has to be fetched + * @return LearningDesign The populated LearningDesign object corresponding to the given learningDesignID + */ + LearningDesign getLearningDesign(Long learningDesignID); + + /** + * Create a copy of learning design as per the requested learning design and saves it in the given workspacefolder. + * Designed to be called when user tries to copy a learning design using the Authoring interface. Does not set the + * original learning design field, so it should not be used for creating lesson learning designs. + * + * @param originalLearningDesingID + * the source learning design id. + * @param copyType + * purpose of copying the design. Can have one of the follwing values + * + * @param userID + * The user_id of the user who has sent this request(author/teacher) + * @param workspaceFolderID + * The workspacefolder where this copy of the design would be saved + * @param setOriginalDesign + * If true, then sets the originalLearningDesign field in the new design + * @return new LearningDesign + */ + LearningDesign copyLearningDesign(Long originalLearningDesignID, Integer copyType, Integer userID, + Integer workspaceFolder, boolean setOriginalDesign) + throws UserException, LearningDesignException, WorkspaceFolderException, IOException; + + /** + * Insert a learning design into another learning design. This is a copy and paste type of copy - it just dumps the + * contents (with modified activity ui ids) in the main learning design. It doesn't wrap up the contents in a + * sequence activity. Always sets the type to COPY_TYPE_NONE. + * + * @param originalDesignID + * The design to be "modified". Required. + * @param designToImportID + * The design to be imported into originalLearningDesign. Required. + * @param userId + * Current User. Required. + * @param customCSV + * The custom CSV required to insert tool adapter tools, so their content can be copied in the external + * server + * @param createNewLearningDesign + * If true, then a copy of the originalLearningDesign is made and the copy modified. If it is false, then + * the originalLearningDesign is modified. Required. + * @param newDesignName + * New name for the design if a new design is being create. Optional. + * @param workspaceFolderID + * The folder in which to put the new learning design if createNewLearningDesign = true. May be null if + * createNewLearningDesign = false + * @return New / updated learning design + */ + LearningDesign insertLearningDesign(Long originalDesignID, Long designToImportID, Integer userID, + boolean createNewLearningDesign, String newDesignName, Integer workspaceFolderID, String customCSV) + throws UserException, LearningDesignException, WorkspaceFolderException, IOException; + + LearningDesign saveLearningDesignDetails(JSONObject ldJSON) + throws UserException, JSONException, WorkspaceFolderException, ObjectExtractorException, ParseException; + + /** + * Validate the learning design, updating the valid flag appropriately. + * + * This needs to be run in a separate transaction to storeLearningDesignDetails to ensure the database is fully + * updated before the validation occurs (due to some quirks we are finding using Hibernate) + * + * @param learningDesignId + * @throws Exception + */ + Vector validateLearningDesign(Long learningDesignId); + + /** + * + * @param learningDesignId + * @return + */ + Vector getToolActivities(Long learningDesignId, String languageCode); + + /** + * This method returns a output definitions of the Tool. + */ + List getToolOutputDefinitions(Long toolContentID, int definitionType); + + Long insertToolContentID(Long toolID); + + /** + * Calls an appropriate tool to copy the content indicated by toolContentId. Returns the new tool content id. + * + * The is called when the user copies and pastes a tool activity icon in authoring. It should only be called on a + * ToolActivity - never a Gate or Grouping or Complex activity. + * + * @param toolContentID + * The toolContentID indicating the content to copy + * @param customCSV + * The customCSV if this is a tool adapter tool. + * @return Long the new content id + */ + Long copyToolContent(Long toolContentID, String customCSV) throws IOException; + + /** + * Get the available licenses. This will include our supported Creative Common licenses and an "OTHER" license which + * may be used for user entered license details. The picture url supplied should be a full URL i.e. if it was a + * relative URL in the database, it should have been converted to a complete server URL (starting http://) before + * sending to the client. + * + * @return Vector of LicenseDTO objects. + */ + Vector getAvailableLicenses(); + + /** + * Delete a learning design from the database. Does not remove any content stored in tools - that is done by the + * LamsCoreToolService + */ + void deleteLearningDesign(LearningDesign design); + + /** + * + * + * @param learningDesignID + * The learning_design_id of the design for which editing has finished. + * @param userID + * user_id of the User who has finished editing the design. + * @param cancelled + * flag specifying whether user cancelled or saved the edit + * @throws IOException + * @throws Exception + */ + void finishEditOnFly(Long learningDesignID, Integer userID, boolean cancelled) throws Exception; + + /** Get the message service, which gives access to the I18N text */ + MessageService getMessageService(); + + String getToolAuthorUrl(Long toolID, Long toolContentID, String contentFolderID); + + Long insertSingleActivityLearningDesign(String learningDesignTitle, Long toolID, Long toolContentID, + Long learningLibraryID, String contentFolderID, Integer organisationID); + + List updateLearningDesignAccessByUser(Integer userId); + + void storeLearningDesignAccess(Long learningDesignId, Integer userId); +} \ No newline at end of file Fisheye: Tag 5caa0c70153ab564c5d8e347c4af4baf53b01fd0 refers to a dead (removed) revision in file `lams_central/src/java/org/lamsfoundation/lams/authoring/service/IAuthoringService.java'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_central/src/java/org/lamsfoundation/lams/authoring/template/web/LdTemplateAction.java =================================================================== diff -u -r5949a49ec6308dfce3ac7c88808da019f8260c76 -r5caa0c70153ab564c5d8e347c4af4baf53b01fd0 --- lams_central/src/java/org/lamsfoundation/lams/authoring/template/web/LdTemplateAction.java (.../LdTemplateAction.java) (revision 5949a49ec6308dfce3ac7c88808da019f8260c76) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/template/web/LdTemplateAction.java (.../LdTemplateAction.java) (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -45,7 +45,7 @@ import org.apache.tomcat.util.json.JSONArray; import org.apache.tomcat.util.json.JSONException; import org.apache.tomcat.util.json.JSONObject; -import org.lamsfoundation.lams.authoring.service.IAuthoringService; +import org.lamsfoundation.lams.authoring.service.IAuthoringFullService; import org.lamsfoundation.lams.authoring.template.Option; import org.lamsfoundation.lams.authoring.template.TextUtil; import org.lamsfoundation.lams.learningdesign.Activity; @@ -85,7 +85,7 @@ private static ILamsCoreToolService lamsCoreToolService; private static IWorkspaceManagementService workspaceManagementService; - private static IAuthoringService authoringService; + private static IAuthoringFullService authoringFullService; private static IToolDAO toolDAO; protected static final String CONTENT_TYPE_JSON = "application/json;charset=utf-8"; @@ -343,7 +343,7 @@ try { learningDesign = getAuthoringService().saveLearningDesignDetails(ldJSON); } catch ( Exception e ) { - LdTemplateAction.log.error("Unable to learning design with details " + ldJSON, e); + log.error("Unable to learning design with details " + ldJSON, e); throw new HttpException("Unable to learning design with details " + ldJSON); } @@ -627,7 +627,7 @@ return toolContentID; } catch (Exception e) { - LdTemplateAction.log.error("Unable to create tool content for " + toolSignature + " with details " + log.error("Unable to create tool content for " + toolSignature + " with details " + toolContentJSON + ". \nThe tool probably threw an exception - check the server logs for more details.\n" + "If the exception is \"Servlet.service() for servlet ToolContentRestServlet threw exception java.lang.ClassCastException: com.sun.proxy.$ProxyXXX cannot be cast to org.lamsfoundation.lams.rest.ToolRestManager)\"" @@ -1277,40 +1277,40 @@ /* ************************************** Service related methods ********************************************** */ /* ************************************** I18N related methods ************************************************* */ - protected final IAuthoringService getAuthoringService() { - if (LdTemplateAction.authoringService == null) { + protected final IAuthoringFullService getAuthoringService() { + if (authoringFullService == null) { WebApplicationContext ctx = WebApplicationContextUtils .getRequiredWebApplicationContext(getServlet().getServletContext()); - LdTemplateAction.authoringService = (IAuthoringService) ctx.getBean("authoringService"); + authoringFullService = (IAuthoringFullService) ctx.getBean("authoringFullService"); } - return LdTemplateAction.authoringService; + return authoringFullService; } protected final Tool getTool(String toolSignature) { - if (LdTemplateAction.toolDAO == null) { + if (toolDAO == null) { WebApplicationContext ctx = WebApplicationContextUtils .getRequiredWebApplicationContext(getServlet().getServletContext()); - LdTemplateAction.toolDAO = (IToolDAO) ctx.getBean("toolDAO"); + toolDAO = (IToolDAO) ctx.getBean("toolDAO"); } - return LdTemplateAction.toolDAO.getToolBySignature(toolSignature); + return toolDAO.getToolBySignature(toolSignature); } protected final IWorkspaceManagementService getWorkspaceManagementService() { - if (LdTemplateAction.workspaceManagementService == null) { + if (workspaceManagementService == null) { WebApplicationContext ctx = WebApplicationContextUtils .getRequiredWebApplicationContext(getServlet().getServletContext()); - LdTemplateAction.workspaceManagementService = (IWorkspaceManagementService) ctx + workspaceManagementService = (IWorkspaceManagementService) ctx .getBean("workspaceManagementService"); } - return LdTemplateAction.workspaceManagementService; + return workspaceManagementService; } private ILamsCoreToolService getLamsCoreToolService() { - if (LdTemplateAction.lamsCoreToolService == null) { - LdTemplateAction.lamsCoreToolService = (ILamsCoreToolService) WebApplicationContextUtils + if (lamsCoreToolService == null) { + lamsCoreToolService = (ILamsCoreToolService) WebApplicationContextUtils .getRequiredWebApplicationContext(getServlet().getServletContext()).getBean("lamsCoreToolService"); } - return LdTemplateAction.lamsCoreToolService; + return lamsCoreToolService; } class ToolDetails { Index: lams_central/src/java/org/lamsfoundation/lams/authoring/web/AuthoringAction.java =================================================================== diff -u -r7b0401fe54636737b72030c60fd9292956e79487 -r5caa0c70153ab564c5d8e347c4af4baf53b01fd0 --- lams_central/src/java/org/lamsfoundation/lams/authoring/web/AuthoringAction.java (.../AuthoringAction.java) (revision 7b0401fe54636737b72030c60fd9292956e79487) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/web/AuthoringAction.java (.../AuthoringAction.java) (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -48,7 +48,7 @@ import org.apache.tomcat.util.json.JSONException; import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.authoring.ObjectExtractorException; -import org.lamsfoundation.lams.authoring.service.IAuthoringService; +import org.lamsfoundation.lams.authoring.service.IAuthoringFullService; import org.lamsfoundation.lams.integration.ExtCourseClassMap; import org.lamsfoundation.lams.integration.ExtServer; import org.lamsfoundation.lams.integration.service.IIntegrationService; @@ -94,10 +94,6 @@ /** * @author Manpreet Minhas - * - * - * - * */ public class AuthoringAction extends LamsDispatchAction { @@ -106,7 +102,7 @@ private static IMonitoringService monitoringService; private static IUserManagementService userManagementService; private static ILamsToolService toolService; - private static IAuthoringService authoringService; + private static IAuthoringFullService authoringFullService; private static ILearningDesignService learningDesignService; private static ISecurityService securityService; private static IIntegrationService integrationService; @@ -167,11 +163,11 @@ public ActionForward getToolOutputDefinitions(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, JSONException { - IAuthoringService authoringService = getAuthoringService(); + IAuthoringFullService authoringFullService = getAuthoringService(); Long toolContentID = WebUtil.readLongParam(request, "toolContentID"); Integer definitionType = ToolOutputDefinition.DATA_OUTPUT_DEFINITION_TYPE_CONDITION; - List defnDTOList = authoringService.getToolOutputDefinitions(toolContentID, + List defnDTOList = authoringFullService.getToolOutputDefinitions(toolContentID, definitionType); Gson gson = new GsonBuilder().create(); @@ -236,12 +232,12 @@ public ActionForward finishLearningDesignEdit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - IAuthoringService authoringService = getAuthoringService(); + IAuthoringFullService authoringFullService = getAuthoringService(); Long learningDesignID = WebUtil.readLongParam(request, "learningDesignID", false); boolean cancelled = WebUtil.readBooleanParam(request, "cancelled", false); try { - authoringService.finishEditOnFly(learningDesignID, getUserId(), cancelled); + authoringFullService.finishEditOnFly(learningDesignID, getUserId(), cancelled); } catch (Exception e) { String errorMsg = "Error occured ending EditOnFly" + e.getMessage() + " learning design id " + learningDesignID; @@ -258,11 +254,11 @@ */ public ActionForward copyToolContent(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - IAuthoringService authoringService = getAuthoringService(); + IAuthoringFullService authoringFullService = getAuthoringService(); try { String customCSV = WebUtil.readStrParam(request, AttributeNames.PARAM_CUSTOM_CSV, true); long toolContentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID, false); - Long newToolContentID = authoringService.copyToolContent(toolContentID, customCSV); + Long newToolContentID = authoringFullService.copyToolContent(toolContentID, customCSV); response.setContentType("text/plain;charset=utf-8"); response.getWriter().write(newToolContentID.toString()); } catch (Exception e) { @@ -277,12 +273,12 @@ */ public ActionForward createToolContent(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, JSONException { - IAuthoringService authoringService = getAuthoringService(); + IAuthoringFullService authoringFullService = getAuthoringService(); Long toolID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_ID); Long toolContentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID, true); if (toolContentID == null) { // if the tool content ID was not provided, generate the next unique content ID for the tool - toolContentID = authoringService.insertToolContentID(toolID); + toolContentID = authoringFullService.insertToolContentID(toolID); } if (toolContentID != null) { @@ -291,7 +287,7 @@ contentFolderID = FileUtil.generateUniqueContentFolderID(); } - String authorUrl = authoringService.getToolAuthorUrl(toolID, toolContentID, contentFolderID); + String authorUrl = authoringFullService.getToolAuthorUrl(toolID, toolContentID, contentFolderID); if (authorUrl != null) { JSONObject responseJSON = new JSONObject(); responseJSON.put("authorURL", authorUrl); @@ -311,7 +307,7 @@ @SuppressWarnings("unchecked") public ActionForward createSingleActivityLesson(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException { - IAuthoringService authoringService = getAuthoringService(); + IAuthoringFullService authoringFullService = getAuthoringService(); Long toolID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_ID); Long toolContentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); Long learningLibraryID = WebUtil.readLongParam(request, AttributeNames.PARAM_LEARNING_LIBRARY_ID, true); @@ -346,7 +342,7 @@ title = getLearningDesignService().internationaliseActivityTitle(learningLibraryID); } // create the LD and put it in Run Sequences folder in the given organisation - Long learningDesignID = authoringService.insertSingleActivityLearningDesign(title, toolID, toolContentID, + Long learningDesignID = authoringFullService.insertSingleActivityLearningDesign(title, toolID, toolContentID, learningLibraryID, contentFolderID, organisationID); if (learningDesignID != null) { User user = (User) getUserManagementService().findById(User.class, userID); @@ -522,14 +518,14 @@ return AuthoringAction.userManagementService; } - public IAuthoringService getAuthoringService() { - if (AuthoringAction.authoringService == null) { + public IAuthoringFullService getAuthoringService() { + if (AuthoringAction.authoringFullService == null) { WebApplicationContext wac = WebApplicationContextUtils .getRequiredWebApplicationContext(getServlet().getServletContext()); - AuthoringAction.authoringService = (IAuthoringService) wac + AuthoringAction.authoringFullService = (IAuthoringFullService) wac .getBean(AuthoringConstants.AUTHORING_SERVICE_BEAN_NAME); } - return AuthoringAction.authoringService; + return AuthoringAction.authoringFullService; } public ILamsToolService getToolService() { Index: lams_central/src/java/org/lamsfoundation/lams/authoring/web/AuthoringConstants.java =================================================================== diff -u -r51fb2a37254f24bb2a805d4ffd54482c779f43fa -r5caa0c70153ab564c5d8e347c4af4baf53b01fd0 --- lams_central/src/java/org/lamsfoundation/lams/authoring/web/AuthoringConstants.java (.../AuthoringConstants.java) (revision 51fb2a37254f24bb2a805d4ffd54482c779f43fa) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/web/AuthoringConstants.java (.../AuthoringConstants.java) (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -33,10 +33,4 @@ /** Spring context name for refering to the authoring service */ public static final String AUTHORING_SERVICE_BEAN_NAME = "authoringService"; public static final String TOOL_SERVICE_BEAN_NAME = "lamsToolService"; - - //used by all tool authoring action class to mark the success flag. - public static final String LAMS_AUTHORING_SUCCESS_FLAG = "LAMS_AUTHORING_SUCCESS_FLAG"; - - // used for tool content folder creation. - public static final String LAMS_WWW_FOLDER = "www/"; } Fisheye: Tag 5caa0c70153ab564c5d8e347c4af4baf53b01fd0 refers to a dead (removed) revision in file `lams_central/src/java/org/lamsfoundation/lams/authoring/web/LamsAuthoringFinishAction.java'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_central/src/java/org/lamsfoundation/lams/rest/RestServlet.java =================================================================== diff -u -r11b64f81e406ff277c7c35988304b0064300de57 -r5caa0c70153ab564c5d8e347c4af4baf53b01fd0 --- lams_central/src/java/org/lamsfoundation/lams/rest/RestServlet.java (.../RestServlet.java) (revision 11b64f81e406ff277c7c35988304b0064300de57) +++ lams_central/src/java/org/lamsfoundation/lams/rest/RestServlet.java (.../RestServlet.java) (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -35,7 +35,7 @@ import org.apache.log4j.Logger; import org.apache.tomcat.util.json.JSONException; import org.apache.tomcat.util.json.JSONObject; -import org.lamsfoundation.lams.authoring.service.IAuthoringService; +import org.lamsfoundation.lams.authoring.service.IAuthoringFullService; import org.lamsfoundation.lams.integration.ExtServer; import org.lamsfoundation.lams.integration.ExtUserUseridMap; import org.lamsfoundation.lams.integration.UserInfoFetchException; @@ -67,7 +67,7 @@ private static IToolDAO toolDAO; private static ILamsCoreToolService lamsCoreToolService; private static IIntegrationService integrationService; - private static IAuthoringService authoringService; + private static IAuthoringFullService authoringFullService; private static IUserManagementService userManagementService; /** @@ -165,13 +165,13 @@ protected abstract void doPostInternal(JSONObject requestJSON, UserDTO userDTO, HttpServletResponse response) throws Exception; - protected final IAuthoringService getAuthoringService() { - if (RestServlet.authoringService == null) { + protected final IAuthoringFullService getAuthoringService() { + if (RestServlet.authoringFullService == null) { WebApplicationContext ctx = WebApplicationContextUtils .getRequiredWebApplicationContext(getServletContext()); - RestServlet.authoringService = (IAuthoringService) ctx.getBean("authoringService"); + RestServlet.authoringFullService = (IAuthoringFullService) ctx.getBean("authoringFullService"); } - return RestServlet.authoringService; + return RestServlet.authoringFullService; } protected ILamsCoreToolService getLamsCoreToolService() { Fisheye: Tag 5caa0c70153ab564c5d8e347c4af4baf53b01fd0 refers to a dead (removed) revision in file `lams_central/src/java/org/lamsfoundation/lams/rest/RestTags.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 5caa0c70153ab564c5d8e347c4af4baf53b01fd0 refers to a dead (removed) revision in file `lams_central/src/java/org/lamsfoundation/lams/rest/ToolRestManager.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 5caa0c70153ab564c5d8e347c4af4baf53b01fd0 refers to a dead (removed) revision in file `lams_central/src/java/org/lamsfoundation/lams/util/BufferOverflowException.java'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_central/src/java/org/lamsfoundation/lams/util/CentralConstants.java =================================================================== diff -u -r471b903caa3365758fbdec0a22440b1b0b3f2947 -r5caa0c70153ab564c5d8e347c4af4baf53b01fd0 --- lams_central/src/java/org/lamsfoundation/lams/util/CentralConstants.java (.../CentralConstants.java) (revision 471b903caa3365758fbdec0a22440b1b0b3f2947) +++ lams_central/src/java/org/lamsfoundation/lams/util/CentralConstants.java (.../CentralConstants.java) (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -171,22 +171,9 @@ public static final String PARAM_FILTER_TEXT = "filterText"; - public static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition"; - - public static final String RESPONSE_CONTENT_TYPE_DOWNLOAD = "application/x-download"; - - public static final String HEADER_CONTENT_ATTACHMENT = "attachment;filename="; - public static final String PARAM_LEARNER_PRESENCE_ENABLE = "learnerSeeOnline"; public static final String PARAM_LEARNER_IM_ENABLE = "learnerInstantMessaging"; public static final String PARAM_ENABLE_NOTIFICATIONS = "enableNotifications"; - - public static final String TOOL_SIGNATURE_ASSESSMENT = "laasse10"; - public static final String TOOL_SIGNATURE_FORUM = "lafrum11"; - public static final String TOOL_SIGNATURE_LEADERSELECTION = "lalead11"; - public static final String TOOL_SIGNATURE_MCQ = "lamc11"; - public static final String TOOL_SIGNATURE_SCRATCHIE = "lascrt11"; - public static final String TOOL_SIGNATURE_PEER_REVIEW = "laprev11"; } \ No newline at end of file Fisheye: Tag 5caa0c70153ab564c5d8e347c4af4baf53b01fd0 refers to a dead (removed) revision in file `lams_central/src/java/org/lamsfoundation/lams/util/CircularByteBuffer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 5caa0c70153ab564c5d8e347c4af4baf53b01fd0 refers to a dead (removed) revision in file `lams_central/src/java/org/lamsfoundation/lams/util/SMTPAuthenticator.java'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_central/src/java/org/lamsfoundation/lams/web/LAMSConnectorServlet.java =================================================================== diff -u -rcac4b20509606b942a7cd762ebadd2674c3983ab -r5caa0c70153ab564c5d8e347c4af4baf53b01fd0 --- lams_central/src/java/org/lamsfoundation/lams/web/LAMSConnectorServlet.java (.../LAMSConnectorServlet.java) (revision cac4b20509606b942a7cd762ebadd2674c3983ab) +++ lams_central/src/java/org/lamsfoundation/lams/web/LAMSConnectorServlet.java (.../LAMSConnectorServlet.java) (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -37,6 +37,7 @@ import org.apache.struts.action.ActionMessage; import org.lamsfoundation.lams.authoring.web.AuthoringConstants; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.util.CommonConstants; import org.lamsfoundation.lams.util.Configuration; import org.lamsfoundation.lams.util.ConfigurationKeys; import org.lamsfoundation.lams.util.FileUtil; @@ -137,7 +138,7 @@ String currentDirPath = realBaseDir + designFolder + typeStr + "/" + currentFolderStr; String validCurrentDirPath = currentDirPath.replace('/', File.separatorChar); - String currentWebPath = lamsContextPath + AuthoringConstants.LAMS_WWW_FOLDER + FileUtil.LAMS_WWW_SECURE_DIR + String currentWebPath = lamsContextPath + CommonConstants.LAMS_WWW_FOLDER + FileUtil.LAMS_WWW_SECURE_DIR + designFolder + typeStr + "/" + currentFolderStr; File currentDir = new File(validCurrentDirPath); @@ -287,7 +288,7 @@ } else { // send back URL to new Paint file - String currentWebPath = lamsContextPath + AuthoringConstants.LAMS_WWW_FOLDER + FileUtil.LAMS_WWW_SECURE_DIR + String currentWebPath = lamsContextPath + CommonConstants.LAMS_WWW_FOLDER + FileUtil.LAMS_WWW_SECURE_DIR + designFolder + fileType + "/" + currentFolderStr; out.println(currentWebPath + newName); } Fisheye: Tag 5caa0c70153ab564c5d8e347c4af4baf53b01fd0 refers to a dead (removed) revision in file `lams_central/src/java/org/lamsfoundation/lams/web/TextSearchActionForm.java'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_central/src/java/org/lamsfoundation/lams/webservice/xml/LessonManagerServlet.java =================================================================== diff -u -r3b255feabeeae3729398d969d6ee4d76947777d3 -r5caa0c70153ab564c5d8e347c4af4baf53b01fd0 --- lams_central/src/java/org/lamsfoundation/lams/webservice/xml/LessonManagerServlet.java (.../LessonManagerServlet.java) (revision 3b255feabeeae3729398d969d6ee4d76947777d3) +++ lams_central/src/java/org/lamsfoundation/lams/webservice/xml/LessonManagerServlet.java (.../LessonManagerServlet.java) (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -63,8 +63,8 @@ import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; import org.lamsfoundation.lams.util.CentralConstants; +import org.lamsfoundation.lams.util.CommonConstants; import org.lamsfoundation.lams.util.DateUtil; -import org.lamsfoundation.lams.util.LanguageUtil; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; @@ -1299,9 +1299,9 @@ boolean hasNumericToolOutput = false; for (ToolActivity activity : activities) { String toolSignature = activity.getTool().getToolSignature(); - hasNumericToolOutput |= CentralConstants.TOOL_SIGNATURE_ASSESSMENT.equals(toolSignature) - || CentralConstants.TOOL_SIGNATURE_MCQ.equals(toolSignature) - || CentralConstants.TOOL_SIGNATURE_SCRATCHIE.equals(toolSignature); + hasNumericToolOutput |= CommonConstants.TOOL_SIGNATURE_ASSESSMENT.equals(toolSignature) + || CommonConstants.TOOL_SIGNATURE_MCQ.equals(toolSignature) + || CommonConstants.TOOL_SIGNATURE_SCRATCHIE.equals(toolSignature); } // Create the root node of the xml document Index: lams_central/src/java/org/lamsfoundation/lams/workspace/service/WorkspaceManagementService.java =================================================================== diff -u -r7b0401fe54636737b72030c60fd9292956e79487 -r5caa0c70153ab564c5d8e347c4af4baf53b01fd0 --- lams_central/src/java/org/lamsfoundation/lams/workspace/service/WorkspaceManagementService.java (.../WorkspaceManagementService.java) (revision 7b0401fe54636737b72030c60fd9292956e79487) +++ lams_central/src/java/org/lamsfoundation/lams/workspace/service/WorkspaceManagementService.java (.../WorkspaceManagementService.java) (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -36,7 +36,7 @@ import org.apache.tomcat.util.json.JSONArray; import org.apache.tomcat.util.json.JSONException; import org.apache.tomcat.util.json.JSONObject; -import org.lamsfoundation.lams.authoring.service.IAuthoringService; +import org.lamsfoundation.lams.authoring.service.IAuthoringFullService; import org.lamsfoundation.lams.contentrepository.exception.RepositoryCheckedException; import org.lamsfoundation.lams.contentrepository.service.IRepositoryService; import org.lamsfoundation.lams.dao.IBaseDAO; @@ -73,7 +73,7 @@ protected IBaseDAO baseDAO; protected ILearningDesignDAO learningDesignDAO; - protected IAuthoringService authoringService; + protected IAuthoringFullService authoringFullService; protected IRepositoryService repositoryService; protected IUserManagementService userMgmtService; protected MessageService messageService; @@ -113,11 +113,11 @@ } /** - * @param authoringService - * The authoringService to set. + * @param authoringFullService + * The authoringFullService to set. */ - public void setAuthoringService(IAuthoringService authoringService) { - this.authoringService = authoringService; + public void setAuthoringService(IAuthoringFullService authoringFullService) { + this.authoringFullService = authoringFullService; } /** @@ -571,7 +571,7 @@ public void copyResource(Long resourceID, String resourceType, Integer copyType, Integer targetFolderID, Integer userID) throws LearningDesignException, UserException, WorkspaceFolderException, IOException { if (FolderContentDTO.DESIGN.equals(resourceType)) { - authoringService.copyLearningDesign(resourceID, + authoringFullService.copyLearningDesign(resourceID, copyType != null ? copyType : new Integer(LearningDesign.COPY_TYPE_NONE), userID, targetFolderID, false); } else if (FolderContentDTO.FOLDER.equals(resourceType)) { @@ -691,7 +691,7 @@ Iterator iterator = designs.iterator(); while (iterator.hasNext()) { LearningDesign design = (LearningDesign) iterator.next(); - authoringService.copyLearningDesign(design, new Integer(LearningDesign.COPY_TYPE_NONE), user, + authoringFullService.copyLearningDesign(design, new Integer(LearningDesign.COPY_TYPE_NONE), user, targetWorkspaceFolder, false, null, null); } } Index: lams_central/web/WEB-INF/struts-config.xml =================================================================== diff -u -r471b903caa3365758fbdec0a22440b1b0b3f2947 -r5caa0c70153ab564c5d8e347c4af4baf53b01fd0 --- lams_central/web/WEB-INF/struts-config.xml (.../struts-config.xml) (revision 471b903caa3365758fbdec0a22440b1b0b3f2947) +++ lams_central/web/WEB-INF/struts-config.xml (.../struts-config.xml) (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -15,7 +15,7 @@ + *
  • LearningDesign.COPY_TYPE_NONE (for authoring enviornment)
  • + *
  • LearningDesign.COPY_TYPE_LESSON (for monitoring enviornment while creating a Lesson)
  • + *
  • LearningDesign.COPY_TYPE_PREVIEW (for previewing purposes)
  • + * + * @param user + * The user who has sent this request(author/teacher) + * @param setOriginalDesign + * If true, then sets the originalLearningDesign field in the new design + * @param custom + * comma separated values used for tool adapters + * @return LearningDesign The new copy of learning design. + */ + LearningDesign copyLearningDesign(LearningDesign originalLearningDesign, Integer copyType, User user, + WorkspaceFolder workspaceFolder, boolean setOriginalDesign, String newDesignName, String customCSV); + + /** + * Get a unique name for a learning design, based on the names of the learning designs in the folder. If the + * learning design has duplicated name in same folder, then the new name will have a timestamp. The new name format + * will be oldname_ddMMYYYY_idx. The idx will be auto incremental index number, start from 1. Warning - this may be + * quite intensive as it gets all the learning designs in a folder. + * + * @param originalLearningDesign + * @param workspaceFolder + * @param copyType + * @return + */ + String getUniqueNameForLearningDesign(String originalTitle, Integer workspaceFolderId); + + Grouping getGroupingById(Long groupingID); + + /** + * This method returns the root workspace folder for a particular user. + * + * @param userID + * The user_id of the user for whom the folders have to fetched + * @return FolderContentDTO for the user's root workspace folder + * @throws IOException + */ + FolderContentDTO getUserWorkspaceFolder(Integer userID) throws IOException; +} Index: lams_common/src/java/org/lamsfoundation/lams/rest/RestTags.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/rest/RestTags.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/rest/RestTags.java (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -0,0 +1,67 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + + +package org.lamsfoundation.lams.rest; + +/** Commonly used JSON tags for the calling the REST servlets */ +public class RestTags { + + public static String AUTH = "auth"; + public static String LEARNING_DESIGN = "ld"; + + /* Learning Design Related */ + public static String WORKSPACE_ID = "workspaceFolderID"; + public static String COPY_TYPE_ID = "copyTypeID"; + public static String TITLE = "title"; + public static String DESCRIPTION = "description"; + public static String MAX_ID = "maxID"; + public static String READ_ONLY = "readOnly"; + public static String EDIT_OVERRIDE_LOCK = "editOverrideLock"; + public static String CONTENT_FOLDER_ID = "contentFolderID"; + public static String SAVE_MODE = "saveMode"; + public static String VALID_DESIGN = "validDesign"; + public static String ACTIVITIES = "activities"; + public static String TRANSITIONS = "transitions"; + public static String GROUPINGS = "groupings"; + + /* Tool related - also TITLE but that is defined above. */ + public static String INSTRUCTIONS = "instructions"; + public static String LOCK_WHEN_FINISHED = "lockWhenFinished"; + public static String REFLECT_ON_ACTIVITY = "reflectOnActivity"; + public static String REFLECT_INSTRUCTIONS = "reflectInstructions"; + public static String ALLOW_RICH_TEXT_EDITOR = "allowRichEditor"; + public static String USE_SELECT_LEADER_TOOL_OUTPUT = "useSelectLeaderToolOuput"; + public static String MINIMUM_RATES = "minimumRates"; + public static String MAXIMUM_RATES = "maximumRates"; + public static String ENABLE_CONFIDENCE_LEVELS = "enableConfidenceLevels"; + public static String CONFIDENCE_LEVELS_ACTIVITY_UIID = "confidenceLevelsActivityUiid"; + + public static String QUESTIONS = "questions"; + public static String QUESTION_TEXT = "questionText"; + public static String QUESTION_TITLE = "questionTitle"; + public static String ANSWERS = "answers"; + public static String ANSWER_TEXT = "answerText"; + public static String DISPLAY_ORDER = "displayOrder"; + public static String CORRECT = "correct"; + +} Index: lams_common/src/java/org/lamsfoundation/lams/rest/ToolRestManager.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/rest/ToolRestManager.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/rest/ToolRestManager.java (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -0,0 +1,31 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + + +package org.lamsfoundation.lams.rest; + +import org.apache.tomcat.util.json.JSONException; +import org.apache.tomcat.util.json.JSONObject; + +public interface ToolRestManager { + void createRestToolContent(Integer userID, Long toolContentID, JSONObject toolContentJSON) throws JSONException; +} \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/util/SMTPAuthenticator.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/util/SMTPAuthenticator.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/util/SMTPAuthenticator.java (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -0,0 +1,39 @@ +/**************************************************************** + * Copyright (C) 2008 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 + * **************************************************************** + */ + + +package org.lamsfoundation.lams.util; + +import javax.mail.PasswordAuthentication; + +public class SMTPAuthenticator extends javax.mail.Authenticator { + private PasswordAuthentication authentication; + + public SMTPAuthenticator(String username, String password) { + authentication = new PasswordAuthentication(username, password); + } + + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return authentication; + } +} \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/util/imgscalr/CircularByteBuffer.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/util/imgscalr/CircularByteBuffer.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/util/imgscalr/CircularByteBuffer.java (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -0,0 +1,905 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + + +package org.lamsfoundation.lams.util; + +/* + * Circular Byte Buffer + * Copyright (C) 2002 Stephen Ostermiller + * http://ostermiller.org/contact.pl?regarding=Java+Utilities + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * See COPYING.TXT for details. + */ + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Implements the Circular Buffer producer/consumer model for bytes. + * More information about this class is available from ostermiller.org. + *

    + * Using this class is a simpler alternative to using a PipedInputStream + * and a PipedOutputStream. PipedInputStreams and PipedOutputStreams don't support the + * mark operation, don't allow you to control buffer sizes that they use, + * and have a more complicated API that requires instantiating two + * classes and connecting them. + *

    + * This class is thread safe. + * + * @see CircularCharBuffer + * @see CircularObjectBuffer + * + * @author Stephen Ostermiller http://ostermiller.org/contact.pl?regarding=Java+Utilities + * @since ostermillerutils 1.00.00 + */ +public class CircularByteBuffer { + + /** + * The default size for a circular byte buffer. + * + * @since ostermillerutils 1.00.00 + */ + private final static int DEFAULT_SIZE = 1024; + + /** + * A buffer that will grow as things are added. + * + * @since ostermillerutils 1.00.00 + */ + public final static int INFINITE_SIZE = -1; + + /** + * The circular buffer. + *

    + * The actual capacity of the buffer is one less than the actual length + * of the buffer so that an empty and a full buffer can be + * distinguished. An empty buffer will have the markPostion and the + * writePosition equal to each other. A full buffer will have + * the writePosition one less than the markPostion. + *

    + * There are three important indexes into the buffer: + * The readPosition, the writePosition, and the markPosition. + * If the InputStream has never been marked, the readPosition and + * the markPosition should always be the same. The bytes + * available to be read go from the readPosition to the writePosition, + * wrapping around the end of the buffer. The space available for writing + * goes from the write position to one less than the markPosition, + * wrapping around the end of the buffer. The bytes that have + * been saved to support a reset() of the InputStream go from markPosition + * to readPosition, wrapping around the end of the buffer. + * + * @since ostermillerutils 1.00.00 + */ + protected byte[] buffer; + /** + * Index of the first byte available to be read. + * + * @since ostermillerutils 1.00.00 + */ + protected volatile int readPosition = 0; + /** + * Index of the first byte available to be written. + * + * @since ostermillerutils 1.00.00 + */ + protected volatile int writePosition = 0; + /** + * Index of the first saved byte. (To support stream marking.) + * + * @since ostermillerutils 1.00.00 + */ + protected volatile int markPosition = 0; + /** + * Number of bytes that have to be saved + * to support mark() and reset() on the InputStream. + * + * @since ostermillerutils 1.00.00 + */ + protected volatile int markSize = 0; + /** + * If this buffer is infinite (should resize itself when full) + * + * @since ostermillerutils 1.00.00 + */ + protected volatile boolean infinite = false; + /** + * True if a write to a full buffer should block until the buffer + * has room, false if the write method should throw an IOException + * + * @since ostermillerutils 1.00.00 + */ + protected boolean blockingWrite = true; + /** + * The InputStream that can empty this buffer. + * + * @since ostermillerutils 1.00.00 + */ + protected InputStream in = new CircularByteBufferInputStream(); + /** + * true if the close() method has been called on the InputStream + * + * @since ostermillerutils 1.00.00 + */ + protected boolean inputStreamClosed = false; + /** + * The OutputStream that can fill this buffer. + * + * @since ostermillerutils 1.00.00 + */ + protected OutputStream out = new CircularByteBufferOutputStream(); + /** + * true if the close() method has been called on the OutputStream + * + * @since ostermillerutils 1.00.00 + */ + protected boolean outputStreamClosed = false; + + /** + * Make this buffer ready for reuse. The contents of the buffer + * will be cleared and the streams associated with this buffer + * will be reopened if they had been closed. + * + * @since ostermillerutils 1.00.00 + */ + public void clear() { + synchronized (this) { + readPosition = 0; + writePosition = 0; + markPosition = 0; + outputStreamClosed = false; + inputStreamClosed = false; + } + } + + /** + * Retrieve a OutputStream that can be used to fill + * this buffer. + *

    + * Write methods may throw a BufferOverflowException if + * the buffer is not large enough. A large enough buffer + * size must be chosen so that this does not happen or + * the caller must be prepared to catch the exception and + * try again once part of the buffer has been consumed. + * + * + * @return the producer for this buffer. + * + * @since ostermillerutils 1.00.00 + */ + public OutputStream getOutputStream() { + return out; + } + + /** + * Retrieve a InputStream that can be used to empty + * this buffer. + *

    + * This InputStream supports marks at the expense + * of the buffer size. + * + * @return the consumer for this buffer. + * + * @since ostermillerutils 1.00.00 + */ + public InputStream getInputStream() { + return in; + } + + /** + * Get number of bytes that are available to be read. + *

    + * Note that the number of bytes available plus + * the number of bytes free may not add up to the + * capacity of this buffer, as the buffer may reserve some + * space for other purposes. + * + * @return the size in bytes of this buffer + * + * @since ostermillerutils 1.00.00 + */ + public int getAvailable() { + synchronized (this) { + return available(); + } + } + + /** + * Get the number of bytes this buffer has free for + * writing. + *

    + * Note that the number of bytes available plus + * the number of bytes free may not add up to the + * capacity of this buffer, as the buffer may reserve some + * space for other purposes. + * + * @return the available space in bytes of this buffer + * + * @since ostermillerutils 1.00.00 + */ + public int getSpaceLeft() { + synchronized (this) { + return spaceLeft(); + } + } + + /** + * Get the capacity of this buffer. + *

    + * Note that the number of bytes available plus + * the number of bytes free may not add up to the + * capacity of this buffer, as the buffer may reserve some + * space for other purposes. + * + * @return the size in bytes of this buffer + * + * @since ostermillerutils 1.00.00 + */ + public int getSize() { + synchronized (this) { + return buffer.length; + } + } + + /** + * double the size of the buffer + * + * @since ostermillerutils 1.00.00 + */ + private void resize() { + byte[] newBuffer = new byte[buffer.length * 2]; + int marked = marked(); + int available = available(); + if (markPosition <= writePosition) { + // any space between the mark and + // the first write needs to be saved. + // In this case it is all in one piece. + int length = writePosition - markPosition; + System.arraycopy(buffer, markPosition, newBuffer, 0, length); + } else { + int length1 = buffer.length - markPosition; + System.arraycopy(buffer, markPosition, newBuffer, 0, length1); + int length2 = writePosition; + System.arraycopy(buffer, 0, newBuffer, length1, length2); + } + buffer = newBuffer; + markPosition = 0; + readPosition = marked; + writePosition = marked + available; + } + + /** + * Space available in the buffer which can be written. + * + * @since ostermillerutils 1.00.00 + */ + private int spaceLeft() { + if (writePosition < markPosition) { + // any space between the first write and + // the mark except one byte is available. + // In this case it is all in one piece. + return (markPosition - writePosition - 1); + } + // space at the beginning and end. + return ((buffer.length - 1) - (writePosition - markPosition)); + } + + /** + * Bytes available for reading. + * + * @since ostermillerutils 1.00.00 + */ + private int available() { + if (readPosition <= writePosition) { + // any space between the first read and + // the first write is available. In this case i + // is all in one piece. + return (writePosition - readPosition); + } + // space at the beginning and end. + return (buffer.length - (readPosition - writePosition)); + } + + /** + * Bytes saved for supporting marks. + * + * @since ostermillerutils 1.00.00 + */ + private int marked() { + if (markPosition <= readPosition) { + // any space between the markPosition and + // the first write is marked. In this case i + // is all in one piece. + return (readPosition - markPosition); + } + // space at the beginning and end. + return (buffer.length - (markPosition - readPosition)); + } + + /** + * If we have passed the markSize reset the + * mark so that the space can be used. + * + * @since ostermillerutils 1.00.00 + */ + private void ensureMark() { + if (marked() >= markSize) { + markPosition = readPosition; + markSize = 0; + } + } + + /** + * Create a new buffer with a default capacity. + * Writing to a full buffer will block until space + * is available rather than throw an exception. + * + * @since ostermillerutils 1.00.00 + */ + public CircularByteBuffer() { + this(DEFAULT_SIZE, true); + } + + /** + * Create a new buffer with given capacity. + * Writing to a full buffer will block until space + * is available rather than throw an exception. + *

    + * Note that the buffer may reserve some bytes for + * special purposes and capacity number of bytes may + * not be able to be written to the buffer. + *

    + * Note that if the buffer is of INFINITE_SIZE it will + * neither block or throw exceptions, but rather grow + * without bound. + * + * @param size + * desired capacity of the buffer in bytes or CircularByteBuffer.INFINITE_SIZE. + * + * @since ostermillerutils 1.00.00 + */ + public CircularByteBuffer(int size) { + this(size, true); + } + + /** + * Create a new buffer with a default capacity and + * given blocking behavior. + * + * @param blockingWrite + * true writing to a full buffer should block + * until space is available, false if an exception should + * be thrown instead. + * + * @since ostermillerutils 1.00.00 + */ + public CircularByteBuffer(boolean blockingWrite) { + this(DEFAULT_SIZE, blockingWrite); + } + + /** + * Create a new buffer with the given capacity and + * blocking behavior. + *

    + * Note that the buffer may reserve some bytes for + * special purposes and capacity number of bytes may + * not be able to be written to the buffer. + *

    + * Note that if the buffer is of INFINITE_SIZE it will + * neither block or throw exceptions, but rather grow + * without bound. + * + * @param size + * desired capacity of the buffer in bytes or CircularByteBuffer.INFINITE_SIZE. + * @param blockingWrite + * true writing to a full buffer should block + * until space is available, false if an exception should + * be thrown instead. + * + * @since ostermillerutils 1.00.00 + */ + public CircularByteBuffer(int size, boolean blockingWrite) { + if (size == INFINITE_SIZE) { + buffer = new byte[DEFAULT_SIZE]; + infinite = true; + } else { + buffer = new byte[size]; + infinite = false; + } + this.blockingWrite = blockingWrite; + } + + /** + * Class for reading from a circular byte buffer. + * + * @since ostermillerutils 1.00.00 + */ + protected class CircularByteBufferInputStream extends InputStream { + + /** + * Returns the number of bytes that can be read (or skipped over) from this + * input stream without blocking by the next caller of a method for this input + * stream. The next caller might be the same thread or or another thread. + * + * @return the number of bytes that can be read from this input stream without blocking. + * @throws IOException + * if the stream is closed. + * + * @since ostermillerutils 1.00.00 + */ + @Override + public int available() throws IOException { + synchronized (CircularByteBuffer.this) { + if (inputStreamClosed) { + throw new IOException("InputStream has been closed, it is not ready."); + } + return (CircularByteBuffer.this.available()); + } + } + + /** + * Close the stream. Once a stream has been closed, further read(), available(), + * mark(), or reset() invocations will throw an IOException. Closing a + * previously-closed stream, however, has no effect. + * + * @throws IOException + * never. + * + * @since ostermillerutils 1.00.00 + */ + @Override + public void close() throws IOException { + synchronized (CircularByteBuffer.this) { + inputStreamClosed = true; + } + } + + /** + * Mark the present position in the stream. Subsequent calls to reset() will + * attempt to reposition the stream to this point. + *

    + * The readAheadLimit must be less than the size of circular buffer, otherwise + * this method has no effect. + * + * @param readAheadLimit + * Limit on the number of bytes that may be read while + * still preserving the mark. After reading this many bytes, attempting to + * reset the stream will fail. + * + * @since ostermillerutils 1.00.00 + */ + @Override + public void mark(int readAheadLimit) { + synchronized (CircularByteBuffer.this) { + //if (inputStreamClosed) throw new IOException("InputStream has been closed; cannot mark a closed InputStream."); + if (buffer.length - 1 > readAheadLimit) { + markSize = readAheadLimit; + markPosition = readPosition; + } + } + } + + /** + * Tell whether this stream supports the mark() operation. + * + * @return true, mark is supported. + * + * @since ostermillerutils 1.00.00 + */ + @Override + public boolean markSupported() { + return true; + } + + /** + * Read a single byte. + * This method will block until a byte is available, an I/O error occurs, + * or the end of the stream is reached. + * + * @return The byte read, as an integer in the range 0 to 255 (0x00-0xff), + * or -1 if the end of the stream has been reached + * @throws IOException + * if the stream is closed. + * + * @since ostermillerutils 1.00.00 + */ + @Override + public int read() throws IOException { + while (true) { + synchronized (CircularByteBuffer.this) { + if (inputStreamClosed) { + throw new IOException("InputStream has been closed; cannot read from a closed InputStream."); + } + int available = CircularByteBuffer.this.available(); + if (available > 0) { + int result = buffer[readPosition] & 0xff; + readPosition++; + if (readPosition == buffer.length) { + readPosition = 0; + } + ensureMark(); + return result; + } else if (outputStreamClosed) { + return -1; + } + } + try { + Thread.sleep(100); + } catch (Exception x) { + throw new IOException("Blocking read operation interrupted."); + } + } + } + + /** + * Read bytes into an array. + * This method will block until some input is available, + * an I/O error occurs, or the end of the stream is reached. + * + * @param cbuf + * Destination buffer. + * @return The number of bytes read, or -1 if the end of + * the stream has been reached + * @throws IOException + * if the stream is closed. + * + * @since ostermillerutils 1.00.00 + */ + @Override + public int read(byte[] cbuf) throws IOException { + return read(cbuf, 0, cbuf.length); + } + + /** + * Read bytes into a portion of an array. + * This method will block until some input is available, + * an I/O error occurs, or the end of the stream is reached. + * + * @param cbuf + * Destination buffer. + * @param off + * Offset at which to start storing bytes. + * @param len + * Maximum number of bytes to read. + * @return The number of bytes read, or -1 if the end of + * the stream has been reached + * @throws IOException + * if the stream is closed. + * + * @since ostermillerutils 1.00.00 + */ + @Override + public int read(byte[] cbuf, int off, int len) throws IOException { + while (true) { + synchronized (CircularByteBuffer.this) { + if (inputStreamClosed) { + throw new IOException("InputStream has been closed; cannot read from a closed InputStream."); + } + int available = CircularByteBuffer.this.available(); + if (available > 0) { + int length = Math.min(len, available); + int firstLen = Math.min(length, buffer.length - readPosition); + int secondLen = length - firstLen; + System.arraycopy(buffer, readPosition, cbuf, off, firstLen); + if (secondLen > 0) { + System.arraycopy(buffer, 0, cbuf, off + firstLen, secondLen); + readPosition = secondLen; + } else { + readPosition += length; + } + if (readPosition == buffer.length) { + readPosition = 0; + } + ensureMark(); + return length; + } else if (outputStreamClosed) { + return -1; + } + } + try { + Thread.sleep(100); + } catch (Exception x) { + throw new IOException("Blocking read operation interrupted."); + } + } + } + + /** + * Reset the stream. + * If the stream has been marked, then attempt to reposition i + * at the mark. If the stream has not been marked, or more bytes + * than the readAheadLimit have been read, this method has no effect. + * + * @throws IOException + * if the stream is closed. + * + * @since ostermillerutils 1.00.00 + */ + @Override + public void reset() throws IOException { + synchronized (CircularByteBuffer.this) { + if (inputStreamClosed) { + throw new IOException("InputStream has been closed; cannot reset a closed InputStream."); + } + readPosition = markPosition; + } + } + + /** + * Skip bytes. + * This method will block until some bytes are available, + * an I/O error occurs, or the end of the stream is reached. + * + * @param n + * The number of bytes to skip + * @return The number of bytes actually skipped + * @throws IllegalArgumentException + * if n is negative. + * @throws IOException + * if the stream is closed. + * + * @since ostermillerutils 1.00.00 + */ + @Override + public long skip(long n) throws IOException, IllegalArgumentException { + while (true) { + synchronized (CircularByteBuffer.this) { + if (inputStreamClosed) { + throw new IOException( + "InputStream has been closed; cannot skip bytes on a closed InputStream."); + } + int available = CircularByteBuffer.this.available(); + if (available > 0) { + int length = Math.min((int) n, available); + int firstLen = Math.min(length, buffer.length - readPosition); + int secondLen = length - firstLen; + if (secondLen > 0) { + readPosition = secondLen; + } else { + readPosition += length; + } + if (readPosition == buffer.length) { + readPosition = 0; + } + ensureMark(); + return length; + } else if (outputStreamClosed) { + return 0; + } + } + try { + Thread.sleep(100); + } catch (Exception x) { + throw new IOException("Blocking read operation interrupted."); + } + } + } + } + + /** + * Class for writing to a circular byte buffer. + * If the buffer is full, the writes will either block + * until there is some space available or throw an IOException + * based on the CircularByteBuffer's preference. + * + * @since ostermillerutils 1.00.00 + */ + protected class CircularByteBufferOutputStream extends OutputStream { + + /** + * Close the stream, flushing it first. + * This will cause the InputStream associated with this circular buffer + * to read its last bytes once it empties the buffer. + * Once a stream has been closed, further write() or flush() invocations + * will cause an IOException to be thrown. Closing a previously-closed stream, + * however, has no effect. + * + * @throws IOException + * never. + * + * @since ostermillerutils 1.00.00 + */ + @Override + public void close() throws IOException { + synchronized (CircularByteBuffer.this) { + if (!outputStreamClosed) { + flush(); + } + outputStreamClosed = true; + } + } + + /** + * Flush the stream. + * + * @throws IOException + * if the stream is closed. + * + * @since ostermillerutils 1.00.00 + */ + @Override + public void flush() throws IOException { + if (outputStreamClosed) { + throw new IOException("OutputStream has been closed; cannot flush a closed OutputStream."); + } + if (inputStreamClosed) { + throw new IOException("Buffer closed by inputStream; cannot flush."); + // this method needs to do nothing + } + } + + /** + * Write an array of bytes. + * If the buffer allows blocking writes, this method will block until + * all the data has been written rather than throw an IOException. + * + * @param cbuf + * Array of bytes to be written + * @throws BufferOverflowException + * if buffer does not allow blocking writes + * and the buffer is full. If the exception is thrown, no data + * will have been written since the buffer was set to be non-blocking. + * @throws IOException + * if the stream is closed, or the write is interrupted. + * + * @since ostermillerutils 1.00.00 + */ + @Override + public void write(byte[] cbuf) throws IOException { + write(cbuf, 0, cbuf.length); + } + + /** + * Write a portion of an array of bytes. + * If the buffer allows blocking writes, this method will block until + * all the data has been written rather than throw an IOException. + * + * @param cbuf + * Array of bytes + * @param off + * Offset from which to start writing bytes + * @param len + * - Number of bytes to write + * @throws BufferOverflowException + * if buffer does not allow blocking writes + * and the buffer is full. If the exception is thrown, no data + * will have been written since the buffer was set to be non-blocking. + * @throws IOException + * if the stream is closed, or the write is interrupted. + * + * @since ostermillerutils 1.00.00 + */ + @Override + public void write(byte[] cbuf, int off, int len) throws IOException { + while (len > 0) { + synchronized (CircularByteBuffer.this) { + if (outputStreamClosed) { + throw new IOException("OutputStream has been closed; cannot write to a closed OutputStream."); + } + if (inputStreamClosed) { + throw new IOException("Buffer closed by InputStream; cannot write to a closed buffer."); + } + int spaceLeft = spaceLeft(); + while (infinite && spaceLeft < len) { + resize(); + spaceLeft = spaceLeft(); + } + if (!blockingWrite && spaceLeft < len) { + throw new BufferOverflowException("CircularByteBuffer is full; cannot write " + len + " bytes"); + } + int realLen = Math.min(len, spaceLeft); + int firstLen = Math.min(realLen, buffer.length - writePosition); + int secondLen = Math.min(realLen - firstLen, buffer.length - markPosition - 1); + int written = firstLen + secondLen; + if (firstLen > 0) { + System.arraycopy(cbuf, off, buffer, writePosition, firstLen); + } + if (secondLen > 0) { + System.arraycopy(cbuf, off + firstLen, buffer, 0, secondLen); + writePosition = secondLen; + } else { + writePosition += written; + } + if (writePosition == buffer.length) { + writePosition = 0; + } + off += written; + len -= written; + } + if (len > 0) { + try { + Thread.sleep(100); + } catch (Exception x) { + throw new IOException("Waiting for available space in buffer interrupted."); + } + } + } + } + + /** + * Write a single byte. + * The byte to be written is contained in the 8 low-order bits of the + * given integer value; the 24 high-order bits are ignored. + * If the buffer allows blocking writes, this method will block until + * all the data has been written rather than throw an IOException. + * + * @param c + * number of bytes to be written + * @throws BufferOverflowException + * if buffer does not allow blocking writes + * and the buffer is full. + * @throws IOException + * if the stream is closed, or the write is interrupted. + * + * @since ostermillerutils 1.00.00 + */ + @Override + public void write(int c) throws IOException { + boolean written = false; + while (!written) { + synchronized (CircularByteBuffer.this) { + if (outputStreamClosed) { + throw new IOException("OutputStream has been closed; cannot write to a closed OutputStream."); + } + if (inputStreamClosed) { + throw new IOException("Buffer closed by InputStream; cannot write to a closed buffer."); + } + int spaceLeft = spaceLeft(); + while (infinite && spaceLeft < 1) { + resize(); + spaceLeft = spaceLeft(); + } + if (!blockingWrite && spaceLeft < 1) { + throw new BufferOverflowException("CircularByteBuffer is full; cannot write 1 byte"); + } + if (spaceLeft > 0) { + buffer[writePosition] = (byte) (c & 0xff); + writePosition++; + if (writePosition == buffer.length) { + writePosition = 0; + } + written = true; + } + } + if (!written) { + try { + Thread.sleep(100); + } catch (Exception x) { + throw new IOException("Waiting for available space in buffer interrupted."); + } + } + } + } + } +} Index: lams_common/src/java/org/lamsfoundation/lams/web/action/LamsAuthoringFinishAction.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/web/action/LamsAuthoringFinishAction.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/web/action/LamsAuthoringFinishAction.java (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -0,0 +1,195 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + + +package org.lamsfoundation.lams.authoring.web; + +import java.io.IOException; +import java.net.URLEncoder; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +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.lamsfoundation.lams.logevent.service.ILogEventService; +import org.lamsfoundation.lams.tool.IToolVO; +import org.lamsfoundation.lams.tool.ToolAccessMode; +import org.lamsfoundation.lams.tool.ToolContentManager; +import org.lamsfoundation.lams.tool.service.ILamsToolService; +import org.lamsfoundation.lams.util.Configuration; +import org.lamsfoundation.lams.util.ConfigurationKeys; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +/** + * This action class does some process when author try to save/cancel/close authoring tool pages. If author try to save + * tool page, this action will redirct tool page to confirm page and execute clearSession() method. If author try to + * cancel/close window, this action will execute clearSession(). + * + * @author Steve.Ni + */ +public abstract class LamsAuthoringFinishAction extends Action { + private static Logger log = Logger.getLogger(LamsAuthoringFinishAction.class); + + private static final String ACTION_NAME = "action"; + private static final String ACTION_MODE = "mode"; + private static final String CUSTOMISE_SESSION_ID = "customiseSessionID"; + private static final String TOOL_SIGNATURE = "signature"; + + private static final String CONFIRM_ACTION = "confirm"; + private static final String CANCEL_ACTION = "cancel"; + private static final String DEFINE_LATER_ACTION = "defineLater"; + + private static final String RE_EDIT_URL = "reEditUrl"; + + private static ILogEventService logEventService; + + /** + * Action method, will handle save/cancel action. + */ + @Override + public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + String action = request.getParameter(ACTION_NAME); + ToolAccessMode mode = WebUtil.readToolAccessModeParam(request, ACTION_MODE, false); + String cSessionID = request.getParameter(CUSTOMISE_SESSION_ID); + String notifyCloseURL = (String) request.getSession().getAttribute(AttributeNames.PARAM_NOTIFY_CLOSE_URL); + Long toolContentId = new Long(WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID)); + + // clear session according to the ToolAccessMode. + clearSession(cSessionID, request.getSession(), mode); + + //CONFIRM_ACTION got fired only for general authoring and not for define later one + if (StringUtils.equals(action, CONFIRM_ACTION)) { + String nextUrl = getLamsUrl() + "authoringConfirm.jsp"; + String signature = request.getParameter(TOOL_SIGNATURE); + + String contentFolderID = "TODO_remove-change_optional_to_false"; + contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID, true); + + // check whether it use on define it later page + IToolVO tool = getToolService().getToolBySignature(signature); + + //add reeditUrl parameter + String reeditUrl = WebUtil.appendParameterToURL(getLamsUrl() + tool.getAuthorUrl(), + AttributeNames.PARAM_TOOL_CONTENT_ID, toolContentId.toString()); + reeditUrl = WebUtil.appendParameterToURL(reeditUrl, AttributeNames.PARAM_CONTENT_FOLDER_ID, + contentFolderID); + if ( notifyCloseURL != null && notifyCloseURL.length() > 0 ) + reeditUrl = WebUtil.appendParameterToURL(reeditUrl, AttributeNames.PARAM_NOTIFY_CLOSE_URL, notifyCloseURL); + nextUrl = WebUtil.appendParameterToURL(nextUrl, RE_EDIT_URL, URLEncoder.encode(reeditUrl, "UTF-8")); + + if (!StringUtils.isBlank(notifyCloseURL)) { + nextUrl = WebUtil.appendParameterToURL(nextUrl, AttributeNames.PARAM_NOTIFY_CLOSE_URL, notifyCloseURL); + } + response.sendRedirect(nextUrl); + } + + //audit log content has been finished being edited + if (StringUtils.equals(action, DEFINE_LATER_ACTION)) { + getLogEventService().logFinishEditingActivityInMonitor(toolContentId); + } + + //reset defineLater task + if (StringUtils.equals(action, CANCEL_ACTION) && mode.isTeacher()) { + String signature = request.getParameter(TOOL_SIGNATURE); + + ToolContentManager contentManager = (ToolContentManager) findToolService(signature); + contentManager.resetDefineLater(toolContentId); + + getLogEventService().logCancelEditingActivityInMonitor(toolContentId); + } + + return null; + } + + /** + * All subclass will implements this method and execute clear HttpSession action to remove obsolete + * session values. + * + * @param customiseSessionID + * customised session ID. + * @param session + * @param mode + * ToolAccessMode to decide which role's session will be clear. + */ + abstract public void clearSession(String customiseSessionID, HttpSession session, ToolAccessMode mode); + + // --------------------------------------------------------------------- + // Helper Methods + // --------------------------------------------------------------------- + + private String getLamsUrl() { + String serverURL = Configuration.get(ConfigurationKeys.SERVER_URL); + + if (StringUtils.isBlank(serverURL)) { + log.warn("ServerURLTag unable to write out server URL as it is missing from the configuration file."); + } + + return serverURL; + } + + public ILamsToolService getToolService() { + WebApplicationContext webContext = WebApplicationContextUtils + .getRequiredWebApplicationContext(this.getServlet().getServletContext()); + return (ILamsToolService) webContext.getBean(AuthoringConstants.TOOL_SERVICE_BEAN_NAME); + } + + /** + * Get LogEventService bean + */ + private ILogEventService getLogEventService() { + if (logEventService == null) { + WebApplicationContext ctx = WebApplicationContextUtils + .getRequiredWebApplicationContext(getServlet().getServletContext()); + logEventService = (ILogEventService) ctx.getBean("logEventService"); + } + return logEventService; + } + + /** + * Find a tool's service registered inside lams. + * + * @param signature + * the tool signature. + * @return the service object from tool. + * @throws NoSuchBeanDefinitionException + * if the tool is not the classpath or the supplied service name is wrong. + */ + public Object findToolService(String signature) throws NoSuchBeanDefinitionException { + IToolVO tool = getToolService().getToolBySignature(signature); + WebApplicationContext webContext = WebApplicationContextUtils + .getRequiredWebApplicationContext(this.getServlet().getServletContext()); + return webContext.getBean(tool.getServiceName()); + } +} Index: lams_common/src/java/org/lamsfoundation/lams/web/form/TextSearchActionForm.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/web/form/TextSearchActionForm.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/web/form/TextSearchActionForm.java (revision 5caa0c70153ab564c5d8e347c4af4baf53b01fd0) @@ -0,0 +1,100 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +package org.lamsfoundation.lams.web; + +import org.apache.struts.action.ActionForm; +import org.lamsfoundation.lams.learningdesign.TextSearchCondition; + +/** + * The form that contains all the fields provided in lams:TextSearch tag. + * + * @author Marcin Cieslak + * + * + */ +public class TextSearchActionForm extends ActionForm { + + public static final String formName = "TextSearchActionForm"; + private String allWords; + private String phrase; + private String anyWords; + private String excludedWords; + private String sessionMapID; + + public TextSearchActionForm() { + } + + /** + * Fills the form with data provided by condition. + * + * @param condition + * condition to read the data from + */ + public void populateForm(TextSearchCondition condition) { + allWords = condition.getAllWords(); + phrase = condition.getPhrase(); + anyWords = condition.getAnyWords(); + excludedWords = condition.getExcludedWords(); + } + + public String getAllWords() { + return allWords; + } + + public void setAllWords(String allWords) { + this.allWords = allWords; + } + + public String getPhrase() { + return phrase; + } + + public void setPhrase(String phrase) { + this.phrase = phrase; + } + + public String getAnyWords() { + return anyWords; + } + + public void setAnyWords(String anyWords) { + this.anyWords = anyWords; + } + + public String getExcludedWords() { + return excludedWords; + } + + public void setExcludedWords(String excludedWords) { + this.excludedWords = excludedWords; + } + + public String getSessionMapID() { + return sessionMapID; + } + + public void setSessionMapID(String sessionMapID) { + this.sessionMapID = sessionMapID; + } +} \ No newline at end of file