Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload documents in Vitro|VIVO #251

Merged
merged 9 commits into from
Apr 14, 2022

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,9 @@ public class VitroVocabulary {
public static final String IND_MAIN_IMAGE = VITRO_PUBLIC + "mainImage";
public static final String IND_IMAGE = VITRO_PUBLIC + "image";

public static final String STORED_FILE = VITRO_PUBLIC + "storedFile";
public static final String PUBLIC_FILENAME = VITRO_PUBLIC + "publicFilename";

// =============== Date Time with Precision vocabulary ===============
private static final String DATETIME_NS = "http://vivoweb.org/ontology/core#";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,5 +253,21 @@ private boolean isFileReferenced(String surrogateUri) {
}
return !stmts.isEmpty();
}

public void removeUploadedFile(String subjectUri, String predicateUri, String fileUri) {
FileInfo fileInfo = FileInfo.instanceFromSurrogateUri(wadf, fileUri);
objectPropertyStatementDao
.deleteObjectPropertyStatement(new ObjectPropertyStatementImpl(subjectUri, predicateUri, fileUri));
deleteIfNotReferenced(fileInfo);
}

public void attachFileToSubject(FileInfo fileInfo, String subjectUri, String predicateUri) {
objectPropertyStatementDao
.insertNewObjectPropertyStatement(new ObjectPropertyStatementImpl(subjectUri, predicateUri, fileInfo.getUri()));
}

