Skip to content
Snippets Groups Projects
Commit ccc6d731 authored by uhensler's avatar uhensler
Browse files

OO-3181: Evaluation form elemnent for file upload

parent 128f3136
No related branches found
No related tags found
No related merge requests found
Showing
with 773 additions and 144 deletions
......@@ -88,10 +88,19 @@ public interface FileElement extends FormMultipartItem {
/**
* Preview is possible only for images.
*
* @param usess
* @param enable
*/
public void setPreview(UserSession usess, boolean enable);
/**
* Enable or disable whether the upload and delete buttons are active. Disabled
* buttons are an alternative to the disabling of the whole element.
*
* @param enable
*/
public void setButtonsEnabled(boolean enable);
public void setCropSelectionEnabled(boolean enable);
/**
......
......@@ -24,7 +24,6 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.text.Normalizer;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
......@@ -94,6 +93,7 @@ public class FileElementImpl extends FormItemImpl
private String uploadFilename;
private String uploadMimeType;
private boolean buttonsEnabled = true;
private boolean deleteEnabled;
private boolean confirmDelete;
......@@ -126,9 +126,6 @@ public class FileElementImpl extends FormItemImpl
setElementCssClass(null); // trigger default css
}
/**
* @see org.olat.core.gui.components.form.flexible.impl.FormItemImpl#evalFormRequest(org.olat.core.gui.UserRequest)
*/
@Override
public void evalFormRequest(UserRequest ureq) {
Form form = getRootForm();
......@@ -166,7 +163,7 @@ public class FileElementImpl extends FormItemImpl
uploadFilename = form.getRequestMultipartFileName(component.getFormDispatchId());
// prevent an issue with Firefox
uploadFilename = Normalizer.normalize(uploadFilename, Normalizer.Form.NFKC);
uploadFilename = FileUtils.normalizeFilenameWithSuffix(uploadFilename);
// use mime-type from file name to have deterministic mime types
uploadMimeType = WebappHelper.getMimeType(uploadFilename);
if (uploadMimeType == null) {
......@@ -224,9 +221,6 @@ public class FileElementImpl extends FormItemImpl
return null;
}
/**
* @see org.olat.core.gui.components.form.flexible.impl.FormItemImpl#getFormItemComponent()
*/
@Override
protected Component getFormItemComponent() {
return component;
......@@ -236,9 +230,6 @@ public class FileElementImpl extends FormItemImpl
return previewEl;
}
/**
* @see org.olat.core.gui.components.form.flexible.impl.FormItemImpl#reset()
*/
@Override
public void reset() {
if (tempUploadFile != null && tempUploadFile.exists()) {
......@@ -259,9 +250,6 @@ public class FileElementImpl extends FormItemImpl
uploadMimeType = null;
}
/**
* @see org.olat.core.gui.components.form.flexible.impl.FormItemImpl#rootFormAvailable()
*/
@Override
protected void rootFormAvailable() {
if (previewEl != null && previewEl.getRootForm() != getRootForm()) {
......@@ -269,19 +257,12 @@ public class FileElementImpl extends FormItemImpl
}
}
/**
* @see org.olat.core.gui.components.form.flexible.elements.FileElement#setMandatory(boolean,
* java.lang.String)
*/
@Override
public void setMandatory(boolean mandatory, String i18nErrKey) {
super.setMandatory(mandatory);
this.i18nErrMandatory = i18nErrKey;
}
/**
* @see org.olat.core.gui.components.form.flexible.impl.FormItemImpl#validate(java.util.List)
*/
@Override
public void validate(List<ValidationStatus> validationResults) {
int lastFormError = getRootForm().getLastRequestError();
......@@ -315,7 +296,7 @@ public class FileElementImpl extends FormItemImpl
} else if (checkForMimeTypes && tempUploadFile != null && tempUploadFile.exists()) {
boolean found = false;
if (uploadMimeType != null) {
for (String validType : mimeTypes) {
for (String validType : getMimeTypeLimitations()) {
if (validType.equals(uploadMimeType)) {
// exact match: image/jpg
found = true;
......@@ -367,14 +348,20 @@ public class FileElementImpl extends FormItemImpl
}
}
public boolean isButtonsEnabled() {
return buttonsEnabled;
}
@Override
public void setButtonsEnabled(boolean buttonsEnabled) {
this.buttonsEnabled = buttonsEnabled;
}
@Override
public void setCropSelectionEnabled(boolean enable) {
this.cropSelectionEnabled = enable;
}
/**
* @see org.olat.core.gui.components.form.flexible.elements.FileElement#setInitialFile(java.io.File)
*/
@Override
public void setInitialFile(File initialFile) {
this.initialFile = initialFile;
......@@ -388,37 +375,32 @@ public class FileElementImpl extends FormItemImpl
}
}
/**
* @see org.olat.core.gui.components.form.flexible.elements.FileElement#getInitialFile()
*/
@Override
public File getInitialFile() {
return initialFile;
}
/**
* @see org.olat.core.gui.components.form.flexible.elements.FileElement#limitToMimeType(java.util.Set,
* java.lang.String, java.lang.String[])
*/
@Override
public void limitToMimeType(Set<String> mimeTypes, String i18nErrKey, String[] i18nArgs) {
this.mimeTypes = mimeTypes;
this.checkForMimeTypes = true;
if (mimeTypes != null) {
this.mimeTypes = mimeTypes;
this.checkForMimeTypes = true;
} else {
this.mimeTypes = new HashSet<>();
this.checkForMimeTypes = false;
}
this.i18nErrMimeType = i18nErrKey;
this.i18nErrMimeTypeArgs = i18nArgs;
}
/**
* @see org.olat.core.gui.components.form.flexible.elements.FileElement#getMimeTypeLimitations()
*/
@Override
public Set<String> getMimeTypeLimitations() {
if (mimeTypes == null)
mimeTypes = new HashSet<String>();
mimeTypes = new HashSet<>();
return mimeTypes;
}
/**
* @see org.olat.core.gui.components.form.flexible.elements.FileElement#setMaxUploadSizeKB(int,
* java.lang.String, java.lang.String[])
*/
@Override
public void setMaxUploadSizeKB(long maxUploadSizeKB, String i18nErrKey, String[] i18nArgs) {
this.maxUploadSizeKB = maxUploadSizeKB;
this.checkForMaxFileSize = (maxUploadSizeKB == UPLOAD_UNLIMITED ? false : true);
......@@ -426,9 +408,7 @@ public class FileElementImpl extends FormItemImpl
this.i18nErrMaxSizeArgs = i18nArgs;
}
/**
* @see org.olat.core.gui.components.form.flexible.FormMultipartItem#getMaxUploadSizeKB()
*/
@Override
public long getMaxUploadSizeKB() {
return maxUploadSizeKB;
}
......@@ -451,9 +431,7 @@ public class FileElementImpl extends FormItemImpl
this.confirmDelete = confirmDelete;
}
/**
* @see org.olat.core.gui.components.form.flexible.elements.FileElement#isUploadSuccess()
*/
@Override
public boolean isUploadSuccess() {
if (tempUploadFile != null && tempUploadFile.exists()) {
return true;
......@@ -461,9 +439,7 @@ public class FileElementImpl extends FormItemImpl
return false;
}
/**
* @see org.olat.core.gui.components.form.flexible.elements.FileElement#getUploadFileName()
*/
@Override
public String getUploadFileName() {
return uploadFilename;
}
......@@ -474,23 +450,17 @@ public class FileElementImpl extends FormItemImpl
this.uploadMimeType = WebappHelper.getMimeType(uploadFilename);
}
/**
* @see org.olat.core.gui.components.form.flexible.elements.FileElement#getUploadMimeType()
*/
@Override
public String getUploadMimeType() {
return uploadMimeType;
}
/**
* @see org.olat.core.gui.components.form.flexible.elements.FileElement#getUploadFile()
*/
@Override
public File getUploadFile() {
return tempUploadFile;
}
/**
* @see org.olat.core.gui.components.form.flexible.elements.FileElement#getUploadInputStream()
*/
@Override
public InputStream getUploadInputStream() {
if (tempUploadFile == null)
return null;
......@@ -502,9 +472,7 @@ public class FileElementImpl extends FormItemImpl
return null;
}
/**
* @see org.olat.core.gui.components.form.flexible.elements.FileElement#getUploadSize()
*/
@Override
public long getUploadSize() {
if (tempUploadFile != null && tempUploadFile.exists()) {
return tempUploadFile.length();
......@@ -515,9 +483,7 @@ public class FileElementImpl extends FormItemImpl
}
}
/**
* @see org.olat.core.gui.components.form.flexible.elements.FileElement#moveUploadFileTo(java.io.File)
*/
@Override
public File moveUploadFileTo(File destinationDir) {
if (tempUploadFile != null && tempUploadFile.exists()) {
destinationDir.mkdirs();
......@@ -537,9 +503,6 @@ public class FileElementImpl extends FormItemImpl
return null;
}
/**
* @see org.olat.core.gui.components.form.flexible.elements.FileElement#moveUploadFileTo(org.olat.core.util.vfs.VFSContainer)
*/
@Override
public VFSLeaf moveUploadFileTo(VFSContainer destinationContainer) {
return moveUploadFileTo(destinationContainer, false);
......@@ -615,9 +578,7 @@ public class FileElementImpl extends FormItemImpl
}
}
/**
* @see org.olat.core.gui.control.Disposable#dispose()
*/
@Override
public void dispose() {
if (tempUploadFile != null && tempUploadFile.exists()) {
tempUploadFile.delete();
......
......@@ -97,28 +97,30 @@ public class FileElementRenderer extends DefaultComponentRenderer {
// the div.o_fakechooser is layered below the input.Browse and represents the visual GUI.
// Since input.Browse is layered above div.o_fakechooser, all click events to go input.Browse
// See http://www.quirksmode.org/dom/inputfile.html
sb.append("<input type='file' name=\"");
sb.append(id); // name for form labeling
sb.append("\" id=\"");
sb.append(id); // id to make dirty button work
sb.append("\" class='form-control o_realchooser ").append(" o_chooser_with_delete", showDeleteButton).append("' ");
// Add on* event handlers
StringBuilder eventHandlers = FormJSHelper.getRawJSFor(fileElem.getRootForm(), id, fileElem.getAction());
int onChangePos = eventHandlers.indexOf("onchange=");
if (onChangePos != -1) {
// add file upload change handler
sb.append(eventHandlers.substring(0, onChangePos + 10))
.append("b_handleFileUploadFormChange(this, this.form.fake_").append(id).append(", this.form.upload);")
.append(eventHandlers.substring(onChangePos + 10, eventHandlers.length()));
} else {
sb.append(eventHandlers)
.append(" onchange=\"b_handleFileUploadFormChange(this, this.form.fake_").append(id).append(", this.form.upload)\"");
}
// Add pseudo focus marker on fake file chooser button
sb.append(" onfocus=\"this.form.fake_").append(id).append(".nextSibling.style.border = '1px dotted black';\"")
.append(" onblur=\"this.form.fake_").append(id).append(".nextSibling.style.border = '0';\"");
// Add select text (hover)
sb.append(" title=\"").append(StringEscapeUtils.escapeHtml(trans.translate("file.element.select"))).append("\" />");
if (fileElem.isButtonsEnabled()) {
sb.append("<input type='file' name=\"");
sb.append(id); // name for form labeling
sb.append("\" id=\"");
sb.append(id); // id to make dirty button work
sb.append("\" class='form-control o_realchooser ").append(" o_chooser_with_delete", showDeleteButton).append("' ");
// Add on* event handlers
StringBuilder eventHandlers = FormJSHelper.getRawJSFor(fileElem.getRootForm(), id, fileElem.getAction());
int onChangePos = eventHandlers.indexOf("onchange=");
if (onChangePos != -1) {
// add file upload change handler
sb.append(eventHandlers.substring(0, onChangePos + 10))
.append("b_handleFileUploadFormChange(this, this.form.fake_").append(id).append(", this.form.upload);")
.append(eventHandlers.substring(onChangePos + 10, eventHandlers.length()));
} else {
sb.append(eventHandlers)
.append(" onchange=\"b_handleFileUploadFormChange(this, this.form.fake_").append(id).append(", this.form.upload)\"");
}
// Add pseudo focus marker on fake file chooser button
sb.append(" onfocus=\"this.form.fake_").append(id).append(".nextSibling.style.border = '1px dotted black';\"")
.append(" onblur=\"this.form.fake_").append(id).append(".nextSibling.style.border = '0';\"");
// Add select text (hover)
sb.append(" title=\"").append(StringEscapeUtils.escapeHtml(trans.translate("file.element.select"))).append("\" />");
}
// Add the visible but fake input field and a styled faked file chooser button
sb.append("<div class='o_fakechooser input-group'>");
sb.append("<input class='form-control' name='fake_").append(id).append("' value=\"").append(StringEscapeUtils.escapeHtml(fileName))
......
......@@ -877,6 +877,23 @@ public class FileUtils {
return nameSanitized;
}
public static String normalizeFilenameWithSuffix(String filename) {
boolean hasExtension = false;
String name = filename;
String extension = getFileSuffix(filename);
if (extension != null && extension.length() > 0) {
hasExtension = true;
name = filename.substring(0, filename.length() - extension.length() - 1);
}
StringBuilder normalizedFilename = new StringBuilder();
normalizedFilename.append(normalizeFilename(name));
if (hasExtension) {
normalizedFilename.append(".");
normalizedFilename.append(normalizeFilename(extension));
}
return normalizedFilename.toString();
}
/**
* Creates a new directory in the specified directory, using the given prefix and suffix strings to generate its name.
* It uses File.createTempFile() and should provide a unique name.
......
......@@ -59,6 +59,7 @@ import org.olat.core.helpers.Settings;
*/
public class Formatter {
private static final int BYTE_UNIT = 1000;
private static final DateFormat formatterDatetimeFilesystem = new SimpleDateFormat("yyyy-MM-dd'T'HH-mm-ss_SSS");
private static final DateFormat formatterDatetimeWithMinutes = new SimpleDateFormat("yyyy-MM-dd'T'HH-mm");
private static final DateFormat formatDateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
......@@ -384,18 +385,23 @@ public class Formatter {
return DurationFormatUtils.formatDuration(timecode, "H:mm", true);
}
public static String formatKBytes(long kBytes) {
return formatBytes(BYTE_UNIT * kBytes);
}
/**
* Format the given bytes to human readable format
* @param bytes the byte count
* @return human readable formatted bytes
*/
public static String formatBytes(long bytes) {
int unit = 1000;
int unit = BYTE_UNIT;
if (bytes < unit) return bytes + " B";
int exp = (int) (Math.log(bytes) / Math.log(unit));
String pre = "kMGTPE".charAt(exp-1) + "";
return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
}
}
/**
* Escape " with &quot; in strings
* @param source
......
......@@ -17,17 +17,29 @@
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.modules.forms;
package org.olat.core.util.vfs;
import javax.servlet.http.HttpServletRequest;
import org.olat.core.dispatcher.mapper.Mapper;
import org.olat.core.gui.media.MediaResource;
/**
*
* Initial date: 12 déc. 2016<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
* Initial date: 06.02.2018<br>
* @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
*
*/
public enum EvaluationFormResponseDataTypes {
public class VFSLeafMapper implements Mapper {
private final VFSLeaf file;
numerical,
text
public VFSLeafMapper(VFSLeaf file) {
this.file = file;
}
@Override
public MediaResource handle(String relPath, HttpServletRequest request) {
return new VFSMediaResource(file);
}
}
......@@ -19,11 +19,14 @@
*/
package org.olat.modules.forms;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;
import org.olat.basesecurity.IdentityRef;
import org.olat.core.id.Identity;
import org.olat.core.util.vfs.VFSLeaf;
import org.olat.modules.portfolio.PageBody;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryEntryRef;
......@@ -54,11 +57,22 @@ public interface EvaluationFormManager {
public List<EvaluationFormResponse> getResponsesFromPortfolioEvaluation(List<? extends IdentityRef> identities, PageBody anchor, EvaluationFormSessionStatus status);
public EvaluationFormResponse createResponseForPortfolioEvaluation(String responseIdentifier, BigDecimal numericalValue, String stringuifiedResponse,
EvaluationFormResponseDataTypes dataType, EvaluationFormSession session);
public EvaluationFormResponse createResponseForPortfolioEvaluation(String responseIdentifier,
BigDecimal numericalValue, String stringuifiedResponse, EvaluationFormSession session);
public EvaluationFormResponse createResponseForPortfolioEvaluation(String responseIdentifier, File file,
String filename, EvaluationFormSession session) throws IOException;
public EvaluationFormResponse updateResponseForPortfolioEvaluation(BigDecimal numericalValue, String stringuifiedResponse, EvaluationFormResponse response);
public EvaluationFormResponse updateResponseForPortfolioEvaluation(BigDecimal numericalValue,
String stringuifiedResponse, EvaluationFormResponse response);
public EvaluationFormResponse updateResponseForPortfolioEvaluation(File file, String filename,
EvaluationFormResponse response) throws IOException;
public File loadResponseFile(EvaluationFormResponse response);
public VFSLeaf loadResponseLeaf(EvaluationFormResponse response);
/**
* Is there some sessions using this repository entry.
*
......@@ -66,4 +80,5 @@ public interface EvaluationFormManager {
* @return
*/
public boolean isEvaluationFormActivelyUsed(RepositoryEntryRef formEntry);
}
......@@ -20,6 +20,7 @@
package org.olat.modules.forms;
import java.math.BigDecimal;
import java.nio.file.Path;
import org.olat.core.id.CreateInfo;
import org.olat.core.id.ModifiedInfo;
......@@ -40,6 +41,8 @@ public interface EvaluationFormResponse extends CreateInfo, ModifiedInfo {
public String getStringuifiedResponse();
public Path getFileResponse();
/**
* The evaluation form session of this response.
*
......
......@@ -19,8 +19,15 @@
*/
package org.olat.modules.forms;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.olat.core.configuration.AbstractSpringModule;
import org.olat.core.configuration.ConfigOnOff;
import org.olat.core.gui.components.form.flexible.elements.FileElement;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.StringHelper;
import org.olat.core.util.coordinate.CoordinatorManager;
import org.olat.modules.forms.handler.EvaluationFormHandler;
......@@ -38,6 +45,8 @@ import org.springframework.stereotype.Service;
@Service
public class EvaluationFormsModule extends AbstractSpringModule implements ConfigOnOff {
private static final OLog log = Tracing.createLoggerFor(EvaluationFormsModule.class);
public static final String FORMS_ENABLED = "forms.enabled";
@Autowired
......@@ -46,6 +55,11 @@ public class EvaluationFormsModule extends AbstractSpringModule implements Confi
@Value("${forms.enabled:true}")
private boolean enabled;
@Value("${forms.file.upload.limit.mb:5,10,20,50}")
private String fileUploadLimitsMB;
private List<Long> orderedFileUploadLimitsKB = new ArrayList<>(4);
private long maxFileUploadLimitsKB = FileElement.UPLOAD_UNLIMITED;
@Autowired
public EvaluationFormsModule(CoordinatorManager coordinatorManager) {
super(coordinatorManager);
......@@ -57,10 +71,28 @@ public class EvaluationFormsModule extends AbstractSpringModule implements Confi
if(StringHelper.containsNonWhitespace(enabledObj)) {
enabled = "true".equals(enabledObj);
}
initFileUploadLimit();
RepositoryHandlerFactory.registerHandler(formHandler, 40);
}
private void initFileUploadLimit() {
String[] limits = fileUploadLimitsMB.split(",");
for (String limit: limits) {
if (StringHelper.containsNonWhitespace(limit)) {
try {
long limitKB = Long.parseLong(limit) * 1000;
orderedFileUploadLimitsKB.add(limitKB);
} catch (Exception e) {
log.warn("The value '" + limit + "' for the property 'forms.file.upload.limit.mb' is no valid numver.");
}
}
}
Collections.sort(orderedFileUploadLimitsKB);
maxFileUploadLimitsKB = orderedFileUploadLimitsKB.get(orderedFileUploadLimitsKB.size() - 1);
}
@Override
protected void initFromChangedProperties() {
init();
......@@ -75,7 +107,13 @@ public class EvaluationFormsModule extends AbstractSpringModule implements Confi
this.enabled = enabled;
setStringProperty(FORMS_ENABLED, Boolean.toString(enabled), true);
}
public List<Long> getOrderedFileUploadLimitsKB() {
return orderedFileUploadLimitsKB;
}
public long getMaxFileUploadLimitKB() {
return maxFileUploadLimitsKB;
}
}
/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.modules.forms.handler;
import java.util.Locale;
import java.util.UUID;
import org.olat.core.CoreSpringFactory;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.WindowControl;
import org.olat.modules.forms.EvaluationFormsModule;
import org.olat.modules.forms.model.xml.FileUpload;
import org.olat.modules.forms.ui.FileUploadController;
import org.olat.modules.forms.ui.FileUploadEditorController;
import org.olat.modules.portfolio.ui.editor.PageElement;
import org.olat.modules.portfolio.ui.editor.PageElementEditorController;
import org.olat.modules.portfolio.ui.editor.PageElementHandler;
import org.olat.modules.portfolio.ui.editor.PageElementRenderingHints;
import org.olat.modules.portfolio.ui.editor.PageRunControllerElement;
import org.olat.modules.portfolio.ui.editor.PageRunElement;
import org.olat.modules.portfolio.ui.editor.SimpleAddPageElementHandler;
/**
*
* Initial date: 02.02.2018<br>
* @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
*
*/
public class FileUploadHandler implements PageElementHandler, SimpleAddPageElementHandler {
@Override
public String getType() {
return "formfileupload";
}
@Override
public String getIconCssClass() {
return "o_icon_fileupload";
}
@Override
public PageRunElement getContent(UserRequest ureq, WindowControl wControl, PageElement element, PageElementRenderingHints hints) {
if(element instanceof FileUpload) {
FileUpload fileUpload = (FileUpload) element;
Controller ctrl = new FileUploadController(ureq, wControl, fileUpload);
return new PageRunControllerElement(ctrl);
}
return null;
}
@Override
public PageElementEditorController getEditor(UserRequest ureq, WindowControl wControl, PageElement element) {
if(element instanceof FileUpload) {
FileUpload fileUpload = (FileUpload) element;
return new FileUploadEditorController(ureq, wControl, fileUpload);
}
return null;
}
@Override
public PageElement createPageElement(Locale locale) {
EvaluationFormsModule evaluationFormModule = CoreSpringFactory.getImpl(EvaluationFormsModule.class);
FileUpload part = new FileUpload();
part.setId(UUID.randomUUID().toString());
part.setMaxUploadSizeKB(evaluationFormModule.getMaxFileUploadLimitKB());
return part;
}
}
......@@ -19,14 +19,17 @@
*/
package org.olat.modules.forms.manager;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Path;
import java.util.List;
import org.olat.basesecurity.IdentityRef;
import org.olat.core.id.Identity;
import org.olat.core.util.vfs.VFSLeaf;
import org.olat.modules.forms.EvaluationFormManager;
import org.olat.modules.forms.EvaluationFormResponse;
import org.olat.modules.forms.EvaluationFormResponseDataTypes;
import org.olat.modules.forms.EvaluationFormSession;
import org.olat.modules.forms.EvaluationFormSessionStatus;
import org.olat.modules.portfolio.PageBody;
......@@ -48,7 +51,10 @@ public class EvaluationFormManagerImpl implements EvaluationFormManager {
private EvaluationFormSessionDAO evaluationFormSessionDao;
@Autowired
private EvaluationFormResponseDAO evaluationFormResponseDao;
@Autowired
private EvaluationFormStorage evaluationFormStorage;
@Override
public EvaluationFormSession createSessionForPortfolioEvaluation(Identity identity, PageBody body, RepositoryEntry formEntry) {
return evaluationFormSessionDao.createSessionForPortfolio(identity, body, formEntry);
}
......@@ -75,13 +81,50 @@ public class EvaluationFormManagerImpl implements EvaluationFormManager {
@Override
public EvaluationFormResponse createResponseForPortfolioEvaluation(String responseIdentifier, BigDecimal numericalValue, String stringuifiedResponse,
EvaluationFormResponseDataTypes dataType, EvaluationFormSession session) {
return evaluationFormResponseDao.createResponse(responseIdentifier, numericalValue, stringuifiedResponse, dataType, session);
EvaluationFormSession session) {
return evaluationFormResponseDao.createResponse(responseIdentifier, numericalValue, stringuifiedResponse, null, session);
}
@Override
public EvaluationFormResponse createResponseForPortfolioEvaluation(String responseIdentifier, File file,
String filename, EvaluationFormSession session) throws IOException {
Path relativePath = evaluationFormStorage.save(file, filename, responseIdentifier);
return evaluationFormResponseDao.createResponse(responseIdentifier, null, filename, relativePath,
session);
}
@Override
public EvaluationFormResponse updateResponseForPortfolioEvaluation(BigDecimal numericalValue, String stringuifiedResponse, EvaluationFormResponse response) {
return evaluationFormResponseDao.updateResponse(numericalValue, stringuifiedResponse, response);
return evaluationFormResponseDao.updateResponse(numericalValue, stringuifiedResponse, null, response);
}
@Override
public EvaluationFormResponse updateResponseForPortfolioEvaluation(File file, String filename,
EvaluationFormResponse response) throws IOException {
if (response.getFileResponse() != null) {
evaluationFormStorage.delete(response.getFileResponse());
}
Path relativePath = null;
String filenameToSave = null;
if (file != null) {
relativePath = evaluationFormStorage.save(file, filename, response.getResponseIdentifier());
filenameToSave = filename;
}
return evaluationFormResponseDao.updateResponse(null, filenameToSave, relativePath, response);
}
@Override
public File loadResponseFile(EvaluationFormResponse response) {
if (response == null || response.getFileResponse() == null) return null;
return evaluationFormStorage.load(response.getFileResponse());
}
@Override
public VFSLeaf loadResponseLeaf(EvaluationFormResponse response) {
if (response == null || response.getFileResponse() == null) return null;
return evaluationFormStorage.resolve(response.getFileResponse());
}
@Override
......
......@@ -20,6 +20,7 @@
package org.olat.modules.forms.manager;
import java.math.BigDecimal;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Date;
import java.util.List;
......@@ -30,7 +31,6 @@ import javax.persistence.TypedQuery;
import org.olat.basesecurity.IdentityRef;
import org.olat.core.commons.persistence.DB;
import org.olat.modules.forms.EvaluationFormResponse;
import org.olat.modules.forms.EvaluationFormResponseDataTypes;
import org.olat.modules.forms.EvaluationFormSession;
import org.olat.modules.forms.EvaluationFormSessionStatus;
import org.olat.modules.forms.model.jpa.EvaluationFormResponseImpl;
......@@ -51,13 +51,13 @@ public class EvaluationFormResponseDAO {
private DB dbInstance;
public EvaluationFormResponse createResponse(String responseIdentifier, BigDecimal numericalValue, String stringuifiedResponse,
EvaluationFormResponseDataTypes dataType, EvaluationFormSession session) {
Path fileResponse, EvaluationFormSession session) {
EvaluationFormResponseImpl response = new EvaluationFormResponseImpl();
response.setCreationDate(new Date());
response.setLastModified(response.getCreationDate());
response.setSession(session);
response.setResponseDataType(dataType.name());
response.setResponseIdentifier(responseIdentifier);
response.setFileResponse(fileResponse);
response.setNumericalResponse(numericalValue);
response.setStringuifiedResponse(stringuifiedResponse);
dbInstance.getCurrentEntityManager().persist(response);
......@@ -97,11 +97,13 @@ public class EvaluationFormResponseDAO {
return rQuery.getResultList();
}
public EvaluationFormResponse updateResponse(BigDecimal numericalValue, String stringuifiedResponse, EvaluationFormResponse response) {
public EvaluationFormResponse updateResponse(BigDecimal numericalValue, String stringuifiedResponse,
Path fileResponse, EvaluationFormResponse response) {
EvaluationFormResponseImpl evalResponse = (EvaluationFormResponseImpl)response;
evalResponse.setLastModified(new Date());
evalResponse.setNumericalResponse(numericalValue);
evalResponse.setStringuifiedResponse(stringuifiedResponse);
evalResponse.setFileResponse(fileResponse);
return dbInstance.getCurrentEntityManager().merge(response);
}
}
/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.modules.forms.manager;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import javax.annotation.PostConstruct;
import org.olat.core.commons.modules.bc.FolderConfig;
import org.olat.core.commons.modules.bc.vfs.OlatRootFileImpl;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.vfs.VFSLeaf;
import org.springframework.stereotype.Service;
/**
*
* Initial date: 04.02.2018<br>
* @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
*
*/
@Service
public class EvaluationFormStorage {
private static final OLog log = Tracing.createLoggerFor(EvaluationFormStorage.class);
private static final String EVALUATION_FORMS_DIRECTORY = "evaluation_form";
private static final String RESPONSES_DIRECTORY = "responses";
private Path bcrootDirectory;
private Path rootDirectory;
private Path responsesDirectory;
@PostConstruct
public void initDirectories() {
bcrootDirectory = Paths.get(FolderConfig.getCanonicalRoot());
rootDirectory = Paths.get(FolderConfig.getCanonicalRoot(), EVALUATION_FORMS_DIRECTORY);
responsesDirectory = Paths.get(rootDirectory.toString(), RESPONSES_DIRECTORY);
try {
Files.createDirectories(responsesDirectory);
} catch (Exception e) {
log.error("Creation of evaluation forms responses directory failed! Path: " + responsesDirectory, e);
}
}
Path getResponsesRoot() {
return responsesDirectory;
}
/**
* Save a file in the responses store.
*
* @param file the file to save
* @param filename the filename of the new file
* @param responseIdentifier the identifier of the evaluation form response
* @return the relative path of the saved file
*/
public Path save(File file, String filename, String responseIdentifier) throws IOException {
Path responsePath = getResponsePath(responseIdentifier, filename);
Path sourcePath = file.toPath();
Files.createDirectories(responsePath.getParent());
Files.copy(sourcePath, responsePath, StandardCopyOption.REPLACE_EXISTING);
return getRelativePath(responsePath);
}
public File load(Path relativePath) {
return getAbsolutePath(relativePath).toFile();
}
public VFSLeaf resolve(Path relativePath) {
return new OlatRootFileImpl("/" + relativePath.toString(), null);
}
public void delete(Path relativePath) {
Path absolutePath = getAbsolutePath(relativePath);
try {
Files.deleteIfExists(absolutePath);
} catch (IOException e) {
log.warn("Cannot properly delete evaluation form response file. Path: " + absolutePath, e);
}
}
private Path getResponsePath(String responseIdentifier, String filename) {
return Paths.get(
responsesDirectory.toString(),
getIndexTooken(responseIdentifier),
responseIdentifier,
filename);
}
private String getIndexTooken(String responseIdentifier) {
return responseIdentifier.replace("-", "").substring(0, 2).toLowerCase();
}
private Path getRelativePath(Path path) {
return bcrootDirectory.relativize(path);
}
private Path getAbsolutePath(Path relativePath) {
return bcrootDirectory.resolve(relativePath);
}
}
......@@ -20,6 +20,8 @@
package org.olat.modules.forms.model.jpa;
import java.math.BigDecimal;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import javax.persistence.Column;
......@@ -64,12 +66,12 @@ public class EvaluationFormResponseImpl implements EvaluationFormResponse, Persi
@Column(name="e_responseidentifier", nullable=false, insertable=true, updatable=false)
private String responseIdentifier;
@Column(name="e_responsedatatype", nullable=false, insertable=true, updatable=false)
private String responseDataType;
@Column(name="e_numericalresponse", nullable=true, insertable=true, updatable=true)
private BigDecimal numericalResponse;
@Column(name="e_stringuifiedresponse", nullable=true, insertable=true, updatable=true)
private String stringuifiedResponse;
@Column(name="e_file_response_path", nullable=true, insertable=true, updatable=true)
private String fileResponsePath;
@ManyToOne(targetEntity=EvaluationFormSessionImpl.class,fetch=FetchType.LAZY,optional=false)
@JoinColumn(name="fk_session", nullable=false, insertable=true, updatable=false)
......@@ -112,14 +114,6 @@ public class EvaluationFormResponseImpl implements EvaluationFormResponse, Persi
this.responseIdentifier = responseIdentifier;
}
public String getResponseDataType() {
return responseDataType;
}
public void setResponseDataType(String responseDataType) {
this.responseDataType = responseDataType;
}
@Override
public BigDecimal getNumericalResponse() {
return numericalResponse;
......@@ -138,6 +132,15 @@ public class EvaluationFormResponseImpl implements EvaluationFormResponse, Persi
this.stringuifiedResponse = stringuifiedResponse;
}
@Override
public Path getFileResponse() {
return fileResponsePath != null? Paths.get(fileResponsePath): null;
}
public void setFileResponse(Path fileResponse) {
this.fileResponsePath = fileResponse != null? fileResponse.toString(): null;
}
@Override
public EvaluationFormSession getSession() {
return session;
......
/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.modules.forms.model.xml;
/**
*
* Initial date: 02.02.2018<br>
* @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
*
*/
public class FileUpload extends AbstractElement {
private static final long serialVersionUID = 7057962558556618266L;
private long maxUploadSizeKB;
private String mimeTypeSetKey;
@Override
public String getType() {
return "formfileupload";
}
public Long getMaxUploadSizeKB() {
return maxUploadSizeKB;
}
public void setMaxUploadSizeKB(long maxUploadSizeKB) {
this.maxUploadSizeKB = maxUploadSizeKB;
}
public String getMimeTypeSetKey() {
return mimeTypeSetKey;
}
public void setMimeTypeSetKey(String mimeTypeSetKey) {
this.mimeTypeSetKey = mimeTypeSetKey;
}
@Override
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj instanceof FileUpload) {
FileUpload fileUpload = (FileUpload)obj;
return getId() != null && getId().equals(fileUpload.getId());
}
return super.equals(obj);
}
}
......@@ -39,6 +39,7 @@ public class FormXStream {
xstream.alias("title", Title.class);
xstream.alias("rubric", Rubric.class);
xstream.alias("slider", Slider.class);
xstream.alias("fileupload", FileUpload.class);
}
public static XStream getXStream() {
......
......@@ -28,6 +28,8 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.olat.core.commons.modules.bc.meta.MetaInfo;
import org.olat.core.commons.modules.bc.meta.tagged.MetaTagged;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.chart.RadarChartComponent.Format;
import org.olat.core.gui.components.chart.RadarChartElement;
......@@ -38,9 +40,12 @@ import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.util.CSSHelper;
import org.olat.core.id.Identity;
import org.olat.core.util.Formatter;
import org.olat.core.util.StringHelper;
import org.olat.core.util.vfs.VFSLeaf;
import org.olat.core.util.vfs.VFSLeafMapper;
import org.olat.core.util.xml.XStreamHelper;
import org.olat.fileresource.FileResourceManager;
import org.olat.modules.forms.EvaluationFormManager;
......@@ -48,6 +53,7 @@ import org.olat.modules.forms.EvaluationFormResponse;
import org.olat.modules.forms.EvaluationFormSession;
import org.olat.modules.forms.EvaluationFormSessionStatus;
import org.olat.modules.forms.model.xml.AbstractElement;
import org.olat.modules.forms.model.xml.FileUpload;
import org.olat.modules.forms.model.xml.Form;
import org.olat.modules.forms.model.xml.FormXStream;
import org.olat.modules.forms.model.xml.Rubric;
......@@ -58,6 +64,7 @@ import org.olat.modules.forms.ui.component.SliderOverviewElement;
import org.olat.modules.forms.ui.component.SliderPoint;
import org.olat.modules.forms.ui.model.EvaluationFormElementWrapper;
import org.olat.modules.forms.ui.model.Evaluator;
import org.olat.modules.forms.ui.model.FileUploadCompareWrapper;
import org.olat.modules.forms.ui.model.SliderWrapper;
import org.olat.modules.forms.ui.model.TextInputWrapper;
import org.olat.modules.portfolio.PageBody;
......@@ -125,13 +132,13 @@ public class CompareEvaluationsFormController extends FormBasicController {
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
updateElements();
updateElements(ureq);
}
private void updateElements() {
private void updateElements(UserRequest ureq) {
List<EvaluationFormElementWrapper> elementWrappers = new ArrayList<>();
for(AbstractElement element:form.getElements()) {
appendsElement(element, elementWrappers);
appendsElement(ureq, element, elementWrappers);
}
flc.contextPut("elements", elementWrappers);
......@@ -152,7 +159,7 @@ public class CompareEvaluationsFormController extends FormBasicController {
}
}
private void appendsElement(AbstractElement element, List<EvaluationFormElementWrapper> wrappers) {
private void appendsElement(UserRequest ureq, AbstractElement element, List<EvaluationFormElementWrapper> wrappers) {
String type = element.getType();
switch(type) {
case "formhtitle":
......@@ -174,18 +181,71 @@ public class CompareEvaluationsFormController extends FormBasicController {
break;
case "formtextinput":
List<EvaluationFormElementWrapper> inputWrappers = forgeTextInput((TextInput)element);
if(inputWrappers != null && inputWrappers.size() > 0) {
if(inputWrappers != null && !inputWrappers.isEmpty()) {
wrappers.addAll(inputWrappers);
}
break;
case "formfileupload":
List<EvaluationFormElementWrapper> fileUploadWrappers = forgeFileUpload(ureq, (FileUpload)element);
if(fileUploadWrappers != null && !fileUploadWrappers.isEmpty()) {
wrappers.addAll(fileUploadWrappers);
}
break;
}
}
private List<EvaluationFormElementWrapper> forgeFileUpload(UserRequest ureq, FileUpload element) {
List<EvaluationFormResponse> responses = identifierToResponses.get(element.getId());
if (responses == null) {
return new ArrayList<>();
}
List<EvaluationFormElementWrapper> fileUploadWrappers = new ArrayList<>(responses.size());
for (EvaluationFormResponse response:responses) {
if (response.getFileResponse() != null) {
FileUploadCompareWrapper fileUploadWrapper = createFileUploadCompareWrapper(ureq, element, response);
EvaluationFormElementWrapper wrapper = new EvaluationFormElementWrapper(element);
wrapper.setFileUploadCompareWrapper(fileUploadWrapper);
fileUploadWrappers.add(wrapper);
}
}
return fileUploadWrappers;
}
private FileUploadCompareWrapper createFileUploadCompareWrapper(UserRequest ureq, FileUpload element,
EvaluationFormResponse response) {
Identity evaluator = response.getSession().getIdentity();
String color = evaluatorToColors.get(evaluator);
String evaluatorName = getLegend(evaluator);
String filename = response.getStringuifiedResponse();
String filesize = null;
String mapperUri = null;
String iconCss = null;
String thumbUri = null;
VFSLeaf leaf = evaluationFormManager.loadResponseLeaf(response);
if (leaf != null) {
filename = leaf.getName();
filesize = Formatter.formatBytes((leaf).getSize());
mapperUri = registerCacheableMapper(ureq, "file-upload-" + element.getId() + "-" + leaf.getLastModified(), new VFSLeafMapper(leaf));
iconCss = CSSHelper.createFiletypeIconCssClassFor(leaf.getName());
if (leaf instanceof MetaTagged) {
MetaTagged metaTaggedLeaf = (MetaTagged) leaf;
MetaInfo meta = metaTaggedLeaf.getMetaInfo();
if (meta != null && meta.isThumbnailAvailable()) {
VFSLeaf thumb = meta.getThumbnail(200, 200, false);
if (thumb != null) {
thumbUri = registerCacheableMapper(ureq, "file-upload-thumb" + element.getId() + "-" + leaf.getLastModified(), new VFSLeafMapper(thumb));;
}
}
}
}
return new FileUploadCompareWrapper(color, evaluatorName, filename, filesize, mapperUri, iconCss, thumbUri);
}
private List<EvaluationFormElementWrapper> forgeTextInput(TextInput element) {
List<EvaluationFormResponse> responses = identifierToResponses.get(element.getId());
if (responses == null) {
// in review - selbstreview ??
return new ArrayList<EvaluationFormElementWrapper>();
return new ArrayList<>();
}
List<EvaluationFormElementWrapper> inputWrappers = new ArrayList<>(responses.size());
for(EvaluationFormResponse response:responses) {
......@@ -325,4 +385,5 @@ public class CompareEvaluationsFormController extends FormBasicController {
protected void doDispose() {
//
}
}
......@@ -22,22 +22,26 @@ package org.olat.modules.forms.ui;
import static org.olat.modules.forms.handler.EvaluationFormResource.FORM_XML_FILE;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.olat.core.commons.persistence.DB;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.FileElement;
import org.olat.core.gui.components.form.flexible.elements.FormLink;
import org.olat.core.gui.components.form.flexible.elements.SingleSelection;
import org.olat.core.gui.components.form.flexible.elements.SliderElement;
import org.olat.core.gui.components.form.flexible.elements.TextElement;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent;
import org.olat.core.gui.components.form.flexible.impl.elements.FileElementEvent;
import org.olat.core.gui.components.form.flexible.impl.elements.FormSubmit;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.control.Controller;
......@@ -46,15 +50,19 @@ import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.generic.modal.DialogBoxController;
import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
import org.olat.core.id.Identity;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.CodeHelper;
import org.olat.core.util.StringHelper;
import org.olat.core.util.xml.XStreamHelper;
import org.olat.fileresource.FileResourceManager;
import org.olat.modules.forms.EvaluationFormManager;
import org.olat.modules.forms.EvaluationFormResponse;
import org.olat.modules.forms.EvaluationFormResponseDataTypes;
import org.olat.modules.forms.EvaluationFormSession;
import org.olat.modules.forms.EvaluationFormSessionStatus;
import org.olat.modules.forms.manager.EvaluationFormStorage;
import org.olat.modules.forms.model.xml.AbstractElement;
import org.olat.modules.forms.model.xml.FileUpload;
import org.olat.modules.forms.model.xml.Form;
import org.olat.modules.forms.model.xml.FormXStream;
import org.olat.modules.forms.model.xml.Rubric;
......@@ -62,6 +70,7 @@ import org.olat.modules.forms.model.xml.Rubric.SliderType;
import org.olat.modules.forms.model.xml.Slider;
import org.olat.modules.forms.model.xml.TextInput;
import org.olat.modules.forms.ui.model.EvaluationFormElementWrapper;
import org.olat.modules.forms.ui.model.FileUploadWrapper;
import org.olat.modules.forms.ui.model.SliderWrapper;
import org.olat.modules.forms.ui.model.TextInputWrapper;
import org.olat.modules.portfolio.PageBody;
......@@ -78,6 +87,8 @@ import org.springframework.beans.factory.annotation.Autowired;
*
*/
public class EvaluationFormController extends FormBasicController implements ValidatingController {
private static final OLog log = Tracing.createLoggerFor(EvaluationFormStorage.class);
private int count = 0;
private final Form form;
......@@ -168,17 +179,17 @@ public class EvaluationFormController extends FormBasicController implements Val
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
updateElements();
updateElements(ureq);
if(doneButton && !readOnly) {
saveAsDoneButton = uifactory.addFormSubmitButton("save.as.done", formLayout);
}
}
private void updateElements() {
private void updateElements(UserRequest ureq) {
List<EvaluationFormElementWrapper> elementWrappers = new ArrayList<>();
for(AbstractElement element:form.getElements()) {
EvaluationFormElementWrapper wrapper = forgeElement(element);
EvaluationFormElementWrapper wrapper = forgeElement(ureq, element);
if(wrapper != null) {
elementWrappers.add(wrapper);
}
......@@ -207,7 +218,7 @@ public class EvaluationFormController extends FormBasicController implements Val
}
}
private EvaluationFormElementWrapper forgeElement(AbstractElement element) {
private EvaluationFormElementWrapper forgeElement(UserRequest ureq, AbstractElement element) {
EvaluationFormElementWrapper wrapper = null;
String type = element.getType();
......@@ -223,10 +234,36 @@ public class EvaluationFormController extends FormBasicController implements Val
case "formtextinput":
wrapper = forgeTextInput((TextInput)element);
break;
case "formfileupload":
wrapper = forgeFileUpload(ureq, (FileUpload)element);
break;
}
return wrapper;
}
private EvaluationFormElementWrapper forgeFileUpload(UserRequest ureq, FileUpload element) {
FileElement fileEl = uifactory.addFileElement(getWindowControl(), "file_upload_" + CodeHelper.getRAMUniqueID(), "", flc);
fileEl.setPreview(ureq.getUserSession(), true);
fileEl.addActionListener(FormEvent.ONCHANGE);
fileEl.setDeleteEnabled(true);
fileEl.setMaxUploadSizeKB(element.getMaxUploadSizeKB(), "file.upload.error.limit.exeeded", null);
Set<String> mimeTypes = MimeTypeSetFactory.getMimeTypes(element.getMimeTypeSetKey());
fileEl.limitToMimeType(mimeTypes, "file.upload.error.mime.type.wrong", null);
EvaluationFormResponse response = identifierToResponses.get(element.getId());
File responseFile = evaluationFormManager.loadResponseFile(response);
if (responseFile != null) {
fileEl.setInitialFile(responseFile);
}
fileEl.setEnabled(!readOnly);
FileUploadWrapper fileUploadWrapper = new FileUploadWrapper(fileEl, element);
fileEl.setUserObject(fileUploadWrapper);
EvaluationFormElementWrapper wrapper = new EvaluationFormElementWrapper(element);
wrapper.setFileUploadWrapper(fileUploadWrapper);
return wrapper;
}
private EvaluationFormElementWrapper forgeTextInput(TextInput element) {
String initialValue = "";
EvaluationFormResponse response = identifierToResponses.get(element.getId());
......@@ -364,6 +401,11 @@ public class EvaluationFormController extends FormBasicController implements Val
if(wrapper != null && !hasResponse(wrapper.getId())) {
allFiled &= false;
}
} else if(elementWrapper.isFileUpload()) {
FileUploadWrapper wrapper = elementWrapper.getFileUploadWrapper();
if(wrapper != null && !hasResponse(wrapper.getId())) {
allFiled &= false;
}
} else if(elementWrapper.getSliders() != null && elementWrapper.getSliders().size() > 0) {
for(SliderWrapper slider:elementWrapper.getSliders()) {
if(slider != null && !hasResponse(slider.getId())) {
......@@ -388,7 +430,9 @@ public class EvaluationFormController extends FormBasicController implements Val
}
EvaluationFormResponse response = identifierToResponses.get(id);
if(response == null ||
(response.getNumericalResponse() == null && !StringHelper.containsNonWhitespace(response.getStringuifiedResponse()))) {
(response.getNumericalResponse() == null
&& !StringHelper.containsNonWhitespace(response.getStringuifiedResponse())
&& response.getFileResponse() == null)) {
return false;
}
return true;
......@@ -426,7 +470,7 @@ public class EvaluationFormController extends FormBasicController implements Val
if(uobject instanceof SliderWrapper) {
String selectedKey = radioEl.getSelectedKey();
SliderWrapper sliderWrapper = (SliderWrapper)uobject;
saveResponse(new BigDecimal(selectedKey), selectedKey, sliderWrapper.getId());
saveNumericalResponse(new BigDecimal(selectedKey), selectedKey, sliderWrapper.getId());
}
} else if(source instanceof SliderElement) {
SliderElement slider = (SliderElement)source;
......@@ -434,7 +478,7 @@ public class EvaluationFormController extends FormBasicController implements Val
if(uobject instanceof SliderWrapper) {
double value = slider.getValue();
SliderWrapper sliderWrapper = (SliderWrapper)uobject;
saveResponse(new BigDecimal(value), Double.toString(value), sliderWrapper.getId());
saveNumericalResponse(BigDecimal.valueOf(value), Double.toString(value), sliderWrapper.getId());
}
} else if(source instanceof FormLink) {
FormLink link = (FormLink)source;
......@@ -442,23 +486,65 @@ public class EvaluationFormController extends FormBasicController implements Val
if(uobject instanceof TextInputWrapper) {
TextInputWrapper wrapper = (TextInputWrapper)uobject;
String value = wrapper.getTextEl().getValue();
saveResponse(null, value, wrapper.getId());
saveNumericalResponse(null, value, wrapper.getId());
}
} else if (source instanceof FileElement) {
FileElement fileElement = (FileElement)source;
Object uobject = fileElement.getUserObject();
if (uobject instanceof FileUploadWrapper) {
FileUploadWrapper wrapper = (FileUploadWrapper)uobject;
if(event instanceof FileElementEvent) {
if(FileElementEvent.DELETE.equals(event.getCommand())) {
saveFileResponse(null, null, wrapper.getId());
fileElement.setInitialFile(null);
if(fileElement.getUploadFile() != null) {
fileElement.reset();
}
flc.setDirty(true);
}
} else if (fileElement.isUploadSuccess()) {
File file = fileElement.getUploadFile();
String filename = fileElement.getUploadFileName();
saveFileResponse(file, filename, wrapper.getId());
}
}
}
super.formInnerEvent(ureq, source, event);
}
private void saveResponse(BigDecimal numericalValue, String stringuifiedReponse, String responseIdentifier) {
private void saveNumericalResponse(BigDecimal numericalValue, String stringuifiedReponse, String responseIdentifier) {
if(evaluator == null || readOnly) return;
EvaluationFormResponse response = identifierToResponses.get(responseIdentifier);
if(response == null) {
response = evaluationFormManager.createResponseForPortfolioEvaluation(responseIdentifier,
numericalValue, stringuifiedReponse, EvaluationFormResponseDataTypes.numerical, session);
numericalValue, stringuifiedReponse, session);
} else {
response = evaluationFormManager.updateResponseForPortfolioEvaluation(numericalValue, stringuifiedReponse, response);
}
//update cache
updateCache(responseIdentifier, response);
}
private void saveFileResponse(File file, String filename, String responseIdentifier) {
if(evaluator == null || readOnly) return;
EvaluationFormResponse response = identifierToResponses.get(responseIdentifier);
try {
if (response == null) {
response = evaluationFormManager.createResponseForPortfolioEvaluation(responseIdentifier, file, filename,
session);
} else {
response = evaluationFormManager.updateResponseForPortfolioEvaluation(file, filename, response);
}
} catch (IOException e) {
showError("error.cannot.save.file");
log.warn("Cannot save file for an evaluation form response!", e);
}
updateCache(responseIdentifier, response);
}
private void updateCache(String responseIdentifier, EvaluationFormResponse response) {
if(response != null) {
identifierToResponses.put(responseIdentifier, response);
}
......@@ -469,7 +555,7 @@ public class EvaluationFormController extends FormBasicController implements Val
if(elementWrapper.isTextInput()) {
TextInputWrapper wrapper = elementWrapper.getTextInputWrapper();
String value = wrapper.getTextEl().getValue();
saveResponse(null, value, wrapper.getId());
saveNumericalResponse(null, value, wrapper.getId());
}
}
......@@ -492,7 +578,7 @@ public class EvaluationFormController extends FormBasicController implements Val
readOnly = true;
dbInstance.commit();
loadResponses();
updateElements();
updateElements(ureq);
if (saveAsDoneButton != null) {
saveAsDoneButton.setVisible(false);
}
......
......@@ -31,6 +31,7 @@ import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.controller.BasicController;
import org.olat.core.util.xml.XStreamHelper;
import org.olat.modules.forms.handler.FileUploadHandler;
import org.olat.modules.forms.handler.HTMLRawHandler;
import org.olat.modules.forms.handler.RubricHandler;
import org.olat.modules.forms.handler.SpacerHandler;
......@@ -131,6 +132,9 @@ public class EvaluationFormEditorController extends BasicController {
// handler for text input
TextInputHandler textInputHandler = new TextInputHandler();
handlers.add(textInputHandler);
// handler for file upload
FileUploadHandler fileUploadhandler = new FileUploadHandler();
handlers.add(fileUploadhandler);
if(!restrictedEdit) {
creationHandlers.add(titleRawHandler);
......@@ -138,6 +142,7 @@ public class EvaluationFormEditorController extends BasicController {
creationHandlers.add(htmlHandler);
creationHandlers.add(rubricHandler);
creationHandlers.add(textInputHandler);
creationHandlers.add(fileUploadhandler);
}
}
......
/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.modules.forms.ui;
import java.util.Set;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.FileElement;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.util.CodeHelper;
import org.olat.modules.forms.model.xml.FileUpload;
/**
*
* Initial date: 02.02.2018<br>
* @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
*
*/
public class FileUploadController extends FormBasicController {
private FileElement fileEl;
private final FileUpload fileUpload;
public FileUploadController(UserRequest ureq, WindowControl wControl, FileUpload fileUpload) {
super(ureq, wControl, "file_upload");
this.fileUpload = fileUpload;
initForm(ureq);
}
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
long postfix = CodeHelper.getRAMUniqueID();
fileEl = uifactory.addFileElement(getWindowControl(), "file_upload_" + postfix, "", formLayout);
fileEl.setButtonsEnabled(false);
fileEl.setDeleteEnabled(true);
fileEl.setMaxUploadSizeKB(fileUpload.getMaxUploadSizeKB(), "file.upload.error.limit.exeeded", null);
Set<String> mimeTypes = MimeTypeSetFactory.getMimeTypes(fileUpload.getMimeTypeSetKey());
fileEl.limitToMimeType(mimeTypes, "file.upload.error.mime.type.wrong", null);
fileEl.setHelpTextKey("ul.select.fhelp", null);
if(formLayout instanceof FormLayoutContainer) {
FormLayoutContainer layoutCont = (FormLayoutContainer)formLayout;
layoutCont.getFormItemComponent().contextPut("postfix", Long.toString(postfix));
}
}
public void update() {
fileEl.setMaxUploadSizeKB(fileUpload.getMaxUploadSizeKB(), null, null);
Set<String> mimeTypes = MimeTypeSetFactory.getMimeTypes(fileUpload.getMimeTypeSetKey());
fileEl.limitToMimeType(mimeTypes, null, null);
}
@Override
protected void formOK(UserRequest ureq) {
//
}
@Override
protected void doDispose() {
//
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment