)";
-
- private static final String URL_SHORTENING_CYPHER = "jbdnuteywk";
-
- /**
- * @exception IllegalArgumentException
- * - if not set
- */
- private static void checkObject(String paramName, Object paramValue) throws IllegalArgumentException {
- boolean isNull = paramValue == null;
- if (!isNull && String.class.isInstance(paramValue)) {
- String str = (String) paramValue;
- isNull = str.trim().length() == 0;
- }
- if (isNull) {
- throw new IllegalArgumentException(paramName + " is required '" + paramValue + "'");
- }
- }
-
- /**
- * @return integer value of paramValue
- * @exception IllegalArgumentException
- * - if (a) not set and is not optional or (b) not integer
- */
- public static Integer checkInteger(String paramName, String paramValue, boolean isOptional)
- throws IllegalArgumentException {
- try {
- if (!isOptional) {
- WebUtil.checkObject(paramName, paramValue);
- }
- String value = paramValue != null ? StringUtils.trimToNull(paramValue) : null;
- return value != null ? Integer.valueOf(value) : null;
-
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException(paramName + " should be an integer '" + paramValue + "'");
- }
- }
-
- /**
- * @return long value of paramValue
- * @exception IllegalArgumentException
- * - if (a) not set and is not optional or (b) not long
- */
- public static Long checkLong(String paramName, String paramValue, boolean isOptional)
- throws IllegalArgumentException {
- try {
- if (!isOptional) {
- WebUtil.checkObject(paramName, paramValue);
- }
- String value = paramValue != null ? StringUtils.trimToNull(paramValue) : null;
- return value != null ? Long.valueOf(value) : null;
-
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException(paramName + " should be a long '" + paramValue + "'");
- }
- }
-
- /**
- * Get a long version of paramValue, throwing an IllegalArgumentException if isOptional = false and the is value is
- * null
- *
- * @return long value of paramValue
- * @exception IllegalArgumentException
- * - if not set or not long
- */
- public static long checkLong(String paramName, Long paramValue, boolean isOptional)
- throws IllegalArgumentException {
- if (!isOptional) {
- WebUtil.checkObject(paramName, paramValue);
- }
- return paramValue.longValue();
- }
-
- /**
- * @return boolean value of paramValue
- * @exception IllegalArgumentException
- * - if not set or not boolean
- */
- public static boolean checkBoolean(String paramName, String paramValue) throws IllegalArgumentException {
- WebUtil.checkObject(paramName, paramValue);
- return Boolean.valueOf(paramValue.trim()).booleanValue();
- }
-
- /**
- * Read an int parameter, throwing exception if null or not a integer
- *
- * @param req
- * -
- * @param paramName
- * -
- * @return parameter value
- */
- public static int readIntParam(HttpServletRequest req, String paramName) {
- return WebUtil.checkInteger(paramName, req.getParameter(paramName), false).intValue();
- }
-
- /**
- * Read an int parameter, throwing exception if ( not optional and null ) or not a integer
- *
- * @param req
- * -
- * @param paramName
- * -
- * @param isOptional
- * @return parameter value
- */
- public static Integer readIntParam(HttpServletRequest req, String paramName, boolean isOptional) {
- return WebUtil.checkInteger(paramName, req.getParameter(paramName), isOptional);
- }
-
- /**
- * Read an long parameter, throwing exception if null or not a long
- *
- * @param req
- * -
- * @param paramName
- * -
- * @return parameter value
- */
- public static long readLongParam(HttpServletRequest req, String paramName) {
- return WebUtil.checkLong(paramName, req.getParameter(paramName), false).longValue();
- }
-
- /**
- * Read an long parameter, throwing exception if ( not optional and null ) or not a long
- *
- * @param req
- * -
- * @param paramName
- * -
- * @param isOptional
- * @return parameter value
- */
- public static Long readLongParam(HttpServletRequest req, String paramName, boolean isOptional) {
- return WebUtil.checkLong(paramName, req.getParameter(paramName), isOptional);
- }
-
- /**
- * @param req
- * -
- * @param paramName
- * -
- * @return parameter value
- */
- public static String readStrParam(HttpServletRequest req, String paramName) {
- return WebUtil.readStrParam(req, paramName, false);
- }
-
- /**
- * @param req
- * -
- * @param paramName
- * -
- * @param isOptional
- * @return parameter value
- */
- public static String readStrParam(HttpServletRequest req, String paramName, boolean isOptional) {
- if (!isOptional) {
- WebUtil.checkObject(paramName, req.getParameter(paramName));
- }
- return req.getParameter(paramName);
- }
-
- /**
- * @param req
- * -
- * @param paramName
- * -
- * @return parameter value
- * @exception IllegalArgumentException
- * - if valid boolean parameter value is not found
- */
- public static boolean readBooleanParam(HttpServletRequest req, String paramName) throws IllegalArgumentException {
- return WebUtil.checkBoolean(paramName, req.getParameter(paramName));
- }
-
- /**
- * @param req
- * -
- * @param paramName
- * -
- * @param defaultValue
- * - if valid boolean parameter value is not found, return this value
- * @return parameter value
- */
- public static boolean readBooleanParam(HttpServletRequest req, String paramName, boolean defaultValue) {
- try {
- return WebUtil.checkBoolean(paramName, req.getParameter(paramName));
- } catch (IllegalArgumentException e) {
- return defaultValue;
- }
- }
-
- public static boolean readBooleanAttr(HttpServletRequest req, String attrName) {
- return WebUtil.checkBoolean(attrName, (String) req.getSession().getAttribute(attrName));
- }
-
- /**
- * Retrieve the tool access mode from http request. This is a utility used by the tools that share an implementation
- * for the learner screen. They use mode=learner, mode=author and mode=teacher for learning, preview and monitoring
- * respectively. Only used if the tool programmer wants to have one call that supports all three ways of looking at
- * a learner screen.
- *
- * @param request
- * @param param_mode
- * @return the ToolAccessMode object
- */
- public static ToolAccessMode readToolAccessModeParam(HttpServletRequest request, String param_mode,
- boolean optional) {
- String mode = WebUtil.readStrParam(request, param_mode, optional);
- if (mode == null) {
- return null;
- } else if (mode.equals(ToolAccessMode.AUTHOR.toString())) {
- return ToolAccessMode.AUTHOR;
- } else if (mode.equals(ToolAccessMode.LEARNER.toString())) {
- return ToolAccessMode.LEARNER;
- } else if (mode.equals(ToolAccessMode.TEACHER.toString())) {
- return ToolAccessMode.TEACHER;
- } else {
- throw new IllegalArgumentException("[" + mode + "] is not a legal mode" + "in LAMS");
- }
- }
-
- /**
- * Retrieve the tool access mode from a string value, presumably from a Form. This is a utility used by the tools
- * that share an implementation for the learner screen. They use mode=learner, mode=author and mode=teacher for
- * learning, preview and monitoring respectively. Only used if the tool programmer wants to have one call that
- * supports all three ways of looking at a learner screen.
- *
- * @param request
- * @return the ToolAccessMode object
- */
- public static ToolAccessMode getToolAccessMode(String modeValue) {
- if (modeValue != null) {
- if (modeValue.equals(ToolAccessMode.AUTHOR.toString())) {
- return ToolAccessMode.AUTHOR;
- } else if (modeValue.equals(ToolAccessMode.LEARNER.toString())) {
- return ToolAccessMode.LEARNER;
- } else if (modeValue.equals(ToolAccessMode.TEACHER.toString())) {
- return ToolAccessMode.TEACHER;
- }
- }
- throw new IllegalArgumentException("[" + modeValue + "] is not a legal mode" + "in LAMS");
- }
-
- /**
- * Get ToolAccessMode from HttpRequest parameters. Default value is AUTHOR mode.
- *
- * @param request
- * @return
- */
- public static ToolAccessMode readToolAccessModeAuthorDefaulted(HttpServletRequest request) {
- String modeStr = request.getParameter(AttributeNames.ATTR_MODE);
-
- ToolAccessMode mode;
- if (StringUtils.equalsIgnoreCase(modeStr, ToolAccessMode.TEACHER.toString())) {
- mode = ToolAccessMode.TEACHER;
- } else {
- mode = ToolAccessMode.AUTHOR;
- }
- return mode;
- }
-
- /**
- * Append a parameter to a requested url.
- *
- * @param parameterName
- * the name of the parameter
- * @param parameterValue
- * the value of the parameter
- * @param learnerUrl
- * the target url
- * @return the url with parameter appended.
- */
- public static String appendParameterToURL(String url, String parameterName, String parameterValue) {
- return WebUtil.appendParameterDeliminator(url) + parameterName + "=" + parameterValue;
- }
-
- /**
- *
- * This helper append the parameter deliminator for a url.
- *
- * It is using a null safe String util method to checkup the url String and append proper deliminator if necessary.
- *
- * @param url
- * the url needs to append deliminator.
- * @return target url with the deliminator;
- */
- public static String appendParameterDeliminator(String url) {
- if (url == null) {
- return null;
- } else if (StringUtils.containsNone(url, "?")) {
- return url + "?";
- } else {
- return url + "&";
- }
- }
-
- /**
- * Converts a url (such as one from a tool) to a complete url. If the url starts with "http" then it is assumed to
- * be a complete url and is returned as is. Otherwise it assumes starts with the path of the webapp so it is
- * appended to the server url from the LAMS Configuration.
- *
- * @param url
- * e.g. tool/lanb11/starter/learner.do
- * @return complete url
- */
- public static String convertToFullURL(String url) {
- if (url == null) {
- return null;
- } else if (url.startsWith("http")) {
- return url;
- } else {
- String serverURL = Configuration.get(ConfigurationKeys.SERVER_URL);
- if (url.charAt(0) == '/') {
- return serverURL + url;
- } else {
- return serverURL + '/' + url;
- }
- }
- }
-
- /**
- * Convert any newslines in a string to
- * . If input = null, returns null.
- */
- public static String convertNewlines(String input) {
- if (input != null) {
- return input.replaceAll("[\n\r\f]", "
");
- } else {
- return null;
- }
- }
-
- /**
- * Strips HTML tags and leave "pure" text. Useful for CKeditor created text.
- *
- * @param text
- * string to process
- * @return string after stripping
- */
- public static String removeHTMLtags(String text) {
- return text == null ? null
- : text.replaceAll(WebUtil.SPACE_TAG_REGEX, " ").replaceAll(WebUtil.HTML_TAG_REGEX, "");
- }
-
- /**
- * Makes a request to the specified url with the specified parameters and returns the response inputstream
- *
- * @param urlStr
- * @param params
- * @return
- * @throws ToolException
- * @throws IOException
- */
- public static InputStream getResponseInputStreamFromExternalServer(String urlStr, HashMap
params)
- throws IOException {
- if (!urlStr.contains("?")) {
- urlStr += "?";
- }
-
- for (Entry entry : params.entrySet()) {
- urlStr += "&" + entry.getKey() + "=" + entry.getValue();
- }
-
- WebUtil.log.info("Making request to external servlet: " + urlStr);
-
- URL url = new URL(urlStr);
- URLConnection conn = url.openConnection();
- if (!(conn instanceof HttpURLConnection)) {
- WebUtil.log.error("Fail to connect to external server though url: " + urlStr);
- throw new RuntimeException("Fail to connect to external server though url: " + urlStr);
- }
-
- HttpURLConnection httpConn = (HttpURLConnection) conn;
- if (httpConn.getResponseCode() != HttpURLConnection.HTTP_OK) {
- WebUtil.log.error("Response code from external server: " + httpConn.getResponseCode() + " Url: " + urlStr);
- }
-
- InputStream is = url.openConnection().getInputStream();
- if (is == null) {
- WebUtil.log.error("Fail to fetch data from external server, return InputStream null: " + urlStr);
- throw new RuntimeException("Fail to fetch data from external server, return inputStream null: " + urlStr);
- }
-
- return is;
- }
-
- public static String extractParameterValue(String url, String param) {
- if (!StringUtils.isBlank(url) && !StringUtils.isBlank(param)) {
- int quotationMarkIndex = url.indexOf("?");
- String queryPart = quotationMarkIndex > -1 ? url.substring(quotationMarkIndex + 1) : url;
- String[] paramEntries = queryPart.split("&");
- for (String paramEntry : paramEntries) {
- String[] paramEntrySplitted = paramEntry.split("=");
- if ((paramEntrySplitted.length > 1) && param.equalsIgnoreCase(paramEntrySplitted[0])) {
- return paramEntrySplitted[1];
- }
- }
- }
- return null;
- }
-
- /**
- * Produces JSON object with basic user details.
- */
- public static ObjectNode userToJSON(User user) {
- ObjectNode userJSON = JsonNodeFactory.instance.objectNode();
- userJSON.put("id", user.getUserId());
- userJSON.put("firstName", user.getFirstName());
- userJSON.put("lastName", user.getLastName());
- userJSON.put("login", user.getLogin());
- userJSON.put("portraitId", user.getPortraitUuid());
- return userJSON;
- }
-
- public static String getBaseServerURL() {
- String serverURL = Configuration.get(ConfigurationKeys.SERVER_URL);
- // "https://" is 8 characters, so next "/" should be context
- return serverURL.substring(0, serverURL.indexOf('/', 9));
- }
-
- /**
- * Converse lessonId into alphabetic sequence for using it in URL shortening
- *
- * @param lessonId
- * @return
- */
- public static String encodeLessonId(Long lessonId) {
- String encodedLessonId = lessonId.toString();
- encodedLessonId = encodedLessonId.replace('0', URL_SHORTENING_CYPHER.charAt(0));
- encodedLessonId = encodedLessonId.replace('1', URL_SHORTENING_CYPHER.charAt(1));
- encodedLessonId = encodedLessonId.replace('2', URL_SHORTENING_CYPHER.charAt(2));
- encodedLessonId = encodedLessonId.replace('3', URL_SHORTENING_CYPHER.charAt(3));
- encodedLessonId = encodedLessonId.replace('4', URL_SHORTENING_CYPHER.charAt(4));
- encodedLessonId = encodedLessonId.replace('5', URL_SHORTENING_CYPHER.charAt(5));
- encodedLessonId = encodedLessonId.replace('6', URL_SHORTENING_CYPHER.charAt(6));
- encodedLessonId = encodedLessonId.replace('7', URL_SHORTENING_CYPHER.charAt(7));
- encodedLessonId = encodedLessonId.replace('8', URL_SHORTENING_CYPHER.charAt(8));
- encodedLessonId = encodedLessonId.replace('9', URL_SHORTENING_CYPHER.charAt(9));
-
- return encodedLessonId;
- }
-
- /**
- * Decodes alphabetic sequence (that is lessonId encoded for URL shortening purposes)
- *
- * @param encodedlessonId
- * @return
- */
- public static String decodeLessonId(String encodedLessonId) throws IllegalArgumentException {
-
- // it should contain only the characters from URL_SHORTENING_CYPHER
- if (!encodedLessonId.matches("[" + URL_SHORTENING_CYPHER + "]*")) {
- throw new IllegalArgumentException("LessonId: " + encodedLessonId + " has wrong format.");
- }
-
- String decodedLessonId = encodedLessonId;
- decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(0), '0');
- decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(1), '1');
- decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(2), '2');
- decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(3), '3');
- decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(4), '4');
- decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(5), '5');
- decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(6), '6');
- decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(7), '7');
- decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(8), '8');
- decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(9), '9');
-
- return decodedLessonId;
- }
-
- public static Document getDocument() throws ParserConfigurationException {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- DocumentBuilder builder = factory.newDocumentBuilder();
- Document document = builder.newDocument();
- return document;
- }
-
- public static String getStringFromDocument(Document document) throws TransformerException {
- DOMSource domSource = new DOMSource(document);
- StringWriter writer = new StringWriter();
- StreamResult result = new StreamResult(writer);
- TransformerFactory tf = TransformerFactory.newInstance();
- Transformer transformer = tf.newTransformer();
- transformer.transform(domSource, result);
- return writer.toString();
- }
+package org.lamsfoundation.lams.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashMap;
+import java.util.Map.Entry;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.lamsfoundation.lams.tool.ToolAccessMode;
+import org.lamsfoundation.lams.tool.exception.ToolException;
+import org.lamsfoundation.lams.usermanagement.User;
+import org.lamsfoundation.lams.web.util.AttributeNames;
+import org.w3c.dom.Document;
+
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * helper methods useful for servlets
+ */
+public class WebUtil {
+
+ // ---------------------------------------------------------------------
+ // Class level constants - Session attributs
+ // ---------------------------------------------------------------------
+
+ private static Logger log = Logger.getLogger(WebUtil.class);
+ /**
+ * A regular expression pattern that matches HTML tags.
+ */
+ private static final String HTML_TAG_REGEX = "\\<.*?>";
+ /**
+ * A regular expression pattern that matches end-of-line and space tags. If needed, BR tags can be extented to
+ * (?:
|
|
|
)
. Right now CKeditor creates only the first option.
+ */
+ private static final String SPACE_TAG_REGEX = "(?:
)|(?: )|(?:)";
+
+ private static final String URL_SHORTENING_CYPHER = "jbdnuteywk";
+
+ /**
+ * @exception IllegalArgumentException
+ * - if not set
+ */
+ private static void checkObject(String paramName, Object paramValue) throws IllegalArgumentException {
+ boolean isNull = paramValue == null;
+ if (!isNull && String.class.isInstance(paramValue)) {
+ String str = (String) paramValue;
+ isNull = str.trim().length() == 0;
+ }
+ if (isNull) {
+ throw new IllegalArgumentException(paramName + " is required '" + paramValue + "'");
+ }
+ }
+
+ /**
+ * @return integer value of paramValue
+ * @exception IllegalArgumentException
+ * - if (a) not set and is not optional or (b) not integer
+ */
+ public static Integer checkInteger(String paramName, String paramValue, boolean isOptional)
+ throws IllegalArgumentException {
+ try {
+ if (!isOptional) {
+ WebUtil.checkObject(paramName, paramValue);
+ }
+ String value = paramValue != null ? StringUtils.trimToNull(paramValue) : null;
+ return value != null ? Integer.valueOf(value) : null;
+
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(paramName + " should be an integer '" + paramValue + "'");
+ }
+ }
+
+ /**
+ * @return long value of paramValue
+ * @exception IllegalArgumentException
+ * - if (a) not set and is not optional or (b) not long
+ */
+ public static Long checkLong(String paramName, String paramValue, boolean isOptional)
+ throws IllegalArgumentException {
+ try {
+ if (!isOptional) {
+ WebUtil.checkObject(paramName, paramValue);
+ }
+ String value = paramValue != null ? StringUtils.trimToNull(paramValue) : null;
+ return value != null ? Long.valueOf(value) : null;
+
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(paramName + " should be a long '" + paramValue + "'");
+ }
+ }
+
+ /**
+ * Get a long version of paramValue, throwing an IllegalArgumentException if isOptional = false and the is value is
+ * null
+ *
+ * @return long value of paramValue
+ * @exception IllegalArgumentException
+ * - if not set or not long
+ */
+ public static long checkLong(String paramName, Long paramValue, boolean isOptional)
+ throws IllegalArgumentException {
+ if (!isOptional) {
+ WebUtil.checkObject(paramName, paramValue);
+ }
+ return paramValue.longValue();
+ }
+
+ /**
+ * @return boolean value of paramValue
+ * @exception IllegalArgumentException
+ * - if not set or not boolean
+ */
+ public static boolean checkBoolean(String paramName, String paramValue) throws IllegalArgumentException {
+ WebUtil.checkObject(paramName, paramValue);
+ return Boolean.valueOf(paramValue.trim()).booleanValue();
+ }
+
+ /**
+ * Read an int parameter, throwing exception if null or not a integer
+ *
+ * @param req
+ * -
+ * @param paramName
+ * -
+ * @return parameter value
+ */
+ public static int readIntParam(HttpServletRequest req, String paramName) {
+ return WebUtil.checkInteger(paramName, req.getParameter(paramName), false).intValue();
+ }
+
+ /**
+ * Read an int parameter, throwing exception if ( not optional and null ) or not a integer
+ *
+ * @param req
+ * -
+ * @param paramName
+ * -
+ * @param isOptional
+ * @return parameter value
+ */
+ public static Integer readIntParam(HttpServletRequest req, String paramName, boolean isOptional) {
+ return WebUtil.checkInteger(paramName, req.getParameter(paramName), isOptional);
+ }
+
+ /**
+ * Read an long parameter, throwing exception if null or not a long
+ *
+ * @param req
+ * -
+ * @param paramName
+ * -
+ * @return parameter value
+ */
+ public static long readLongParam(HttpServletRequest req, String paramName) {
+ return WebUtil.checkLong(paramName, req.getParameter(paramName), false).longValue();
+ }
+
+ /**
+ * Read an long parameter, throwing exception if ( not optional and null ) or not a long
+ *
+ * @param req
+ * -
+ * @param paramName
+ * -
+ * @param isOptional
+ * @return parameter value
+ */
+ public static Long readLongParam(HttpServletRequest req, String paramName, boolean isOptional) {
+ return WebUtil.checkLong(paramName, req.getParameter(paramName), isOptional);
+ }
+
+ /**
+ * @param req
+ * -
+ * @param paramName
+ * -
+ * @return parameter value
+ */
+ public static String readStrParam(HttpServletRequest req, String paramName) {
+ return WebUtil.readStrParam(req, paramName, false);
+ }
+
+ /**
+ * @param req
+ * -
+ * @param paramName
+ * -
+ * @param isOptional
+ * @return parameter value
+ */
+ public static String readStrParam(HttpServletRequest req, String paramName, boolean isOptional) {
+ if (!isOptional) {
+ WebUtil.checkObject(paramName, req.getParameter(paramName));
+ }
+ return req.getParameter(paramName);
+ }
+
+ /**
+ * @param req
+ * -
+ * @param paramName
+ * -
+ * @return parameter value
+ * @exception IllegalArgumentException
+ * - if valid boolean parameter value is not found
+ */
+ public static boolean readBooleanParam(HttpServletRequest req, String paramName) throws IllegalArgumentException {
+ return WebUtil.checkBoolean(paramName, req.getParameter(paramName));
+ }
+
+ /**
+ * @param req
+ * -
+ * @param paramName
+ * -
+ * @param defaultValue
+ * - if valid boolean parameter value is not found, return this value
+ * @return parameter value
+ */
+ public static boolean readBooleanParam(HttpServletRequest req, String paramName, boolean defaultValue) {
+ try {
+ return WebUtil.checkBoolean(paramName, req.getParameter(paramName));
+ } catch (IllegalArgumentException e) {
+ return defaultValue;
+ }
+ }
+
+ public static boolean readBooleanAttr(HttpServletRequest req, String attrName) {
+ return WebUtil.checkBoolean(attrName, (String) req.getSession().getAttribute(attrName));
+ }
+
+ /**
+ * Retrieve the tool access mode from http request. This is a utility used by the tools that share an implementation
+ * for the learner screen. They use mode=learner, mode=author and mode=teacher for learning, preview and monitoring
+ * respectively. Only used if the tool programmer wants to have one call that supports all three ways of looking at
+ * a learner screen.
+ *
+ * @param request
+ * @param param_mode
+ * @return the ToolAccessMode object
+ */
+ public static ToolAccessMode readToolAccessModeParam(HttpServletRequest request, String param_mode,
+ boolean optional) {
+ String mode = WebUtil.readStrParam(request, param_mode, optional);
+ if (mode == null) {
+ return null;
+ } else if (mode.equals(ToolAccessMode.AUTHOR.toString())) {
+ return ToolAccessMode.AUTHOR;
+ } else if (mode.equals(ToolAccessMode.LEARNER.toString())) {
+ return ToolAccessMode.LEARNER;
+ } else if (mode.equals(ToolAccessMode.TEACHER.toString())) {
+ return ToolAccessMode.TEACHER;
+ } else {
+ throw new IllegalArgumentException("[" + mode + "] is not a legal mode" + "in LAMS");
+ }
+ }
+
+ /**
+ * Retrieve the tool access mode from a string value, presumably from a Form. This is a utility used by the tools
+ * that share an implementation for the learner screen. They use mode=learner, mode=author and mode=teacher for
+ * learning, preview and monitoring respectively. Only used if the tool programmer wants to have one call that
+ * supports all three ways of looking at a learner screen.
+ *
+ * @param request
+ * @return the ToolAccessMode object
+ */
+ public static ToolAccessMode getToolAccessMode(String modeValue) {
+ if (modeValue != null) {
+ if (modeValue.equals(ToolAccessMode.AUTHOR.toString())) {
+ return ToolAccessMode.AUTHOR;
+ } else if (modeValue.equals(ToolAccessMode.LEARNER.toString())) {
+ return ToolAccessMode.LEARNER;
+ } else if (modeValue.equals(ToolAccessMode.TEACHER.toString())) {
+ return ToolAccessMode.TEACHER;
+ }
+ }
+ throw new IllegalArgumentException("[" + modeValue + "] is not a legal mode" + "in LAMS");
+ }
+
+ /**
+ * Get ToolAccessMode from HttpRequest parameters. Default value is AUTHOR mode.
+ *
+ * @param request
+ * @return
+ */
+ public static ToolAccessMode readToolAccessModeAuthorDefaulted(HttpServletRequest request) {
+ String modeStr = request.getParameter(AttributeNames.ATTR_MODE);
+
+ ToolAccessMode mode;
+ if (StringUtils.equalsIgnoreCase(modeStr, ToolAccessMode.TEACHER.toString())) {
+ mode = ToolAccessMode.TEACHER;
+ } else {
+ mode = ToolAccessMode.AUTHOR;
+ }
+ return mode;
+ }
+
+ /**
+ * Append a parameter to a requested url.
+ *
+ * @param parameterName
+ * the name of the parameter
+ * @param parameterValue
+ * the value of the parameter
+ * @param learnerUrl
+ * the target url
+ * @return the url with parameter appended.
+ */
+ public static String appendParameterToURL(String url, String parameterName, String parameterValue) {
+ return WebUtil.appendParameterDeliminator(url) + parameterName + "=" + parameterValue;
+ }
+
+ /**
+ *
+ * This helper append the parameter deliminator for a url.
+ *
+ * It is using a null safe String util method to checkup the url String and append proper deliminator if necessary.
+ *
+ * @param url
+ * the url needs to append deliminator.
+ * @return target url with the deliminator;
+ */
+ public static String appendParameterDeliminator(String url) {
+ if (url == null) {
+ return null;
+ } else if (StringUtils.containsNone(url, "?")) {
+ return url + "?";
+ } else {
+ return url + "&";
+ }
+ }
+
+ /**
+ * Converts a url (such as one from a tool) to a complete url. If the url starts with "http" then it is assumed to
+ * be a complete url and is returned as is. Otherwise it assumes starts with the path of the webapp so it is
+ * appended to the server url from the LAMS Configuration.
+ *
+ * @param url
+ * e.g. tool/lanb11/starter/learner.do
+ * @return complete url
+ */
+ public static String convertToFullURL(String url) {
+ if (url == null) {
+ return null;
+ } else if (url.startsWith("http")) {
+ return url;
+ } else {
+ String serverURL = Configuration.get(ConfigurationKeys.SERVER_URL);
+ if (url.charAt(0) == '/') {
+ return serverURL + url;
+ } else {
+ return serverURL + '/' + url;
+ }
+ }
+ }
+
+ /**
+ * Convert any newslines in a string to
+ * . If input = null, returns null.
+ */
+ public static String convertNewlines(String input) {
+ if (input != null) {
+ return input.replaceAll("[\n\r\f]", "
");
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Strips HTML tags and leave "pure" text. Useful for CKeditor created text.
+ *
+ * @param text
+ * string to process
+ * @return string after stripping
+ */
+ public static String removeHTMLtags(String text) {
+ return text == null ? null
+ : text.replaceAll(WebUtil.SPACE_TAG_REGEX, " ").replaceAll(WebUtil.HTML_TAG_REGEX, "");
+ }
+
+ /**
+ * Makes a request to the specified url with the specified parameters and returns the response inputstream
+ *
+ * @param urlStr
+ * @param params
+ * @return
+ * @throws ToolException
+ * @throws IOException
+ */
+ public static InputStream getResponseInputStreamFromExternalServer(String urlStr, HashMap
params)
+ throws IOException {
+ if (!urlStr.contains("?")) {
+ urlStr += "?";
+ }
+
+ for (Entry entry : params.entrySet()) {
+ urlStr += "&" + entry.getKey() + "=" + entry.getValue();
+ }
+
+ WebUtil.log.info("Making request to external servlet: " + urlStr);
+
+ URL url = new URL(urlStr);
+ URLConnection conn = url.openConnection();
+ if (!(conn instanceof HttpURLConnection)) {
+ WebUtil.log.error("Fail to connect to external server though url: " + urlStr);
+ throw new RuntimeException("Fail to connect to external server though url: " + urlStr);
+ }
+
+ HttpURLConnection httpConn = (HttpURLConnection) conn;
+ if (httpConn.getResponseCode() != HttpURLConnection.HTTP_OK) {
+ WebUtil.log.error("Response code from external server: " + httpConn.getResponseCode() + " Url: " + urlStr);
+ }
+
+ InputStream is = url.openConnection().getInputStream();
+ if (is == null) {
+ WebUtil.log.error("Fail to fetch data from external server, return InputStream null: " + urlStr);
+ throw new RuntimeException("Fail to fetch data from external server, return inputStream null: " + urlStr);
+ }
+
+ return is;
+ }
+
+ public static String extractParameterValue(String url, String param) {
+ if (!StringUtils.isBlank(url) && !StringUtils.isBlank(param)) {
+ int quotationMarkIndex = url.indexOf("?");
+ String queryPart = quotationMarkIndex > -1 ? url.substring(quotationMarkIndex + 1) : url;
+ String[] paramEntries = queryPart.split("&");
+ for (String paramEntry : paramEntries) {
+ String[] paramEntrySplitted = paramEntry.split("=");
+ if ((paramEntrySplitted.length > 1) && param.equalsIgnoreCase(paramEntrySplitted[0])) {
+ return paramEntrySplitted[1];
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Produces JSON object with basic user details.
+ */
+ public static ObjectNode userToJSON(User user) {
+ ObjectNode userJSON = JsonNodeFactory.instance.objectNode();
+ userJSON.put("id", user.getUserId());
+ userJSON.put("firstName", user.getFirstName());
+ userJSON.put("lastName", user.getLastName());
+ userJSON.put("login", user.getLogin());
+ userJSON.put("portraitId", user.getPortraitUuid() == null ? null : user.getPortraitUuid().toString());
+ return userJSON;
+ }
+
+ public static String getBaseServerURL() {
+ String serverURL = Configuration.get(ConfigurationKeys.SERVER_URL);
+ // "https://" is 8 characters, so next "/" should be context
+ return serverURL.substring(0, serverURL.indexOf('/', 9));
+ }
+
+ /**
+ * Converse lessonId into alphabetic sequence for using it in URL shortening
+ *
+ * @param lessonId
+ * @return
+ */
+ public static String encodeLessonId(Long lessonId) {
+ String encodedLessonId = lessonId.toString();
+ encodedLessonId = encodedLessonId.replace('0', URL_SHORTENING_CYPHER.charAt(0));
+ encodedLessonId = encodedLessonId.replace('1', URL_SHORTENING_CYPHER.charAt(1));
+ encodedLessonId = encodedLessonId.replace('2', URL_SHORTENING_CYPHER.charAt(2));
+ encodedLessonId = encodedLessonId.replace('3', URL_SHORTENING_CYPHER.charAt(3));
+ encodedLessonId = encodedLessonId.replace('4', URL_SHORTENING_CYPHER.charAt(4));
+ encodedLessonId = encodedLessonId.replace('5', URL_SHORTENING_CYPHER.charAt(5));
+ encodedLessonId = encodedLessonId.replace('6', URL_SHORTENING_CYPHER.charAt(6));
+ encodedLessonId = encodedLessonId.replace('7', URL_SHORTENING_CYPHER.charAt(7));
+ encodedLessonId = encodedLessonId.replace('8', URL_SHORTENING_CYPHER.charAt(8));
+ encodedLessonId = encodedLessonId.replace('9', URL_SHORTENING_CYPHER.charAt(9));
+
+ return encodedLessonId;
+ }
+
+ /**
+ * Decodes alphabetic sequence (that is lessonId encoded for URL shortening purposes)
+ *
+ * @param encodedlessonId
+ * @return
+ */
+ public static String decodeLessonId(String encodedLessonId) throws IllegalArgumentException {
+
+ // it should contain only the characters from URL_SHORTENING_CYPHER
+ if (!encodedLessonId.matches("[" + URL_SHORTENING_CYPHER + "]*")) {
+ throw new IllegalArgumentException("LessonId: " + encodedLessonId + " has wrong format.");
+ }
+
+ String decodedLessonId = encodedLessonId;
+ decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(0), '0');
+ decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(1), '1');
+ decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(2), '2');
+ decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(3), '3');
+ decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(4), '4');
+ decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(5), '5');
+ decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(6), '6');
+ decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(7), '7');
+ decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(8), '8');
+ decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(9), '9');
+
+ return decodedLessonId;
+ }
+
+ public static Document getDocument() throws ParserConfigurationException {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ Document document = builder.newDocument();
+ return document;
+ }
+
+ public static String getStringFromDocument(Document document) throws TransformerException {
+ DOMSource domSource = new DOMSource(document);
+ StringWriter writer = new StringWriter();
+ StreamResult result = new StreamResult(writer);
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Transformer transformer = tf.newTransformer();
+ transformer.transform(domSource, result);
+ return writer.toString();
+ }
}
Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/CrNode.java
===================================================================
diff -u -r1ee503e3d0e0228ea8a45025fddf15d9623c0377 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b
--- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/CrNode.java (.../CrNode.java) (revision 1ee503e3d0e0228ea8a45025fddf15d9623c0377)
+++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/CrNode.java (.../CrNode.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b)
@@ -21,7 +21,6 @@
* ****************************************************************
*/
-
package org.lamsfoundation.lams.contentrepository;
import java.io.Serializable;
@@ -31,6 +30,7 @@
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
+import java.util.UUID;
import javax.persistence.CascadeType;
import javax.persistence.Column;
@@ -57,6 +57,9 @@
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long nodeId;
+ @Column(name = "portrait_uuid")
+ private UUID portraitUuid;
+
@Column
private String path;
@@ -69,18 +72,15 @@
@Column(name = "next_version_id")
private Long nextVersionId;
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "workspace_id")
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "workspace_id")
private org.lamsfoundation.lams.contentrepository.CrWorkspace crWorkspace;
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "parent_nv_id")
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "parent_nv_id")
private org.lamsfoundation.lams.contentrepository.CrNodeVersion parentNodeVersion;
- @OneToMany(mappedBy = "node",
- cascade = CascadeType.ALL,
- orphanRemoval = true,
- fetch = FetchType.EAGER)
+ @OneToMany(mappedBy = "node", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private Set crNodeVersions;
/** default constructor - used by Hibernate */
@@ -133,6 +133,14 @@
this.nodeId = nodeId;
}
+ public UUID getPortraitUuid() {
+ return portraitUuid;
+ }
+
+ public void setPortraitUuid(UUID portraitUuid) {
+ this.portraitUuid = portraitUuid;
+ }
+
public String getPath() {
return this.path;
}
@@ -192,7 +200,7 @@
/** Add a version to this node */
public void addCrNodeVersion(CrNodeVersion version) {
if (getCrNodeVersions() == null) {
- Set set = new HashSet();
+ Set set = new HashSet<>();
set.add(version);
setCrNodeVersions(set);
} else {
@@ -264,12 +272,12 @@
* Get the history for this node. Quite intensive operation
* as it has to build all the data structures. Can't cache
* it as can't tell easily when the versions are changed.
- *
+ *
* @return SortedSet of IVersionDetail objects, ordered by version
*/
public SortedSet getVersionHistory() {
- SortedSet history = new TreeSet();
+ SortedSet history = new TreeSet<>();
Set versions = getCrNodeVersions();
if (versions != null) {
@@ -285,7 +293,7 @@
/**
* Indicates whether this node is of the specified node type.
- *
+ *
* @param nodeTypeName
* the name of a node type.
* @return true if this node is of the specified node type
Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/IVersionedNode.java
===================================================================
diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b
--- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/IVersionedNode.java (.../IVersionedNode.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80)
+++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/IVersionedNode.java (.../IVersionedNode.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b)
@@ -21,7 +21,6 @@
* ****************************************************************
*/
-
package org.lamsfoundation.lams.contentrepository;
import java.io.InputStream;
@@ -62,14 +61,14 @@
/**
* Returns an Set of all child nodes of node. Returns an empty
* set if no nodes found.
- *
+ *
* @return Set of nodes.
*/
public Set getChildNodes();
/**
* Does this node have a parent node?
- *
+ *
* @return boolean
*/
public boolean hasParentNode();
@@ -120,6 +119,8 @@
*/
public Long getUUID();
+ public String getPortraitUuid();
+
/**
* Indicates whether a property exists for this name
* Returns true if a property exists and false otherwise.
@@ -211,23 +212,23 @@
/**
* Get the date/time of when this node was created.
- *
+ *
* @return date/time stamp of creation
*/
public Date getCreatedDateTime();
/**
* Get the file, as an inputstream. It is the responsibility
* of the caller to close the stream.
- *
+ *
* If the node is a package node, it will get the input stream
* of the first file.
*/
public InputStream getFile() throws FileException;
/**
* Get the user_id of the user who created this node.
- *
+ *
* @return userId
*/
public Integer getUserId();
Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/Download.java
===================================================================
diff -u -r1e26200cec472e799b29f548270b1a67027e9167 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b
--- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/Download.java (.../Download.java) (revision 1e26200cec472e799b29f548270b1a67027e9167)
+++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/Download.java (.../Download.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b)
@@ -138,8 +138,6 @@
private void handleCall(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, RepositoryCheckedException {
- long start = System.currentTimeMillis();
-
ITicket ticket = null;
String toolContentHandlerName = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_HANDLER_NAME);
if (StringUtils.isBlank(toolContentHandlerName)) {
@@ -152,18 +150,15 @@
throw new RepositoryCheckedException("Unable to get ticket - getTicket(false) returned null");
}
- Long uuid = Download.getLong(request.getParameter(Download.UUID_NAME));
+ String uuid = request.getParameter(Download.UUID_NAME);
Long version = null;
boolean saveFile = Download.getBoolean(request.getParameter(Download.PREFER_DOWNLOAD));
- String callId = null;
-
if (uuid != null) {
version = Download.getLong(request.getParameter(Download.VERSION_NAME));
-
- IVersionedNode node = getFileItem(ticket, uuid, version, null);
-
+ IVersionedNode node = uuid.contains("-") ? getRepositoryService().getFileItem(ticket, uuid, version)
+ : getRepositoryService().getFileItem(ticket, Long.valueOf(uuid), version);
// update versionId in case it was null and we got the latest version...
version = node.getVersion();
@@ -200,12 +195,10 @@
// using the /download// format - must be a file node!
String pathString = request.getPathInfo();
String[] strings = deriveIdFile(pathString);
- uuid = Download.getLong(strings[0]);
+ uuid = strings[0];
version = Download.getLong(strings[1]);
String relPathString = strings[2];
- callId = "download " + Math.random() + " " + uuid;
-
if (uuid == null) {
throw new RepositoryCheckedException("UUID value is missing. " + Download.expectedFormat);
}
@@ -218,7 +211,8 @@
throw new RepositoryCheckedException("Filename is missing. " + Download.expectedFormat);
}
- IVersionedNode node = getFileItem(ticket, uuid, version, relPathString);
+ IVersionedNode node = uuid.contains("-") ? getRepositoryService().getFileItem(ticket, uuid, version)
+ : getRepositoryService().getFileItem(ticket, Long.valueOf(uuid), version);
if (!node.isNodeType(NodeType.FILENODE)) {
throw new RepositoryCheckedException(
"Unexpected type of node " + node.getNodeType() + " Expected File node. Data is " + node);
@@ -229,29 +223,6 @@
}
/**
- * The call getFileItem was throwing a runtime hibernate/jdbc error when being thrash tested, and I couldn't work
- * out the context, so I've wrapped the call here so it can be debugged.
- */
- private IVersionedNode getFileItem(ITicket ticket, Long uuid, Long version, String relPathString)
- throws RepositoryCheckedException {
- try {
- IVersionedNode node = null;
- if (relPathString != null) {
- // get file in package
- node = getRepositoryService().getFileItem(ticket, uuid, version, relPathString);
- } else {
- // get node
- node = getRepositoryService().getFileItem(ticket, uuid, version);
- }
- return node;
- } catch (RuntimeException e) {
- Download.log.error("Exception thrown calling repository.getFileItem(," + uuid + "," + version + ","
- + relPathString + "). " + e.getMessage(), e);
- throw e;
- }
- }
-
- /**
* @param response
* @param aNode
* @throws IOException
Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/ToolContentHandler.java
===================================================================
diff -u -r783f965b1bb2251474d01f32a53e4ccb28d5473b -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b
--- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/ToolContentHandler.java (.../ToolContentHandler.java) (revision 783f965b1bb2251474d01f32a53e4ccb28d5473b)
+++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/ToolContentHandler.java (.../ToolContentHandler.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b)
@@ -25,6 +25,7 @@
import java.io.IOException;
import java.io.InputStream;
+import java.util.UUID;
import org.apache.log4j.Logger;
import org.lamsfoundation.lams.contentrepository.ICredentials;
@@ -172,16 +173,18 @@
}
@Override
- public NodeKey uploadFile(InputStream stream, String fileName, String mimeType)
+ public NodeKey uploadFile(InputStream stream, String fileName, String mimeType, boolean generatePortraitUuid)
throws RepositoryCheckedException, InvalidParameterException, RepositoryCheckedException {
NodeKey nodeKey = null;
try {
try {
- nodeKey = repositoryService.addFileItem(getTicket(false), stream, fileName, mimeType, null);
+ nodeKey = repositoryService.addFileItem(getTicket(false), stream, fileName, mimeType, null,
+ generatePortraitUuid);
} catch (AccessDeniedException e) {
log.warn("Unable to access repository to add file " + fileName + "AccessDeniedException: "
+ e.getMessage() + " Retrying login.");
- nodeKey = repositoryService.addFileItem(getTicket(true), stream, fileName, mimeType, null);
+ nodeKey = repositoryService.addFileItem(getTicket(true), stream, fileName, mimeType, null,
+ generatePortraitUuid);
}
} catch (RepositoryCheckedException e2) {
@@ -194,6 +197,12 @@
}
@Override
+ public NodeKey uploadFile(InputStream stream, String fileName, String mimeType)
+ throws RepositoryCheckedException, InvalidParameterException, RepositoryCheckedException {
+ return uploadFile(stream, fileName, mimeType, false);
+ }
+
+ @Override
public NodeKey updateFile(Long uuid, InputStream stream, String fileName, String mimeType)
throws RepositoryCheckedException, InvalidParameterException, RepositoryCheckedException {
NodeKey nodeKey = null;
@@ -353,6 +362,25 @@
}
@Override
+ public void deleteFile(UUID portraitUuid) throws InvalidParameterException, RepositoryCheckedException {
+ try {
+ try {
+ repositoryService.deleteNode(getTicket(false), portraitUuid);
+ } catch (AccessDeniedException e) {
+ log.warn("Unable to access repository to delete file id" + portraitUuid + "AccessDeniedException: "
+ + e.getMessage() + " Retrying login.");
+ repositoryService.deleteNode(getTicket(true), portraitUuid);
+ }
+ } catch (ItemNotFoundException e1) {
+ // didn't exist so don't need to delete. Ignore problem.
+ } catch (RepositoryCheckedException e2) {
+ log.error("Unable delete file id" + portraitUuid + "Repository Exception: " + e2.getMessage()
+ + " Retry not possible.");
+ throw e2;
+ }
+ }
+
+ @Override
public InputStream getFileInputStream(Long uuid)
throws ItemNotFoundException, FileException, RepositoryCheckedException {
try {
Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/INodeFactory.java
===================================================================
diff -u -rea80430beb4497f12c92db2580341f21750a5a43 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b
--- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/INodeFactory.java (.../INodeFactory.java) (revision ea80430beb4497f12c92db2580341f21750a5a43)
+++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/INodeFactory.java (.../INodeFactory.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b)
@@ -21,10 +21,10 @@
* ****************************************************************
*/
-
package org.lamsfoundation.lams.contentrepository.service;
import java.io.InputStream;
+import java.util.UUID;
import org.lamsfoundation.lams.contentrepository.CrNode;
import org.lamsfoundation.lams.contentrepository.CrWorkspace;
@@ -43,7 +43,7 @@
/**
* Create a new file node (which is assumed to be a newly created Spring
* bean) with relPath and node type.
- *
+ *
* @param relPath
* The path of the new Node that is to be created,
* the last item of this path will be the name of the new Node.
@@ -54,12 +54,13 @@
*/
public abstract SimpleVersionedNode createFileNode(CrWorkspace workspace, SimpleVersionedNode parentNode,
String relPath, InputStream istream, String filename, String mimeType, String versionDescription,
- Integer userId) throws org.lamsfoundation.lams.contentrepository.exception.InvalidParameterException;
+ Integer userId, boolean generatePortraitUuid)
+ throws org.lamsfoundation.lams.contentrepository.exception.InvalidParameterException;
/**
* Create a new package node (which is assumed to be a newly created Spring
* bean) with the default file and node type. Package node cannot have a parent node.
- *
+ *
* @param initialPath
* The path of the default content.
* @throws org.lamsfoundation.lams.contentrepository.exception.InvalidParameterException
@@ -74,7 +75,7 @@
/**
* Create a new data node (which is assumed to be a newly created Spring
* bean). This node may have a parent node.
- *
+ *
* @throws org.lamsfoundation.lams.contentrepository.exception.InvalidParameterException
* if the file parameters are invalid
* @throws RepositoryRuntimeException
@@ -87,7 +88,7 @@
/**
* Build a SimpleVersionedNode, given a CrNode from the database. If versionId == null
* then gets the latest version.
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.IVersionedNode#getNode(String relPath)
*/
public abstract SimpleVersionedNode getNode(CrNode databaseNode, Long versionId);
@@ -97,17 +98,20 @@
* Creates the CrNode and CrNodeVersion objects.
* Equivalent of createFileNode/createPackageNode for existing nodes
* Checks that the workspace found in the database is the expected workspace.
- *
+ *
* If this node object is returned to a web app, then the
* crNode and crNodeVersion objects will be disconnected
* from the session, as the session will have been ended
* with the Spring transaction.
- *
+ *
* If versionId is null, then gets the latest version
*/
public abstract SimpleVersionedNode getNode(Long workspaceId, Long uuid, Long versionId)
throws ItemNotFoundException;
+ public abstract SimpleVersionedNode getNode(Long workspaceId, UUID portraitUuid, Long versionId)
+ throws ItemNotFoundException;
+
/**
* Build a SimpleVersionedNode, reading the data from the database.
* Creates a new (empty) version ready for updating.
@@ -118,9 +122,9 @@
* crNode and crNodeVersion objects will be disconnected
* from the session, as the session will have been ended
* with the Spring transaction.
- *
+ *
* @throws ItemNotFoundException
- *
+ *
* @throws RepositoryRuntimeException
* if an internal error occurs.
* @see org.lamsfoundation.lams.contentrepository.IVersionedNode#createNewVersion(java.lang.String,
@@ -132,11 +136,11 @@
/**
* Copy the supplied node/version to a new node. Does not copy the history
* of the node. Copies any child nodes of the current version. All files are duplicated.
- *
+ *
* This method only works as we know that we have two levels of nodes - the
* childNodes can't have their own childNodes. If this is no longer the case,
* this method and SimpleVersionedNode.save() will need to be changed.
- *
+ *
* @throws FileException
* will occur if there is a problem reading a file from the repository
* @throws InvalidParameterException
Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/IRepositoryService.java
===================================================================
diff -u -rea80430beb4497f12c92db2580341f21750a5a43 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b
--- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/IRepositoryService.java (.../IRepositoryService.java) (revision ea80430beb4497f12c92db2580341f21750a5a43)
+++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/IRepositoryService.java (.../IRepositoryService.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b)
@@ -28,6 +28,7 @@
import java.util.List;
import java.util.SortedMap;
import java.util.SortedSet;
+import java.util.UUID;
import org.lamsfoundation.lams.contentrepository.CrWorkspace;
import org.lamsfoundation.lams.contentrepository.ICredentials;
@@ -170,7 +171,8 @@
* if any internal errors have occured
*/
public abstract NodeKey addFileItem(ITicket ticket, InputStream istream, String filename, String mimeType,
- String versionDescription) throws FileException, AccessDeniedException, InvalidParameterException;
+ String versionDescription, boolean generatePortraitUuid)
+ throws FileException, AccessDeniedException, InvalidParameterException;
/**
* Add a new package of files to the repository. If startFile
@@ -329,6 +331,9 @@
public abstract IVersionedNode getFileItem(ITicket ticket, Long uuid, Long version)
throws AccessDeniedException, ItemNotFoundException, FileException;
+ IVersionedNode getFileItem(ITicket ticket, String portraitUuid, Long version)
+ throws AccessDeniedException, ItemNotFoundException, FileException;
+
/**
* Get an item from the repository based on the UUID and relative
* path. Only used to get the content from a package. The
@@ -441,6 +446,9 @@
public String[] deleteNode(ITicket ticket, Long uuid)
throws AccessDeniedException, InvalidParameterException, ItemNotFoundException;
+ public String[] deleteNode(ITicket ticket, UUID portraitUuid)
+ throws AccessDeniedException, InvalidParameterException, ItemNotFoundException;
+
/**
* Finish using this ticket. No more updates may be used with this ticket
* after logout(). Allows any resources to be freed.
Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/NodeFactory.java
===================================================================
diff -u -rc1c22cae1f9de439732bbb93eed949b583917af9 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b
--- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/NodeFactory.java (.../NodeFactory.java) (revision c1c22cae1f9de439732bbb93eed949b583917af9)
+++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/NodeFactory.java (.../NodeFactory.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b)
@@ -21,13 +21,14 @@
* ****************************************************************
*/
-
package org.lamsfoundation.lams.contentrepository.service;
import java.io.InputStream;
import java.util.Date;
import java.util.Iterator;
+import java.util.List;
import java.util.Set;
+import java.util.UUID;
import org.apache.log4j.Logger;
import org.lamsfoundation.lams.contentrepository.CrNode;
@@ -68,26 +69,26 @@
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#createFileNode(org.lamsfoundation.lams.
* contentrepository.CrWorkspace, org.lamsfoundation.lams.contentrepository.service.SimpleVersionedNode,
* java.lang.String, java.io.InputStream, java.lang.String, java.lang.String, java.lang.String)
*/
@Override
public SimpleVersionedNode createFileNode(CrWorkspace workspace, SimpleVersionedNode parentNode, String relPath,
- InputStream istream, String filename, String mimeType, String versionDescription, Integer userId)
- throws InvalidParameterException {
+ InputStream istream, String filename, String mimeType, String versionDescription, Integer userId,
+ boolean generatePortraitUuid) throws InvalidParameterException {
SimpleVersionedNode initialNodeVersion = createBasicNode(NodeType.FILENODE, workspace, parentNode, relPath,
- versionDescription, userId);
+ versionDescription, userId, generatePortraitUuid);
initialNodeVersion.setFile(istream, filename, mimeType);
return initialNodeVersion;
}
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#createPackageNode(org.lamsfoundation.lams.
* contentrepository.CrWorkspace, java.lang.String, java.lang.String)
*/
@@ -96,15 +97,15 @@
Integer userId) throws org.lamsfoundation.lams.contentrepository.exception.InvalidParameterException {
SimpleVersionedNode initialNodeVersion = createBasicNode(NodeType.PACKAGENODE, workspace, null, null,
- versionDescription, userId);
+ versionDescription, userId, false);
initialNodeVersion.setProperty(PropertyName.INITIALPATH, initialPath);
return initialNodeVersion;
}
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#createDataNode(org.lamsfoundation.lams.
* contentrepository.CrWorkspace, org.lamsfoundation.lams.contentrepository.service.SimpleVersionedNode,
* java.lang.String)
@@ -115,21 +116,24 @@
throws org.lamsfoundation.lams.contentrepository.exception.InvalidParameterException {
SimpleVersionedNode initialNodeVersion = createBasicNode(NodeType.DATANODE, workspace, parentNode, null,
- versionDescription, userId);
+ versionDescription, userId, false);
return initialNodeVersion;
}
/** Create the core part of a node */
private SimpleVersionedNode createBasicNode(String nodeType, CrWorkspace workspace, SimpleVersionedNode parentNode,
- String relPath, String versionDescription, Integer userId) {
+ String relPath, String versionDescription, Integer userId, boolean generatePortraitUuid) {
SimpleVersionedNode initialNodeVersion = beanFactory.getBean("node", SimpleVersionedNode.class);
Date createdDate = new Date(System.currentTimeMillis());
CrNodeVersion parentNodeVersion = parentNode != null ? parentNode.getNodeVersion() : null;
CrNode node = new CrNode(relPath, nodeType, createdDate, userId, workspace, parentNodeVersion,
versionDescription);
+ if (generatePortraitUuid) {
+ node.setPortraitUuid(UUID.randomUUID());
+ }
CrNodeVersion nodeVersion = node.getNodeVersion(null);
initialNodeVersion.setNode(node);
@@ -144,7 +148,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see
* org.lamsfoundation.lams.contentrepository.service.INodeFactory#getNode(org.lamsfoundation.lams.contentrepository.
* CrNode, java.lang.Long)
@@ -159,7 +163,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#getNode(java.lang.Long, java.lang.Long,
* java.lang.Long)
*/
@@ -176,7 +180,7 @@
CrNode node = null;
- node = (CrNode) nodeDAO.find(CrNode.class, uuid);
+ node = nodeDAO.find(CrNode.class, uuid);
if (node == null) {
throw new ItemNotFoundException("Node " + uuid + " not found.");
@@ -192,9 +196,39 @@
return getNode(node, versionId);
}
+ @Override
+ public SimpleVersionedNode getNode(Long workspaceId, UUID portraitUuid, Long versionId)
+ throws ItemNotFoundException {
+
+ if (portraitUuid == null) {
+ throw new ItemNotFoundException("UUID is null, unable to find node.");
+ }
+
+ if (workspaceId == null) {
+ throw new ItemNotFoundException("Workspace Id is null, unable to find node.");
+ }
+
+ CrNode node = null;
+ List result = nodeDAO.findByProperty(CrNode.class, "portraitUuid", portraitUuid);
+ node = result.isEmpty() ? null : result.get(0);
+ if (node == null) {
+
+ throw new ItemNotFoundException("Node " + portraitUuid + " not found.");
+
+ } else if (!workspaceId.equals(node.getCrWorkspace().getWorkspaceId())) {
+
+ log.error("Security warning. User of workspace " + workspaceId + " is trying to access node " + portraitUuid
+ + " which is in workspace " + node.getCrWorkspace().getWorkspaceId()
+ + " Request for node will be rejected.");
+ throw new ItemNotFoundException("Node " + portraitUuid + " does not exist in workspace " + workspaceId);
+ }
+
+ return getNode(node, versionId);
+ }
+
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#getNode(java.lang.Long, java.lang.Long,
* java.lang.Long, java.lang.String)
*/
@@ -220,7 +254,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see
* org.lamsfoundation.lams.contentrepository.service.INodeFactory#copy(org.lamsfoundation.lams.contentrepository.
* service.SimpleVersionedNode)
@@ -235,7 +269,7 @@
/**
* Private method to handle the recursive copy. The parent node is needed to set up the
* node -> parent link in the CrNode object.
- *
+ *
* @param originalNode
* @param parentNode
* @return new Node
@@ -268,7 +302,7 @@
}
}
- // copy any attached file. don't actually copy the file - set up
+ // copy any attached file. don't actually copy the file - set up
// and input stream and the file will be copied when the node is saved.
// this is likely to recopy the Filename and Mimetype properties.
if (originalNode.isNodeType(NodeType.FILENODE)) {
@@ -300,7 +334,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#getNodeDAO()
*/
@Override
@@ -310,7 +344,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#setNodeDAO(org.lamsfoundation.lams.
* contentrepository.dao.INodeDAO)
*/
@@ -322,7 +356,7 @@
/* **** Method for BeanFactoryAware interface *****************/
/*
* (non-Javadoc)
- *
+ *
* @see
* org.lamsfoundation.lams.contentrepository.service.INodeFactory#setBeanFactory(org.springframework.beans.factory.
* BeanFactory)
Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/SimpleRepository.java
===================================================================
diff -u -rea80430beb4497f12c92db2580341f21750a5a43 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b
--- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/SimpleRepository.java (.../SimpleRepository.java) (revision ea80430beb4497f12c92db2580341f21750a5a43)
+++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/SimpleRepository.java (.../SimpleRepository.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b)
@@ -21,7 +21,6 @@
* ****************************************************************
*/
-
package org.lamsfoundation.lams.contentrepository.service;
import java.io.FileNotFoundException;
@@ -37,6 +36,7 @@
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
+import java.util.UUID;
import javax.servlet.http.HttpSession;
@@ -87,7 +87,7 @@
* run separately and without suitable AOP support then
* each transaction method must check that the credential is okay
* or that the ticket is a known ticket (isTicketOkay() method).
- *
+ *
* This class also depends on the transactions defined in the
* application context for the hibernate sessions to work properly.
* If the method isn't transactioned, then there won't be a proper
@@ -134,10 +134,10 @@
}
return user.getUserID();
}
- throw new AccessDeniedException(
- "Cannot get user details for content repository. No session found - user not logged in or the webservice call has not set up the session details.");
+ throw new AccessDeniedException(
+ "Cannot get user details for content repository. No session found - user not logged in or the webservice call has not set up the session details.");
- }
+ }
/**
* @param workspaceId
@@ -155,7 +155,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.IRepository#login(org.lamsfoundation.lams.contentrepository.
* ICredentials, java.lang.String)
*/
@@ -182,7 +182,7 @@
}
// okay, we should now be able to create a ticket
- // make ticket, create new credentials without the password
+ // make ticket, create new credentials without the password
ITicket ticket = new SimpleTicket(workspace.getWorkspaceId());
ticketIdSet.add(ticket.getTicketId());
return ticket;
@@ -191,7 +191,7 @@
/**
* Add a workspace, giving the credentials as the user of this workspace.
* It does not clear the password in the credentials
- *
+ *
* @param credentials
* this user/password must already exist in the repository. Password will be checked.
* @param workspaceName
@@ -266,7 +266,7 @@
* The password must be at least 6 chars.
* Possibly this should only be available to an internal management tool
* *** Security Risk - I'm converting the password to a string... ***
- *
+ *
* @throws LoginException
* if the oldCredential fails login test (e.g. wrong password)
* @throws RepositoryCheckedException
@@ -304,9 +304,9 @@
/**
* Checks that a password meets our password criteria. This could be implemented
* as a Strategy, but that's overkill!
- *
+ *
* Checks that the password is six or more characters.
- *
+ *
* @param password
* @throws RepositoryCheckedException
* if
@@ -404,7 +404,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see
* org.lamsfoundation.lams.contentrepository.IRepository#logout(org.lamsfoundation.lams.contentrepository.ITicket)
*/
@@ -426,19 +426,20 @@
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.IRepository#addFileItem(org.lamsfoundation.lams.contentrepository.
* ITicket, java.io.InputStream, java.lang.String, java.lang.String, java.lang.String)
*/
@Override
public NodeKey addFileItem(ITicket ticket, InputStream istream, String filename, String mimeType,
- String versionDescription) throws FileException, AccessDeniedException, InvalidParameterException {
+ String versionDescription, boolean generatePortraitUUid)
+ throws FileException, AccessDeniedException, InvalidParameterException {
try {
CrWorkspace workspace = getWorkspace(ticket.getWorkspaceId());
Integer userId = getCurrentUserId();
SimpleVersionedNode initialNodeVersion = nodeFactory.createFileNode(workspace, null, null, istream,
- filename, mimeType, versionDescription, userId);
+ filename, mimeType, versionDescription, userId, generatePortraitUUid);
initialNodeVersion.save();
return initialNodeVersion.getNodeKey();
} catch (ValidationException e) {
@@ -452,7 +453,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see
* org.lamsfoundation.lams.contentrepository.IRepository#addPackageItem(org.lamsfoundation.lams.contentrepository.
* ITicket, java.lang.String, java.lang.String, java.lang.String)
@@ -486,7 +487,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.IRepository#getFileItem(org.lamsfoundation.lams.contentrepository.
* ITicket, java.lang.Long, java.lang.Long)
*/
@@ -497,9 +498,15 @@
return nodeFactory.getNode(ticket.getWorkspaceId(), uuid, version);
}
+ @Override
+ public IVersionedNode getFileItem(ITicket ticket, String portraitUuid, Long version)
+ throws AccessDeniedException, ItemNotFoundException, FileException {
+ return nodeFactory.getNode(ticket.getWorkspaceId(), UUID.fromString(portraitUuid), version);
+ }
+
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.IRepository#getFileItem(org.lamsfoundation.lams.contentrepository.
* ITicket, java.lang.Long, java.lang.Long, java.lang.String)
*/
@@ -530,7 +537,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.IRepository#getFileItem(org.lamsfoundation.lams.contentrepository.
* ITicket, java.lang.Long, java.lang.Long, java.lang.String)
*/
@@ -556,7 +563,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.IRepository#getNodeList(org.lamsfoundation.lams.contentrepository.
* ITicket)
*/
@@ -582,7 +589,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see
* org.lamsfoundation.lams.contentrepository.IRepository#getVersionHistory(org.lamsfoundation.lams.contentrepository
* .ITicket, java.lang.Long)
@@ -596,7 +603,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see
* org.lamsfoundation.lams.contentrepository.IRepository#updateFileItem(org.lamsfoundation.lams.contentrepository.
* ITicket, java.lang.Long, java.lang.String, java.io.InputStream, java.lang.String, java.lang.String)
@@ -627,7 +634,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see
* org.lamsfoundation.lams.contentrepository.IRepository#updatePackageItem(org.lamsfoundation.lams.contentrepository
* .ITicket, java.lang.Long, java.lang.String, java.lang.String, java.lang.String)
@@ -690,7 +697,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see
* org.lamsfoundation.lams.contentrepository.IRepository#copyNodeVersion(org.lamsfoundation.lams.contentrepository.
* ITicket, java.lang.Long, java.lang.Long)
@@ -723,7 +730,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see
* org.lamsfoundation.lams.contentrepository.IRepository#saveFile(org.lamsfoundation.lams.contentrepository.ITicket,
* java.lang.Long, java.lang.String, java.lang.String, java.lang.String)
@@ -804,7 +811,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see
* org.lamsfoundation.lams.contentrepository.IRepository#updatePackageItem(org.lamsfoundation.lams.contentrepository
* .ITicket, java.lang.Long, java.lang.String, java.lang.String, java.lang.String)
@@ -828,9 +835,28 @@
}
+ @Override
+ public String[] deleteNode(ITicket ticket, UUID portraitUuid)
+ throws AccessDeniedException, InvalidParameterException, ItemNotFoundException {
+
+ if (portraitUuid == null) {
+ throw new InvalidParameterException("UUID is required for deleteItem.");
+ }
+
+ // get the first version of the node and delete from there.
+ SimpleVersionedNode latestNodeVersion = nodeFactory.getNode(ticket.getWorkspaceId(), portraitUuid, new Long(1));
+ if (latestNodeVersion.hasParentNode()) {
+ throw new InvalidParameterException("You cannot delete a node that is in a package (ie has a parent). "
+ + "Please delete the parent. Node UUID " + portraitUuid);
+ }
+ List problemPaths = latestNodeVersion.deleteNode();
+ return problemPaths != null ? (String[]) problemPaths.toArray(new String[problemPaths.size()]) : new String[0];
+
+ }
+
/*
* (non-Javadoc)
- *
+ *
* @see
* org.lamsfoundation.lams.contentrepository.IRepository#updatePackageItem(org.lamsfoundation.lams.contentrepository
* .ITicket, java.lang.Long, java.lang.String, java.lang.String, java.lang.String)
@@ -850,10 +876,12 @@
}
+ @Override
public boolean workspaceExists(ICredentials credentials, Long workspaceId) {
return workspaceDAO.find(CrWorkspace.class, workspaceId) != null;
}
+ @Override
public boolean workspaceExists(ICredentials credentials, String workspaceName) {
return workspaceDAO.findByName(workspaceName) != null;
}
Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/SimpleVersionedNode.java
===================================================================
diff -u -rc1c22cae1f9de439732bbb93eed949b583917af9 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b
--- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/SimpleVersionedNode.java (.../SimpleVersionedNode.java) (revision c1c22cae1f9de439732bbb93eed949b583917af9)
+++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/SimpleVersionedNode.java (.../SimpleVersionedNode.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b)
@@ -21,7 +21,6 @@
* ****************************************************************
*/
-
package org.lamsfoundation.lams.contentrepository.service;
import java.io.ByteArrayInputStream;
@@ -145,12 +144,12 @@
@Override
public NodeKey getNodeKey() {
- return new NodeKey(getUUID(), getVersion());
+ return new NodeKey(getUUID(), getVersion(), getPortraitUuid());
}
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, java.lang.String,
* int)
*/
@@ -162,7 +161,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, java.lang.String)
*/
@Override
@@ -173,7 +172,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, boolean)
*/
@Override
@@ -184,7 +183,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, double)
*/
@Override
@@ -195,7 +194,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, long)
*/
@Override
@@ -206,7 +205,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, java.util.Calendar)
*/
@Override
@@ -244,6 +243,12 @@
return node.getNodeId();
}
+ @Override
+ public String getPortraitUuid() {
+ nodeObjectInitilised("Unable to get portrait UUID");
+ return node.getPortraitUuid() == null ? null : node.getPortraitUuid().toString();
+ }
+
/**
* @see org.lamsfoundation.lams.contentrepository.IVersionedNode#hasProperty(java.lang.String)
*/
@@ -273,7 +278,7 @@
/**
* (non-Javadoc)
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.IVersionedNode#isNodeType(java.lang.String)
*/
@Override
@@ -286,7 +291,7 @@
* Get the history for this node. Quite intensive operation
* as it has to build all the data structures. Can't be easily
* cached.
- *
+ *
* @return SortedSet of IVersionDetail objects, ordered by version
*/
@Override
@@ -382,7 +387,7 @@
* of the caller to close the stream. Note: this should only be
* called once the node is saved - do not call it directly after
* setting the file stream
- *
+ *
* If the node is a package node, it will get the input stream
* of the first file.
*/
@@ -418,7 +423,7 @@
/**
* Set the file, passed in as an inputstream. The stream will be closed
* when the file is saved. Only nodes of type FILENODE can have a file!
- *
+ *
* @param iStream
* mandatory
* @param filename
@@ -494,7 +499,7 @@
* we could just be doing a setProperty save, in which case the file
* will already exist.
* Package nodes must not have a file, must have a INITIALPATH property
- *
+ *
* @throws ValidationException
* if problems exist.
*/
@@ -557,19 +562,19 @@
* Save the changes to this node. This method must be called when saving a file
* or package node for the first time - it does both the database and the file
* saves.
- *
+ *
* If it is a file node, then it writes out the db changes and then saves
* the file.
- *
+ *
* If is is a package node, then it writes out the db changes for all the nodes,
* then saves all the file. Why do it this way - we want to do all the file
* changes at the end as they cannot be rolled back if there is a db error.
- *
+ *
* This method only works as we know that we have two levels of nodes - the
* childNodes can't have their own childNodes. If this is no longer the case,
* this method and copy() will need to be changed.
- *
*
+ *
* TODO This needs a lot of testing
*/
protected Long save() throws ValidationException, FileException {
@@ -631,7 +636,8 @@
: element.getFilePath();
} else {
failedDeleted = failedDeleted != null
- ? failedDeleted + File.pathSeparator + element.getFilePath() : element.getFilePath();
+ ? failedDeleted + File.pathSeparator + element.getFilePath()
+ : element.getFilePath();
}
}
String msg = "Result of rolling back file changes:";
@@ -683,7 +689,7 @@
/**
* Write the file out (if one exists). Sets the private attribute filePath.
- *
+ *
* @return the path to which the file was written
*/
private void writeFile() throws FileException {
@@ -711,7 +717,7 @@
/**
* Another case for the factory?
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.IVersionedNode#getNode(String relPath)
*/
@Override
@@ -735,7 +741,7 @@
/**
* If no nodes are found, returns an empty set.
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.IVersionedNode#getChildNodes()
*/
@Override
@@ -798,13 +804,13 @@
/**
* Delete all versions of this node, returning the number of nodes
* deleted. If it is a package node, all child nodes will be deleted.
- *
+ *
* @see org.lamsfoundation.lams.contentrepository.IVersionedNodeAdmin#deleteNode()
*/
@Override
public List deleteNode() {
- // first make a list of all the versions to delete.
+ // first make a list of all the versions to delete.
// don't iterate over the set, deleting as we go so that
// we can't run into any issues trying to access something
// that is deleted or belongs to an iterator.
@@ -838,7 +844,7 @@
// doing file system changes if the db would fail later.
deleteVersionFromDB(nodeKeysDeleted);
- // now delete the files. If it fails due to the file not being found, then
+ // now delete the files. If it fails due to the file not being found, then
// that's fine.
ArrayList failedList = new ArrayList();
Iterator iter = nodeKeysDeleted.iterator();
@@ -906,7 +912,7 @@
/**
* Process files in the package. Create a List of file nodes but do not persist
* the nodes.
- *
+ *
* @param dirPath:
* the directory from which to get files. Mandatory.
* @param packageNode:
@@ -1001,7 +1007,7 @@
// no need to the new node as a child node, as createFileNode will do it.
FileInputStream istream = new FileInputStream(file);
nodeFactory.createFileNode(workspace, this, relPath, istream, filename, null, versionDescription,
- userId);
+ userId, false);
}
}
@@ -1025,11 +1031,11 @@
/**
* Copy the supplied node/version to a new node. Does not copy the history
* of the node. Copies any child nodes of the current version. All files are duplicated.
- *
+ *
* This method only works as we know that we have two levels of nodes - the
* childNodes can't have their own childNodes. If this is no longer the case,
* this method and SimpleVersionedNode.save() will need to be changed.
- *
+ *
* @throws FileException
* will occur if there is a problem reading a file from the repository
* @throws InvalidParameterException
Index: lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/dto/GBUserGridRowDTO.java
===================================================================
diff -u -rfd2cfad55c7c517931f69334ce644d509ec28140 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b
--- lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/dto/GBUserGridRowDTO.java (.../GBUserGridRowDTO.java) (revision fd2cfad55c7c517931f69334ce644d509ec28140)
+++ lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/dto/GBUserGridRowDTO.java (.../GBUserGridRowDTO.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b)
@@ -41,7 +41,7 @@
private String lastName;
private String login;
private String currentActivity;
- private Long portraitId;
+ private String portraitId;
private boolean hasArchivedMarks;
@@ -54,12 +54,12 @@
this.firstName = user.getFirstName();
this.lastName = user.getLastName();
this.login = user.getLogin();
- this.setPortraitId(user.getPortraitUuid());
+ this.setPortraitId(user.getPortraitUuid() == null ? null : user.getPortraitUuid().toString());
}
@Override
public ArrayList toStringArray(GBGridView view) {
- ArrayList ret = new ArrayList();
+ ArrayList ret = new ArrayList<>();
ret.add(id.toString());
@@ -150,11 +150,11 @@
this.currentActivity = currentActivity;
}
- public Long getPortraitId() {
+ public String getPortraitId() {
return portraitId;
}
- public void setPortraitId(Long portraitId) {
+ public void setPortraitId(String portraitId) {
this.portraitId = portraitId;
}
Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentResultDAOHibernate.java
===================================================================
diff -u -r02ce40b60524aa33d326fbda824dcd43f566ab94 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b
--- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentResultDAOHibernate.java (.../AssessmentResultDAOHibernate.java) (revision 02ce40b60524aa33d326fbda824dcd43f566ab94)
+++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentResultDAOHibernate.java (.../AssessmentResultDAOHibernate.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b)
@@ -258,15 +258,15 @@
@Override
public List