public void setPublicFileName(FileInfo fileInfo, String uploadedFileName) {
dataPropertyStatementDao.insertNewDataPropertyStatement(
new DataPropertyStatementImpl(fileInfo.getUri(), VitroVocabulary.PUBLIC_FILENAME, uploadedFileName));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ private String makeDeleteUrl() {
if (VitroVocabulary.IND_MAIN_IMAGE.equals(property.getURI())) {
return ObjectPropertyTemplateModel.getImageUploadUrl(subjectUri, "delete");
}
//If object is a File but not associated with main image
if (ObjectPropertyTemplateModel.isFileStoreProperty(property)) {
return ObjectPropertyTemplateModel.getDeleteFileUrl(subjectUri, property.getURI(), objectUri);
}

ParamMap params = new ParamMap(
"subjectUri", subjectUri,
Expand Down Expand Up @@ -109,6 +113,10 @@ private String makeEditUrl() {
if (VitroVocabulary.IND_MAIN_IMAGE.equals(property.getURI())) {
return ObjectPropertyTemplateModel.getImageUploadUrl(subjectUri, "edit");
}
if (ObjectPropertyTemplateModel.isFileStoreProperty(property)) {
//Disable file editing
return "";
}

ParamMap params = new ParamMap(
"subjectUri", subjectUri,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
private static final String TYPE = "object";
private static final String EDIT_PATH = "editRequestDispatch";
private static final String IMAGE_UPLOAD_PATH = "/uploadImages";
private static final String FILE_UPLOAD_PATH = "/uploadFile";

private static final String END_DATE_TIME_VARIABLE = "dateTimeEnd";
private static final Pattern ORDER_BY_END_DATE_TIME_PATTERN =
Expand Down Expand Up @@ -131,6 +132,8 @@ protected void setAddUrl(Property property) {

if (propertyUri.equals(VitroVocabulary.IND_MAIN_IMAGE)) {
addUrl = getImageUploadUrl(subjectUri, "add");
} else if (isFileStoreProperty(property)) {
addUrl = getFileUploadUrl(subjectUri,property.getURI());
} else {
ParamMap params = new ParamMap(
"subjectUri", subjectUri,
Expand All @@ -149,7 +152,7 @@ protected void setAddUrl(Property property) {
}
}

/**
/**
* Pull this into a protected method so we can stub it out in the unit tests.
* Other options:
* 1) receive a TemplateLoader into the constructor of ObjectPropertyTemplateModel,
Expand Down Expand Up @@ -378,4 +381,20 @@ public String getTemplate() {

public abstract boolean isCollatedBySubclass();


protected static boolean isFileStoreProperty(Property property) {
return property.getRangeVClassURI() != null && property.getRangeVClassURI().equals(VitroVocabulary.FS_FILE_CLASS);
}

public static String getDeleteFileUrl(String subjectUri, String predicateUri, String objectUri) {
ParamMap params = new ParamMap("subjectUri", subjectUri, "predicateUri", predicateUri, "fileUri", objectUri,
"action", "delete");
return UrlBuilder.getUrl(FILE_UPLOAD_PATH, params);
}

private static String getFileUploadUrl(String subjectUri, String predicateUri) {
ParamMap params = new ParamMap("subjectUri", subjectUri, "predicateUri", predicateUri, "action", "upload");
return UrlBuilder.getUrl(FILE_UPLOAD_PATH, params);
}

}
5 changes: 5 additions & 0 deletions dependencies/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,11 @@
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>2.1.0</version>
</dependency>

<dependency>
<groupId>com.sun.mail</groupId>
Expand Down
5 changes: 5 additions & 0 deletions home/src/main/resources/config/example.runtime.properties
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,8 @@ proxy.eligibleTypeList = http://www.w3.org/2002/07/owl#Thing
# Vitro does not contain restricted data that should not be shared with others.
#
# tpf.activeFlag = true
#
# File upload file size in bytes. By default 10485760 bytes (10Mb)
#fileUpload.maxFileSize = 10485760
#comma separated list of mime types allowed for upload
#fileUpload.allowedMIMETypes = image/png, application/pdf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<http://vitro.mannlib.cornell.edu/ns/vitro/public#storedFile> <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#listViewConfigFile> "listViewConfig-storedFile.xml" .
9 changes: 9 additions & 0 deletions home/src/main/resources/rdf/tbox/filegraph/vitroPublic.owl
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
<rdfs:range rdf:resource="&xsd;string"/>
</owl:DatatypeProperty>

<owl:DatatypeProperty rdf:about="#publicFilename">
<rdfs:domain><owl:Class rdf:about="#File"/></rdfs:domain>
<rdfs:range rdf:resource="&xsd;string"/>
</owl:DatatypeProperty>

<owl:DatatypeProperty rdf:about="#attribution">
<rdfs:domain><owl:Class rdf:about="#File"/></rdfs:domain>
<rdfs:range rdf:resource="&xsd;string"/>
Expand All @@ -67,6 +72,10 @@
<rdfs:range><owl:Class rdf:about="#File"/></rdfs:range>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:about="#storedFile">
<rdfs:range><owl:Class rdf:about="#File"/></rdfs:range>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:about="#image">
<rdfs:range><owl:Class rdf:about="#File"/></rdfs:range>
</owl:ObjectProperty>
Expand Down
6 changes: 6 additions & 0 deletions installer/home/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -107,5 +107,11 @@
<artifactId>vitro-home</artifactId>
<type>tar.gz</type>
</dependency>
<dependency>
<groupId>org.vivoweb</groupId>
<artifactId>vitro-languages-home-core</artifactId>
<version>${project.version}</version>
<type>pom</type>
</dependency>
</dependencies>
</project>
44 changes: 44 additions & 0 deletions webapp/src/main/webapp/config/listViewConfig-storedFile.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- $This file is distributed under the terms of the license in LICENSE$ -->

<!-- Default list view config file for object properties

See guidelines at https://wiki.duraspace.org/x/eYXVAw -->

<list-view-config>
<query-select>

PREFIX rdfs: &lt;http://www.w3.org/2000/01/rdf-schema#&gt;
PREFIX vitro: &lt;http://vitro.mannlib.cornell.edu/ns/vitro/0.7#&gt;
PREFIX vitro-public: &lt;http://vitro.mannlib.cornell.edu/ns/vitro/public#&gt;

SELECT <collated> ?subclass </collated>
?object
?filename
?publicFilename
?localName
?url
WHERE {
?subject ?property ?object .
LET (?localName := REPLACE(STR(?object),"^.*(#)(.*)$", "$2"))
?object vitro-public:filename ?filename .
?object vitro-public:publicFilename ?publicFilename .
?object vitro-public:downloadLocation ?url .

<collated>
OPTIONAL {
<precise-subquery>?subject ?property ?object .</precise-subquery>
?object a ?subclass .
# Require the subclasses retrieved to be in a classgroup, since others are not generally
# for display. See vivo-dev-all thread titled "Internal Entity and mostSpecificType,"
# Aug 9-10, 2011.
# ?subclass vitro:inClassGroup ?classgroup
}
FILTER ( REPLACE(STR(?subclass),"^(.*)(#)(.*)$", "$1$2") != "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#" )
</collated>

} ORDER BY <collated> ?subclass </collated> ASC( ?publicFilename ) ASC( ?localName )
</query-select>

<template>storedFile-default.ftl</template>
</list-view-config>
61 changes: 61 additions & 0 deletions webapp/src/main/webapp/js/fileUpload/fileUploadUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* $This file is distributed under the terms of the license in LICENSE$ */

$(document).ready(function(){

var xpath = "//attribute::href[contains(., '/uploadFile')]";
var result = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null);
var node = null;
while (node = result.iterateNext()) {
if(isDeleteUploadFile(node)){
$(node.ownerElement).click(function(){
var answer = confirm(i18n_confirmDeleteUploadedFile);
return answer;
});
} else if (isUploadFile(node)){
$(node.ownerElement).click(function(){
uploadFileRequest(event.target);
return false;
});
}
}
});

function isDeleteUploadFile(node){
var url = node.nodeValue;
if (url.match("&action=delete")){
return true;
}
return false;
}

function isUploadFile(node){
var url = node.nodeValue;
if (url.match("&action=upload")){
return true;
}
return false;
}

function uploadFileRequest(node){
var aElement = node.parentElement;
var form = document.createElement("form");
form.setAttribute("method", "post");
form.setAttribute("action", aElement.href);
form.setAttribute("enctype","multipart/form-data");
form.setAttribute("role","form");
document.body.insertBefore(form, null);
var inputFile = document.createElement("input");
inputFile.type = "file";
inputFile.name = "datafile";
var inputId = "fileUploadInput" + Math.floor(Math.random() * 1000000);
inputFile.setAttribute("id", inputId);
inputFile.setAttribute("style", "display:none;");
form.insertBefore(inputFile, null);
inputFile.click();
inputFile.addEventListener("change", onFileSelect);
}

function onFileSelect(e) {
e.target.parentElement.submit();
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<#-- $This file is distributed under the terms of the license in LICENSE$ -->


${scripts.add('<script type="text/javascript" src="${urls.base}/js/fileUpload/fileUploadUtils.js"></script>')}

<#assign i18n = i18n() >

<section id="fileploadContainer" role="region">
<h2>${i18n.file_upload_heading}</h2>

<#if errorMessage??>
<section id="error-alert" role="alert"><img src="${urls.images}/iconAlert.png" alt="${i18n.alt_error_alert}" />
<p>${errorMessage}</p>
</section>
</#if>
<#if !supportedMediaTypes?has_content>
<section id="error-alert" role="alert"><img src="${urls.images}/iconAlert.png" alt="${i18n.alt_error_alert}" />
<p>${i18n.file_upload_no_allowed_media}</p>
</section>
</#if>
<#if action?? && action == "upload" >
<form id="fileUploadForm" action="${formAction}" enctype="multipart/form-data" method="post" role="form">
<#if supportedMediaTypes?has_content>
<label>${i18n.file_upload_supported_media}</label>
<p>${supportedMediaTypes}</p>
</#if>
<input id="datafile" type="file" name="datafile" size="30" />
<p class="note">${i18n.maximum_file_size(maxFileSize)}</p>
<input class="submit" type="submit" value="${i18n.file_upload_submit_label}"/>
<span class="or"> ${i18n.or} <a class="cancel" href="${referrer}" title="${i18n.cancel_title}">${i18n.cancel_link}</a></span>
</form>
</#if>
</section>
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,11 @@ ${headScripts.add('<script type="text/javascript" src="${urls.base}/js/jquery_pl
'<script type="text/javascript" src="${urls.base}/js/tiny_mce/tiny_mce.js"></script>')}

${scripts.add('<script type="text/javascript" src="${urls.base}/js/imageUpload/imageUploadUtils.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/fileUpload/fileUploadUtils.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/individual/moreLessController.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/individual/individualUriRdf.js"></script>')}

<script type="text/javascript">
i18n_confirmDelete = "${i18n().confirm_delete?js_string}";
i18n_confirmDeleteUploadedFile = "${i18n().file_upload_confirm_delete?js_string}";
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<#-- $This file is distributed under the terms of the license in LICENSE$ -->

<#-- Default object property statement template.

This template must be self-contained and not rely on other variables set for the individual page, because it
is also used to generate the property statement during a deletion.
-->
<@showFiles statement individual />

<#macro showFiles statement individual>
<a download="${statement.publicFilename}" title="${i18n().name}" href="${profileUrl(statement.url)}" >${statement.publicFilename}</a>
</#macro>