Index: lams_build/lib/lams/lams-central.jar =================================================================== diff -u -r126d84999e520648cb187e465cb4aaa3baad222e -rd76e13fea785246cc091078e2b8eb460cc7bf342 Binary files differ Index: lams_central/src/java/org/lamsfoundation/lams/util/CentralConstants.java =================================================================== diff -u -r49cb26ada930a59687956591672498c7f5613d34 -rd76e13fea785246cc091078e2b8eb460cc7bf342 --- lams_central/src/java/org/lamsfoundation/lams/util/CentralConstants.java (.../CentralConstants.java) (revision 49cb26ada930a59687956591672498c7f5613d34) +++ lams_central/src/java/org/lamsfoundation/lams/util/CentralConstants.java (.../CentralConstants.java) (revision d76e13fea785246cc091078e2b8eb460cc7bf342) @@ -174,4 +174,6 @@ public static final String FILE_EXTENSION_XLS = ".xls"; public static final String FILE_EXTENSION_CSV = ".csv"; + + public static final String HEADER_CONTENT_ATTACHMENT = "attachment;filename="; } \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/util/FileUtil.java =================================================================== diff -u -r49cb26ada930a59687956591672498c7f5613d34 -rd76e13fea785246cc091078e2b8eb460cc7bf342 --- lams_common/src/java/org/lamsfoundation/lams/util/FileUtil.java (.../FileUtil.java) (revision 49cb26ada930a59687956591672498c7f5613d34) +++ lams_common/src/java/org/lamsfoundation/lams/util/FileUtil.java (.../FileUtil.java) (revision d76e13fea785246cc091078e2b8eb460cc7bf342) @@ -35,17 +35,22 @@ import java.io.Writer; import java.net.URLEncoder; import java.nio.channels.FileChannel; +import java.text.SimpleDateFormat; +import java.util.Calendar; import java.util.Date; import java.util.Properties; import javax.mail.internet.MimeUtility; import javax.servlet.http.HttpServletRequest; +import jxl.CellView; import jxl.JXLException; import jxl.Workbook; -import jxl.write.DateTime; +import jxl.format.Font; import jxl.write.Label; import jxl.write.WritableCell; +import jxl.write.WritableCellFormat; +import jxl.write.WritableFont; import jxl.write.WritableSheet; import jxl.write.WritableWorkbook; @@ -69,6 +74,10 @@ */ public class FileUtil { + public static final String ENCODING_UTF_8 = "UTF-8"; + public static final String EXPORT_TO_SPREADSHEET_TITLE_DATE_FORMAT = "dd.MM.yyyy h a"; + public static final String EXPORT_TO_SPREADSHEET_CELL_DATE_FORMAT = "dd.MM.yyyy"; + private static Logger log = Logger.getLogger(FileUtil.class); public static final String LAMS_WWW_SECURE_DIR = "secure"; @@ -624,11 +633,11 @@ if (null != agent && -1 != agent.indexOf("MSIE")) { // if MSIE then urlencode it - filename = URLEncoder.encode(unEncodedFilename, "UTF-8"); + filename = URLEncoder.encode(unEncodedFilename, FileUtil.ENCODING_UTF_8); } else if (null != agent && -1 != agent.indexOf("Mozilla")) { // if Mozilla then base64 url_safe encoding - filename = MimeUtility.encodeText(unEncodedFilename, "UTF-8", "B"); + filename = MimeUtility.encodeText(unEncodedFilename, FileUtil.ENCODING_UTF_8, "B"); } else { // any others use same filename. @@ -696,7 +705,7 @@ } numTries++; - file = new InputStreamReader(new FileInputStream(fullFilePath), "UTF-8"); + file = new InputStreamReader(new FileInputStream(fullFilePath), FileUtil.ENCODING_UTF_8); return conversionXml.fromXML(file); } catch (ConversionException ce) { @@ -774,39 +783,73 @@ } } - public static void exportToExcel(OutputStream out, String sheetName, String title, String dateHeader, + /** + * Exports data in MS Excel (.xls) format. + * + * @param out + * output stream to which the file written; usually taken from HTTP response; it is not closed + * afterwards + * @param sheetName + * name of first sheet in Excel workbook; data will be stored in this sheet + * @param title + * title printed in the first (0,0) cell + * @param dateHeader + * text describing current date; if NULL then no date is printed; if not + * NULL then text is written out along with current date in the cell; the date is + * formatted according to {@link #EXPORT_TO_SPREADSHEET_TITLE_DATE_FORMAT} + * @param columnNames + * name of the columns that describe data parameter + * @param data + * array of data to print out; first index of array describes a row, second a column; dates are + * formatted according to {@link #EXPORT_TO_SPREADSHEET_CELL_DATE_FORMAT} + * @throws IOException + * @throws JXLException + */ + public static void exportToolToExcel(OutputStream out, String sheetName, String title, String dateHeader, String[] columnNames, Object[][] data) throws IOException, JXLException { WritableWorkbook workbook = Workbook.createWorkbook(out); WritableSheet sheet = workbook.createSheet(sheetName, 0); - if (!StringUtils.isEmpty(title)) { - sheet.addCell(new Label(0, 0, title)); + // Prepare cell formatter used in all columns + CellView stretchedCellView = new CellView(); + stretchedCellView.setAutosize(true); + // Pring title in bold, if needed + if (!StringUtils.isBlank(title)) { + Label titleCell = new Label(0, 0, title); + Font font = titleCell.getCellFormat().getFont(); + WritableFont titleFont = new WritableFont(font); + titleFont.setBoldStyle(WritableFont.BOLD); + WritableCellFormat titleCellFormat = new WritableCellFormat(titleFont); + titleCell.setCellFormat(titleCellFormat); + sheet.addCell(titleCell); } - if (!StringUtils.isEmpty(dateHeader)) { + // Print current date, if needed + if (!StringUtils.isBlank(dateHeader)) { sheet.addCell(new Label(0, 1, dateHeader)); - sheet.addCell(new DateTime(1, 1, new Date())); + SimpleDateFormat titleDateFormat = new SimpleDateFormat(FileUtil.EXPORT_TO_SPREADSHEET_TITLE_DATE_FORMAT); + sheet.addCell(new Label(1, 1, titleDateFormat.format(new Date()))); } + // Print column names, if needed if (columnNames != null) { for (int columnIndex = 0; columnIndex < columnNames.length; columnIndex++) { sheet.addCell(new Label(columnIndex, 3, columnNames[columnIndex])); + sheet.setColumnView(columnIndex, stretchedCellView); } } + SimpleDateFormat cellDateFormat = new SimpleDateFormat(FileUtil.EXPORT_TO_SPREADSHEET_CELL_DATE_FORMAT); + Calendar calendar = Calendar.getInstance(); if (data != null) { - for (int columnIndex = 0; columnIndex < data.length; columnIndex++) { - for (int rowIndex = 0; rowIndex < data[columnIndex].length; rowIndex++) { - Object content = data[columnIndex][rowIndex]; + // Print data + for (int rowIndex = 0; rowIndex < data.length; rowIndex++) { + int sheetRowIndex = rowIndex + 4; + for (int columnIndex = 0; columnIndex < data[rowIndex].length; columnIndex++) { + Object content = data[rowIndex][columnIndex]; if (content != null) { WritableCell cell = null; - if (content instanceof Number) { - Number number = (Number) content; - cell = new jxl.write.Number(columnIndex, rowIndex, number.doubleValue()); - } else if (content instanceof Date) { + if (content instanceof Date) { Date date = (Date) content; - cell = new DateTime(columnIndex, rowIndex, date); - } else if (content instanceof Boolean) { - Boolean bool = (Boolean) content; - cell = new jxl.write.Boolean(columnIndex, rowIndex, bool); + cell = new Label(columnIndex, sheetRowIndex, cellDateFormat.format(date)); } else { - cell = new Label(columnIndex, rowIndex, content.toString()); + cell = new Label(columnIndex, sheetRowIndex, content.toString()); } sheet.addCell(cell); } @@ -817,31 +860,63 @@ workbook.close(); } - public static void exportToCSV(OutputStream out, String title, String dateHeader, String[] columnNames, + /** + * Exports data in CSV format. It uses UTF-8 character set and semicolon as separator. + * + * @param out + * output stream to which the file written; usually taken from HTTP response; it is not closed + * afterwards + * @param title + * title printed in the first (0,0) cell + * @param dateHeader + * text describing current date; if NULL then no date is printed; if not + * NULL then text is written out along with current date in the cell; the date is + * formatted according to {@link #EXPORT_TO_SPREADSHEET_TITLE_DATE_FORMAT} + * @param columnNames + * name of the columns that describe data parameter + * @param data + * array of data to print out; first index of array describes a row, second a column; dates are + * formatted according to {@link #EXPORT_TO_SPREADSHEET_CELL_DATE_FORMAT} + * @throws IOException + */ + public static void exportToolToCSV(OutputStream out, String title, String dateHeader, String[] columnNames, Object[][] data) throws IOException { - Writer writer = new OutputStreamWriter(out); - CSVWriter csv = new CSVWriter(writer); + Writer writer = new OutputStreamWriter(out, FileUtil.ENCODING_UTF_8); + CSVWriter csv = new CSVWriter(writer, ';'); String[] line = null; - if (!StringUtils.isEmpty(title)) { + // Print title, if needed + if (!StringUtils.isBlank(title)) { line = new String[] { title }; csv.writeNext(line); } - if (!StringUtils.isEmpty(dateHeader)) { - line = new String[] { dateHeader, new Date().toString() }; + // Print current date,if needed + if (!StringUtils.isBlank(dateHeader)) { + String date = new SimpleDateFormat(FileUtil.EXPORT_TO_SPREADSHEET_TITLE_DATE_FORMAT).format(new Date()); + line = new String[] { dateHeader, date }; csv.writeNext(line); } + // Separator + line = new String[] {}; + csv.writeNext(line); + + // Print column names, if needed if (columnNames != null) { - line = new String[] {}; - csv.writeNext(line); csv.writeNext(columnNames); } + SimpleDateFormat cellDateFormat = new SimpleDateFormat(FileUtil.EXPORT_TO_SPREADSHEET_CELL_DATE_FORMAT); + // Print data if (data != null) { - for (int columnIndex = 0; columnIndex < data.length; columnIndex++) { - line = new String[data[columnIndex].length]; - for (int rowIndex = 0; rowIndex < data[columnIndex].length; rowIndex++) { - Object content = data[columnIndex][rowIndex]; + for (int rowIndex = 0; rowIndex < data.length; rowIndex++) { + line = new String[data[rowIndex].length]; + for (int columnIndex = 0; columnIndex < line.length; columnIndex++) { + Object content = data[rowIndex][columnIndex]; if (content != null) { - line[rowIndex] = content.toString(); + if (content instanceof Date) { + Date date = (Date) content; + line[columnIndex] = cellDateFormat.format(date); + } else { + line[columnIndex] = content.toString(); + } } } csv.writeNext(line); Index: lams_tool_daco/build.properties =================================================================== diff -u -r955a2a0ed552a7c8e8ffd9894cac59233e56747e -rd76e13fea785246cc091078e2b8eb460cc7bf342 --- lams_tool_daco/build.properties (.../build.properties) (revision 955a2a0ed552a7c8e8ffd9894cac59233e56747e) +++ lams_tool_daco/build.properties (.../build.properties) (revision d76e13fea785246cc091078e2b8eb460cc7bf342) @@ -13,7 +13,7 @@ weblib=lib #project version -tool.version=20081114 +tool.version=20090326 # hide tool option hideTool=false Index: lams_tool_daco/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -r2fe2f7285feec62a72f6bf7006b276938efc3071 -rd76e13fea785246cc091078e2b8eb460cc7bf342 --- lams_tool_daco/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 2fe2f7285feec62a72f6bf7006b276938efc3071) +++ lams_tool_daco/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision d76e13fea785246cc091078e2b8eb460cc7bf342) @@ -252,5 +252,16 @@ output.desc.learner.number.of.posts =Learner's number of records message.authoring.delete.question =Are you sure you want to delete this question? +title.export.spreadsheet=Export to file +label.export.spreadsheet.instruction =Please choose format which you want to export +label.export.spreadsheet.choose.format.excel=MS Excel +label.export.spreadsheet.choose.format.csv=CSV (character set: UTF-8, separator: semicolon ";") +button.export =Export +label.export.spreadsheet.instruction.continue=and press export button.\nAfter successful export you may close this window. +label.export.file.title=Data Collection Export +label.export.file.date=Exported on +label.export.file.sheet=Tool content +label.export.file.user=Learner +label.export.file.answer.date=Added on #======= End labels: Exported 245 labels for en AU ===== Index: lams_tool_daco/conf/language/lams/ApplicationResources_en_AU.properties =================================================================== diff -u -r2fe2f7285feec62a72f6bf7006b276938efc3071 -rd76e13fea785246cc091078e2b8eb460cc7bf342 --- lams_tool_daco/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision 2fe2f7285feec62a72f6bf7006b276938efc3071) +++ lams_tool_daco/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision d76e13fea785246cc091078e2b8eb460cc7bf342) @@ -252,5 +252,15 @@ output.desc.learner.number.of.posts =Learner's number of records message.authoring.delete.question =Are you sure you want to delete this question? - +title.export.spreadsheet=Export to file +label.export.spreadsheet.instruction =Please choose format which you want to export +label.export.spreadsheet.choose.format.excel=MS Excel +label.export.spreadsheet.choose.format.csv=CSV (character set: UTF-8, separator: semicolon ";") +button.export =Export +label.export.spreadsheet.instruction.continue=and press export button.\nAfter successful export you may close this window. +label.export.file.title=Data Collection Export +label.export.file.date=Exported on +label.export.file.sheet=Tool content +label.export.file.user=Learner +label.export.file.answer.date=Added on #======= End labels: Exported 245 labels for en AU ===== Index: lams_tool_daco/conf/xdoclet/struts-actions.xml =================================================================== diff -u -r3bdebf472590492a1e54e2495e1b566449e5ea4a -rd76e13fea785246cc091078e2b8eb460cc7bf342 --- lams_tool_daco/conf/xdoclet/struts-actions.xml (.../struts-actions.xml) (revision 3bdebf472590492a1e54e2495e1b566449e5ea4a) +++ lams_tool_daco/conf/xdoclet/struts-actions.xml (.../struts-actions.xml) (revision d76e13fea785246cc091078e2b8eb460cc7bf342) @@ -158,5 +158,9 @@ + + + Index: lams_tool_daco/db/sql/create_lams_tool_daco.sql =================================================================== diff -u -ra8e7e92f2121c4b307fb49d28008a5828ad58c58 -rd76e13fea785246cc091078e2b8eb460cc7bf342 --- lams_tool_daco/db/sql/create_lams_tool_daco.sql (.../create_lams_tool_daco.sql) (revision a8e7e92f2121c4b307fb49d28008a5828ad58c58) +++ lams_tool_daco/db/sql/create_lams_tool_daco.sql (.../create_lams_tool_daco.sql) (revision d76e13fea785246cc091078e2b8eb460cc7bf342) @@ -89,17 +89,19 @@ PRIMARY KEY (uid) )TYPE=innodb; -CREATE TABLE tl_ladaco10_answers -(uid bigint NOT NULL UNIQUE auto_increment, -user_uid bigint, -question_uid bigint, -record_id smallint unsigned, -answer text, +CREATE TABLE tl_ladaco10_answers ( + uid bigint NOT NULL UNIQUE auto_increment, + user_uid bigint, + question_uid bigint, + record_id smallint unsigned, + answer text, file_type varchar(255), file_name varchar(255), file_uuid bigint, file_version_id bigint, -PRIMARY KEY (uid)) TYPE=innodb; + create_date datetime, + PRIMARY KEY (uid) +)TYPE=innodb; ALTER TABLE tl_ladaco10_attachments ADD INDEX (content_uid), ADD CONSTRAINT FOREIGN KEY (content_uid) REFERENCES tl_ladaco10_contents (uid); ALTER TABLE tl_ladaco10_contents ADD INDEX (create_by), ADD CONSTRAINT DacoToUser FOREIGN KEY (create_by) REFERENCES tl_ladaco10_users (uid); Index: lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/DacoConstants.java =================================================================== diff -u -r955a2a0ed552a7c8e8ffd9894cac59233e56747e -rd76e13fea785246cc091078e2b8eb460cc7bf342 --- lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/DacoConstants.java (.../DacoConstants.java) (revision 955a2a0ed552a7c8e8ffd9894cac59233e56747e) +++ lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/DacoConstants.java (.../DacoConstants.java) (revision d76e13fea785246cc091078e2b8eb460cc7bf342) @@ -288,4 +288,28 @@ public static final String PAGE_EDITABLE = "isPageEditable"; public final static String LEARNER_NUM_POSTS_DEFINITION_NAME = "learner.number.of.posts"; + + // for export to spreadsheet + + public static final String EXPORT_TO_SPREADSHEET_FILE_NAME = "Data_Collection_Export"; + + public static final String PARAM_FORMAT = "format"; + + public static final String KEY_LABEL_EXPORT_FILE_SHEET = "label.export.file.sheet"; + + public static final String KEY_LABEL_LEARNING_LONGLAT_LATITUDE_UNIT = "label.learning.longlat.latitude.unit"; + + public static final String KEY_LABEL_LEARNING_LONGLAT_LATITUDE = "label.learning.longlat.latitude"; + + public static final String KEY_LABEL_LEARNING_LONGLAT_LONGITUDE_UNIT = "label.learning.longlat.longitude.unit"; + + public static final String KEY_LABEL_LEARNING_LONGLAT_LONGITUDE = "label.learning.longlat.longitude"; + + public static final String KEY_LABEL_EXPORT_FILE_USER = "label.export.file.user"; + + public static final String KEY_LABEL_EXPORT_FILE_DATE = "label.export.file.date"; + + public static final String KEY_LABEL_EXPORT_FILE_TITLE = "label.export.file.title"; + + public static final String KEY_LABEL_EXPORT_FILE_ANSWER_DATE = "label.export.file.answer.date"; } \ No newline at end of file Index: lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/dbupdates/patch20090326_updateFrom22.sql =================================================================== diff -u --- lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/dbupdates/patch20090326_updateFrom22.sql (revision 0) +++ lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/dbupdates/patch20090326_updateFrom22.sql (revision d76e13fea785246cc091078e2b8eb460cc7bf342) @@ -0,0 +1,14 @@ +-- SQL statements to update from LAMS 2.2 + +-- Turn off autocommit, so nothing is committed if there is an error +SET AUTOCOMMIT = 0; + +----------------------Put all sql statements below here------------------------- + +ALTER TABLE tl_ladaco10_answers ADD COLUMN create_date datetime; + +---Put all sql statements above here------------------------- + +-- If there were no errors, commit and restore autocommit to on +COMMIT; +SET AUTOCOMMIT = 1; \ No newline at end of file Index: lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/model/DacoAnswer.java =================================================================== diff -u -r9aa7e24878b41bd6baffa35e83ef392e670811c3 -rd76e13fea785246cc091078e2b8eb460cc7bf342 --- lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/model/DacoAnswer.java (.../DacoAnswer.java) (revision 9aa7e24878b41bd6baffa35e83ef392e670811c3) +++ lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/model/DacoAnswer.java (.../DacoAnswer.java) (revision d76e13fea785246cc091078e2b8eb460cc7bf342) @@ -22,6 +22,8 @@ */ package org.lamsfoundation.lams.tool.daco.model; +import java.util.Date; + import org.apache.log4j.Logger; /** @@ -32,148 +34,160 @@ * @hibernate.class table="tl_ladaco10_answers" */ public class DacoAnswer implements Cloneable { - private static final Logger log = Logger.getLogger(DacoQuestion.class); + private static final Logger log = Logger.getLogger(DacoQuestion.class); - private Long uid; + private Long uid; - private DacoUser user; + private DacoUser user; - private Integer recordId; + private Integer recordId; - private String answer; + private String answer; - private DacoQuestion question; + private DacoQuestion question; - private Long fileUuid; + private Long fileUuid; - private Long fileVersionId; + private Long fileVersionId; - private String fileName; + private String fileName; - private String fileType; + private String fileType; - @Override - public Object clone() { - DacoAnswer cloned = null; - try { - cloned = (DacoAnswer) super.clone(); - cloned.setUid(null); - } - catch (CloneNotSupportedException e) { - DacoAnswer.log.error("Cloning " + DacoQuestion.class + " failed"); - } + private Date createDate; - return cloned; + @Override + public Object clone() { + DacoAnswer cloned = null; + try { + cloned = (DacoAnswer) super.clone(); + cloned.setUid(null); + } catch (CloneNotSupportedException e) { + DacoAnswer.log.error("Cloning " + DacoQuestion.class + " failed"); } - // ********************************************************** - // Get/Set methods - // ********************************************************** + return cloned; + } - /** - * @hibernate.id generator-class="native" type="java.lang.Long" column="uid" - * @return Returns the answer ID. - */ - public Long getUid() { - return uid; - } + // ********************************************************** + // Get/Set methods + // ********************************************************** - public void setUid(Long uuid) { - uid = uuid; - } + /** + * @hibernate.id generator-class="native" type="java.lang.Long" column="uid" + * @return Returns the answer ID. + */ + public Long getUid() { + return uid; + } - /** - * @hibernate.many-to-one column="user_uid" cascade="none" foreign-key="AnswerToUser" - * @return - */ - public DacoUser getUser() { - return user; - } + public void setUid(Long uuid) { + uid = uuid; + } - public void setUser(DacoUser user) { - this.user = user; - } + /** + * @hibernate.many-to-one column="user_uid" cascade="none" foreign-key="AnswerToUser" + * @return + */ + public DacoUser getUser() { + return user; + } - /** - * @hibernate.property column="record_id" - * @return Returns the record ID. - */ - public Integer getRecordId() { - return recordId; - } + public void setUser(DacoUser user) { + this.user = user; + } - public void setRecordId(Integer recordId) { - this.recordId = recordId; - } + /** + * @hibernate.property column="record_id" + * @return Returns the record ID. + */ + public Integer getRecordId() { + return recordId; + } - /** - * @hibernate.property column="answer" - * @return Returns the answer. - */ - public String getAnswer() { - return answer; - } + public void setRecordId(Integer recordId) { + this.recordId = recordId; + } - public void setAnswer(String answer) { - this.answer = answer; - } + /** + * @hibernate.property column="answer" + * @return Returns the answer. + */ + public String getAnswer() { + return answer; + } - /** - * @hibernate.many-to-one column="question_uid" cascade="none" foreign-key="AnswerToQuestion" - * @return - */ - public DacoQuestion getQuestion() { - return question; - } + public void setAnswer(String answer) { + this.answer = answer; + } - public void setQuestion(DacoQuestion question) { - this.question = question; - } + /** + * @hibernate.many-to-one column="question_uid" cascade="none" foreign-key="AnswerToQuestion" + * @return + */ + public DacoQuestion getQuestion() { + return question; + } - /** - * @hibernate.property column="file_uuid" - * - * @return - */ - public Long getFileUuid() { - return fileUuid; - } + public void setQuestion(DacoQuestion question) { + this.question = question; + } - public void setFileUuid(Long crUuid) { - fileUuid = crUuid; - } + /** + * @hibernate.property column="file_uuid" + * + * @return + */ + public Long getFileUuid() { + return fileUuid; + } - /** - * @hibernate.property column="file_version_id" - * @return - */ - public Long getFileVersionId() { - return fileVersionId; - } + public void setFileUuid(Long crUuid) { + fileUuid = crUuid; + } - public void setFileVersionId(Long crVersionId) { - fileVersionId = crVersionId; - } + /** + * @hibernate.property column="file_version_id" + * @return + */ + public Long getFileVersionId() { + return fileVersionId; + } - /** - * @hibernate.property column="file_type" - */ - public String getFileType() { - return fileType; - } + public void setFileVersionId(Long crVersionId) { + fileVersionId = crVersionId; + } - public void setFileType(String type) { - fileType = type; - } + /** + * @hibernate.property column="file_type" + */ + public String getFileType() { + return fileType; + } - /** - * @hibernate.property column="file_name" - */ - public String getFileName() { - return fileName; - } + public void setFileType(String type) { + fileType = type; + } - public void setFileName(String name) { - fileName = name; - } + /** + * @hibernate.property column="file_name" + */ + public String getFileName() { + return fileName; + } + + public void setFileName(String name) { + fileName = name; + } + + /** + * @hibernate.property column="create_date" + */ + public Date getCreateDate() { + return createDate; + } + + public void setCreateDate(Date createDate) { + this.createDate = createDate; + } } \ No newline at end of file Index: lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/web/action/LearningAction.java =================================================================== diff -u -r874dc94c4844b91d40cb30d79e4d0de3a40bfe43 -rd76e13fea785246cc091078e2b8eb460cc7bf342 --- lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/web/action/LearningAction.java (.../LearningAction.java) (revision 874dc94c4844b91d40cb30d79e4d0de3a40bfe43) +++ lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/web/action/LearningAction.java (.../LearningAction.java) (revision d76e13fea785246cc091078e2b8eb460cc7bf342) @@ -361,6 +361,7 @@ answer.setRecordId(displayedRecordNumber); answer.setUser(user); } + answer.setCreateDate(new Date()); switch (question.getType()) { case DacoConstants.QUESTION_TYPE_NUMBER: { Index: lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/web/action/MonitoringAction.java =================================================================== diff -u -ra3cbfca2faad29605192470bb2bb1ec21b0344f6 -rd76e13fea785246cc091078e2b8eb460cc7bf342 --- lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision a3cbfca2faad29605192470bb2bb1ec21b0344f6) +++ lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision d76e13fea785246cc091078e2b8eb460cc7bf342) @@ -25,13 +25,21 @@ package org.lamsfoundation.lams.tool.daco.web.action; import java.io.IOException; +import java.text.ParseException; +import java.util.Date; +import java.util.LinkedList; import java.util.List; +import java.util.Set; import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import jxl.JXLException; + +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; @@ -44,9 +52,14 @@ import org.lamsfoundation.lams.tool.daco.dto.MonitoringSummaryUserDTO; import org.lamsfoundation.lams.tool.daco.dto.QuestionSummaryDTO; import org.lamsfoundation.lams.tool.daco.model.Daco; +import org.lamsfoundation.lams.tool.daco.model.DacoAnswer; +import org.lamsfoundation.lams.tool.daco.model.DacoAnswerOption; +import org.lamsfoundation.lams.tool.daco.model.DacoQuestion; import org.lamsfoundation.lams.tool.daco.model.DacoUser; import org.lamsfoundation.lams.tool.daco.service.IDacoService; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.util.CentralConstants; +import org.lamsfoundation.lams.util.FileUtil; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; @@ -59,7 +72,7 @@ @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException { + HttpServletResponse response) throws IOException, ServletException, JXLException, ParseException { String param = mapping.getParameter(); if (param.equals("summary")) { @@ -75,6 +88,9 @@ if (param.equals("changeView")) { return changeView(mapping, request); } + if (param.equals("exportToSpreadsheet")) { + return exportToSpreadsheet(request, response); + } return mapping.findForward(DacoConstants.ERROR); } @@ -195,4 +211,175 @@ } return mapping.findForward(DacoConstants.SUCCESS); } + + /** + * Exports all learners' data to an Excel or CSV file. + * + * @param request + * @param response + * @return + * @throws IOException + * @throws JXLException + * @throws ParseException + */ + protected ActionForward exportToSpreadsheet(HttpServletRequest request, HttpServletResponse response) + throws IOException, JXLException, ParseException { + // Get required parameters + String sessionMapID = request.getParameter(DacoConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + Daco daco = (Daco) sessionMap.get(DacoConstants.ATTR_DACO); + int format = WebUtil.readIntParam(request, DacoConstants.PARAM_FORMAT); + IDacoService service = getDacoService(); + + // Prepare headers and column names + String title = service.getLocalisedMessage(DacoConstants.KEY_LABEL_EXPORT_FILE_TITLE, null); + String dateHeader = service.getLocalisedMessage(DacoConstants.KEY_LABEL_EXPORT_FILE_DATE, null); + + Set questions = daco.getDacoQuestions(); + // First two columns are "user" and date when was the answer added + int columnIndex = 2; + String[] columnNames = new String[questions.size() + 2]; + short[] questionTypes = new short[questions.size()]; + columnNames[0] = service.getLocalisedMessage(DacoConstants.KEY_LABEL_EXPORT_FILE_USER, null); + columnNames[1] = service.getLocalisedMessage(DacoConstants.KEY_LABEL_EXPORT_FILE_ANSWER_DATE, null); + for (DacoQuestion question : questions) { + columnNames[columnIndex] = WebUtil.removeHTMLtags(question.getDescription()); + questionTypes[columnIndex - 2] = question.getType(); + columnIndex++; + } + + // Some strings used in building cell values + String longitudeHeader = service.getLocalisedMessage(DacoConstants.KEY_LABEL_LEARNING_LONGLAT_LONGITUDE, null); + String longitudeUnit = service.getLocalisedMessage(DacoConstants.KEY_LABEL_LEARNING_LONGLAT_LONGITUDE_UNIT, + null); + String latitudeHeader = service.getLocalisedMessage(DacoConstants.KEY_LABEL_LEARNING_LONGLAT_LATITUDE, null); + String latitudeUnit = service.getLocalisedMessage(DacoConstants.KEY_LABEL_LEARNING_LONGLAT_LATITUDE_UNIT, null); + + List rows = new LinkedList(); + // We get all sessions with all users with all their records from the given Daco content + List monitoringSummary = service.getMonitoringSummary(daco.getContentId(), null); + for (MonitoringSummarySessionDTO summarySession : monitoringSummary) { + // Maybe we'll need delimiter between sessions one day - here is the place to add an empty row + for (MonitoringSummaryUserDTO user : summarySession.getUsers()) { + List> records = user.getRecords(); + for (int rowIndex = 0; rowIndex < records.size(); rowIndex++) { + Object[] row = new Object[questions.size() + 2]; + row[0] = user.getFullName(); + + List record = records.get(rowIndex); + columnIndex = 2; + for (int answerIndex = 0; answerIndex < record.size(); answerIndex++) { + DacoAnswer answer = record.get(answerIndex); + // we set the date of the whole row to the latest from all the participating answers + if (row[1] == null) { + row[1] = answer.getCreateDate(); + } else { + Date currentDate = (Date) row[1]; + Date newDate = answer.getCreateDate(); + if (currentDate.compareTo(newDate) < 0) { + row[1] = newDate; + } + } + Object cell = null; + String answerString = answer.getAnswer(); + // we extract answers and add them to "data" array in readable form + switch (questionTypes[columnIndex - 2]) { + case DacoConstants.QUESTION_TYPE_DATE: + if (!StringUtils.isBlank(answerString)) { + cell = DacoConstants.DEFAULT_DATE_FORMAT.parse(answerString); + } + break; + case DacoConstants.QUESTION_TYPE_CHECKBOX: + if (!StringUtils.isBlank(answerString)) { + DacoQuestion question = answer.getQuestion(); + DacoQuestion currentQuestion = question; + List answerOptions = new LinkedList(question + .getAnswerOptions()); + StringBuilder cellStringBuilder = new StringBuilder(); + // instead of number, we create a comma-separated string of chosen options + do { + int chosenAnswer = Integer.parseInt(answerString) - 1; + String chosenAnswerOption = answerOptions.get(chosenAnswer).getAnswerOption(); + cellStringBuilder.append(chosenAnswerOption).append(", "); + answerIndex++; + answer = record.get(answerIndex); + currentQuestion = answer.getQuestion(); + answerString = answer.getAnswer(); + } while (currentQuestion.equals(question)); + // we went one answer too far, so we go back + answerIndex--; + cell = cellStringBuilder.delete(cellStringBuilder.length() - 2, + cellStringBuilder.length()).toString(); + } + break; + case DacoConstants.QUESTION_TYPE_LONGLAT: + // Both longitude and latitude go in the same cell + if (StringUtils.isBlank(answerString)) { + // If longitude was not entered, then latitude also is blank, so skip the next answer + answerIndex++; + } else { + StringBuilder cellStringBuilder = new StringBuilder(longitudeHeader).append(' ') + .append(answerString).append(' ').append(longitudeUnit).append("; "); + answerIndex++; + answer = record.get(answerIndex); + cellStringBuilder.append(latitudeHeader).append(' ').append(answer.getAnswer()).append( + ' ').append(latitudeUnit); + cell = cellStringBuilder.toString(); + } + break; + case DacoConstants.QUESTION_TYPE_FILE: + case DacoConstants.QUESTION_TYPE_IMAGE: + if (!StringUtils.isBlank(answer.getFileName())) { + // Just get the file name, instead of the real file + cell = answer.getFileName(); + } + break; + case DacoConstants.QUESTION_TYPE_RADIO: + case DacoConstants.QUESTION_TYPE_DROPDOWN: + if (!StringUtils.isBlank(answerString)) { + List answerOptions = new LinkedList(answer + .getQuestion().getAnswerOptions()); + int chosenAnswer = Integer.parseInt(answerString) - 1; + cell = answerOptions.get(chosenAnswer).getAnswerOption(); + } + break; + default: + cell = answer.getAnswer(); + break; + } + row[columnIndex] = cell; + columnIndex++; + } + rows.add(row); + } + + } + } + // Convert from Collection to array + Object[][] data = rows.toArray(new Object[][] {}); + + // Prepare response headers + String fileName = DacoConstants.EXPORT_TO_SPREADSHEET_FILE_NAME + + (format == 1 ? CentralConstants.FILE_EXTENSION_XLS : CentralConstants.FILE_EXTENSION_CSV); + fileName = FileUtil.encodeFilenameForDownload(request, fileName); + response.setContentType(CentralConstants.RESPONSE_CONTENT_TYPE_DOWNLOAD); + response.setHeader(CentralConstants.HEADER_CONTENT_DISPOSITION, CentralConstants.HEADER_CONTENT_ATTACHMENT + + fileName); + MonitoringAction.log.debug("Exporting to a spreadsheet tool content with UID: " + daco.getUid()); + ServletOutputStream out = response.getOutputStream(); + + switch (format) { + case 1: + // Export to XLS + String sheetName = service.getLocalisedMessage(DacoConstants.KEY_LABEL_EXPORT_FILE_SHEET, null); + FileUtil.exportToolToExcel(out, sheetName, title, dateHeader, columnNames, data); + break; + case 2: + // Export to CSV + FileUtil.exportToolToCSV(out, title, dateHeader, columnNames, data); + break; + } + // Return the file inside response, but not any JSP page + return null; + } } Index: lams_tool_daco/web/pages/export/exportToSpreadsheet.jsp =================================================================== diff -u --- lams_tool_daco/web/pages/export/exportToSpreadsheet.jsp (revision 0) +++ lams_tool_daco/web/pages/export/exportToSpreadsheet.jsp (revision d76e13fea785246cc091078e2b8eb460cc7bf342) @@ -0,0 +1,51 @@ +<%@ page language="java" pageEncoding="UTF-8" contentType="text/html;charset=utf-8" %> +<%@ include file="/common/taglibs.jsp"%> + + + + + <fmt:message key="title.export.spreadsheet" /> + + + + + + +
+

+ +

+ + + + + + + +
+ +

+
+ +
+

+ +

+
+
+ + +
+ +
+ + +
\ No newline at end of file Index: lams_tool_daco/web/pages/monitoring/summary.jsp =================================================================== diff -u -r144da09f649cddf30dcbc362f0ac094e6a58c50d -rd76e13fea785246cc091078e2b8eb460cc7bf342 --- lams_tool_daco/web/pages/monitoring/summary.jsp (.../summary.jsp) (revision 144da09f649cddf30dcbc362f0ac094e6a58c50d) +++ lams_tool_daco/web/pages/monitoring/summary.jsp (.../summary.jsp) (revision d76e13fea785246cc091078e2b8eb460cc7bf342) @@ -206,5 +206,11 @@ + + + + + +

\ No newline at end of file