From 9f7c5d6443a1ec9a94b3f6ccaf3b92c4be3f7393 Mon Sep 17 00:00:00 2001 From: Derek Hulley Date: Thu, 2 Aug 2007 23:44:15 +0000 Subject: [PATCH] Merged V2.1 to HEAD 6374: AR-1639 Web Script Content Upload Patch merge: Schema target 71 changed to 101 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6404 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/bootstrap/webScripts2.xml | 79 ++++++++ .../bootstrap/webscripts/upload.get.desc.xml | 6 + .../bootstrap/webscripts/upload.get.html.ftl | 27 +++ .../bootstrap/webscripts/upload.post.desc.xml | 6 + .../bootstrap/webscripts/upload.post.html.ftl | 19 ++ .../bootstrap/webscripts/upload.post.js | 43 +++++ .../messages/patch-service.properties | 1 + .../alfresco/patch/patch-services-context.xml | 17 ++ config/alfresco/version.properties | 2 +- .../org/alfresco/repo/jscript/ScriptNode.java | 179 ++++++++++++++++-- 10 files changed, 360 insertions(+), 19 deletions(-) create mode 100644 config/alfresco/bootstrap/webScripts2.xml create mode 100644 config/alfresco/bootstrap/webscripts/upload.get.desc.xml create mode 100644 config/alfresco/bootstrap/webscripts/upload.get.html.ftl create mode 100644 config/alfresco/bootstrap/webscripts/upload.post.desc.xml create mode 100644 config/alfresco/bootstrap/webscripts/upload.post.html.ftl create mode 100644 config/alfresco/bootstrap/webscripts/upload.post.js diff --git a/config/alfresco/bootstrap/webScripts2.xml b/config/alfresco/bootstrap/webScripts2.xml new file mode 100644 index 0000000000..7a78f00f1b --- /dev/null +++ b/config/alfresco/bootstrap/webScripts2.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + true + contentUrl=classpath:alfresco/bootstrap/webscripts/upload.get.desc.xml|mimetype=text/xml|size=|encoding=UTF-8|locale=en_US_ + + + upload.get.desc.xml + + + + + + + + + + true + contentUrl=classpath:alfresco/bootstrap/webscripts/upload.get.html.ftl|mimetype=text/plain|size=|encoding=UTF-8|locale=en_US_ + + + upload.get.html.ftl + + + + + + + + + + true + contentUrl=classpath:alfresco/bootstrap/webscripts/upload.post.desc.xml|mimetype=text/xml|size=|encoding=UTF-8|locale=en_US_ + + + upload.post.desc.xml + + + + + + + + + + true + contentUrl=classpath:alfresco/bootstrap/webscripts/upload.post.js|mimetype=application/x-javascript|size=|encoding=UTF-8|locale=en_US_ + + + upload.post.js + + + + + + + + + + true + contentUrl=classpath:alfresco/bootstrap/webscripts/upload.post.html.ftl|mimetype=text/plain|size=|encoding=UTF-8|locale=en_US_ + + + upload.post.html.ftl + + + + + + \ No newline at end of file diff --git a/config/alfresco/bootstrap/webscripts/upload.get.desc.xml b/config/alfresco/bootstrap/webscripts/upload.get.desc.xml new file mode 100644 index 0000000000..cb51741f97 --- /dev/null +++ b/config/alfresco/bootstrap/webscripts/upload.get.desc.xml @@ -0,0 +1,6 @@ + + File Upload Form Sample + Form for uploading file content and meta-data into Repository + /sample/upload + user + \ No newline at end of file diff --git a/config/alfresco/bootstrap/webscripts/upload.get.html.ftl b/config/alfresco/bootstrap/webscripts/upload.get.html.ftl new file mode 100644 index 0000000000..4dffeaf35c --- /dev/null +++ b/config/alfresco/bootstrap/webscripts/upload.get.html.ftl @@ -0,0 +1,27 @@ + + + + + Upload Web Script Sample + + + + + + + + +
AlfrescoUpload Web Script Sample
Alfresco ${server.edition} v${server.version} +
+

+ + +
File: +
Title: +
Description: +
+
+ +
+ + diff --git a/config/alfresco/bootstrap/webscripts/upload.post.desc.xml b/config/alfresco/bootstrap/webscripts/upload.post.desc.xml new file mode 100644 index 0000000000..94edc2e90f --- /dev/null +++ b/config/alfresco/bootstrap/webscripts/upload.post.desc.xml @@ -0,0 +1,6 @@ + + File Upload Sample + Upload file content and meta-data into Repository + /sample/upload + user + \ No newline at end of file diff --git a/config/alfresco/bootstrap/webscripts/upload.post.html.ftl b/config/alfresco/bootstrap/webscripts/upload.post.html.ftl new file mode 100644 index 0000000000..aaa4a0e033 --- /dev/null +++ b/config/alfresco/bootstrap/webscripts/upload.post.html.ftl @@ -0,0 +1,19 @@ + + + + + Upload Web Script Sample + + + + + + + + +
AlfrescoUpload Web Script Sample
Alfresco ${server.edition} v${server.version} +
  +
Uploaded ${upload.name} of size ${upload.properties.content.size}. +
+ + diff --git a/config/alfresco/bootstrap/webscripts/upload.post.js b/config/alfresco/bootstrap/webscripts/upload.post.js new file mode 100644 index 0000000000..d1337ff1c5 --- /dev/null +++ b/config/alfresco/bootstrap/webscripts/upload.post.js @@ -0,0 +1,43 @@ +var filename = null; +var content = null; +var title = ""; +var description = ""; + +// locate file attributes +for each (field in formdata.fields) +{ + if (field.name == "title") + { + title = field.value; + } + else if (field.name == "desc") + { + description = field.value; + } + else if (field.name == "file" && field.isFile) + { + filename = field.filename; + content = field.content; + } +} + +// ensure mandatory file attributes have been located +if (filename == undefined || content == undefined) +{ + status.code = 400; + status.message = "Uploaded file cannot be located in request"; + status.redirect = true; +} +else +{ + // create document in company home for uploaded file + upload = companyhome.createFile("upload" + companyhome.children.length + "_" + filename) ; + upload.properties.content.write(content); + upload.properties.content.mimetype = "UTF-8"; + upload.properties.title = title; + upload.properties.description = description; + upload.save(); + + // setup model for response template + model.upload = upload; +} \ No newline at end of file diff --git a/config/alfresco/messages/patch-service.properties b/config/alfresco/messages/patch-service.properties index 5e1046dcc6..6bf835d84e 100644 --- a/config/alfresco/messages/patch-service.properties +++ b/config/alfresco/messages/patch-service.properties @@ -147,6 +147,7 @@ patch.AVMGuidPatch.description=Set GUIDs on AVM nodes. patch.AVMGuidPatch.result=AVM GUIDS set. patch.webscripts.description=Adds Web Scripts to Data Dictionary. +patch.webscripts2.description=Adds Web Scripts (second set) to Data Dictionary. patch.webscriptsExtension.description=Adds Web Scripts Extension to Data Dictionary. patch.AVMLayeredSnapshot.description=Set indirectionVersion on Layered Nodes. diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml index efc47dcf36..d6f849a9e6 100644 --- a/config/alfresco/patch/patch-services-context.xml +++ b/config/alfresco/patch/patch-services-context.xml @@ -890,5 +890,22 @@ classpath:alfresco/dbscripts/upgrade/2.1/${db.script.dialect}/AlfrescoSchemaUpdate-2.1-VersionColumns.sql + + + patch.webscripts2 + patch.webscripts2.description + 0 + 100 + 101 + + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname} + alfresco/bootstrap/webScripts2.xml + + + diff --git a/config/alfresco/version.properties b/config/alfresco/version.properties index 2ae0d49c0e..04466a502f 100644 --- a/config/alfresco/version.properties +++ b/config/alfresco/version.properties @@ -19,4 +19,4 @@ version.build=@build-number@ # Schema number -version.schema=100 +version.schema=101 diff --git a/source/java/org/alfresco/repo/jscript/ScriptNode.java b/source/java/org/alfresco/repo/jscript/ScriptNode.java index 3971d32c53..ddffb3d6eb 100644 --- a/source/java/org/alfresco/repo/jscript/ScriptNode.java +++ b/source/java/org/alfresco/repo/jscript/ScriptNode.java @@ -24,6 +24,9 @@ */ package org.alfresco.repo.jscript; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; @@ -51,14 +54,13 @@ import org.alfresco.service.cmr.model.FileNotFoundException; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentData; +import org.alfresco.service.cmr.repository.ContentIOException; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentWriter; -import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.repository.TemplateException; import org.alfresco.service.cmr.repository.TemplateImageResolver; import org.alfresco.service.cmr.search.QueryParameterDefinition; import org.alfresco.service.cmr.security.AccessPermission; @@ -77,6 +79,7 @@ import org.mozilla.javascript.Context; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; import org.mozilla.javascript.Wrapper; +import org.springframework.util.FileCopyUtils; import org.springframework.util.StringUtils; /** @@ -2093,10 +2096,63 @@ public class ScriptNode implements Serializable, Scopeable // ------------------------------------------------------------------------------ // Inner Classes + + /** + * Inner class for representing content + */ + public static abstract class ScriptContent implements Serializable + { + /** + * @return the content stream as a string + */ + public abstract String getContent(); + + public String jsGet_content() + { + return getContent(); + } + + /** + * @return the content mimetype + */ + public abstract String getMimetype(); + + public String jsGet_mimetype() + { + return getMimetype(); + } + + /** + * @return the content encoding + */ + public abstract String getEncoding(); + + public String jsGet_encoding() + { + return getEncoding(); + } + + /** + * @return the content size + */ + public abstract long getSize(); + + public long jsGet_size() + { + return getSize(); + } + + /** + * @return input stream onto content + */ + /*package*/ abstract InputStream getInputStream(); + } + + /** * Inner class wrapping and providing access to a ContentData property */ - public class ScriptContentData implements Serializable + public class ScriptContentData extends ScriptContent implements Serializable { private static final long serialVersionUID = -7819328543933312278L; @@ -2111,9 +2167,9 @@ public class ScriptNode implements Serializable, Scopeable this.contentData = contentData; this.property = property; } - - /** - * @return the content stream + + /* (non-Javadoc) + * @see org.alfresco.repo.jscript.ScriptNode.ScriptContent#getContent() */ public String getContent() { @@ -2123,9 +2179,12 @@ public class ScriptNode implements Serializable, Scopeable return (reader != null && reader.exists()) ? reader.getContentString() : ""; } - public String jsGet_content() + /*package*/ InputStream getInputStream() { - return getContent(); + ContentService contentService = services.getContentService(); + ContentReader reader = contentService.getReader(nodeRef, property); + + return (reader != null && reader.exists()) ? reader.getContentInputStream() : null; } /** @@ -2148,7 +2207,24 @@ public class ScriptNode implements Serializable, Scopeable { setContent(content); } - + + /** + * Set the content stream from another content object + * + * @param content ScriptContent to set + */ + public void write(ScriptContent content) + { + ContentService contentService = services.getContentService(); + ContentWriter writer = contentService.getWriter(nodeRef, this.property, true); + writer.setMimetype(content.getMimetype()); + writer.setEncoding(content.getEncoding()); + writer.putContent(content.getInputStream()); + + // update cached variables after putContent() + this.contentData = (ContentData) services.getNodeService().getProperty(nodeRef, this.property); + } + /** * @return download URL to the content */ @@ -2203,28 +2279,22 @@ public class ScriptNode implements Serializable, Scopeable { return getDownloadUrl(); } - public long getSize() { return contentData.getSize(); } - public long jsGet_size() - { - return getSize(); - } - public String getMimetype() { return contentData.getMimetype(); } - public String jsGet_mimetype() + public String getEncoding() { - return getMimetype(); + return contentData.getEncoding(); } - + public void setMimetype(String mimetype) { this.contentData = ContentData.setMimetype(this.contentData, mimetype); @@ -2244,6 +2314,79 @@ public class ScriptNode implements Serializable, Scopeable private QName property; } + + /** + * Inner class wrapping and providing access to a Content stream + */ + public static class ScriptContentStream extends ScriptContent implements Serializable + { + private static final long serialVersionUID = -7819328543933312278L; + + /** + * Constructor + * + * @param stream content input stream + * @param mimetype content mimetype + */ + public ScriptContentStream(InputStream stream, String mimetype, String encoding) + { + this.stream = stream; + this.mimetype = mimetype; + this.encoding = encoding; + } + + /* (non-Javadoc) + * @see org.alfresco.repo.jscript.ScriptNode.ScriptContent#getContent() + */ + public String getContent() + { + try + { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + FileCopyUtils.copy(stream, os); // both streams are closed + byte[] bytes = os.toByteArray(); + // get the encoding for the string + String encoding = getEncoding(); + // create the string from the byte[] using encoding if necessary + String content = (encoding == null) ? new String(bytes) : new String(bytes, encoding); + // done + return content; + } + catch (IOException e) + { + throw new ContentIOException("Failed to copy content to string", e); + } + } + + /*package*/ InputStream getInputStream() + { + return stream; + } + + public long getSize() + { + return -1; + } + + public String getMimetype() + { + return mimetype; + } + + public String getEncoding() + { + return encoding; + } + + + private InputStream stream; + + private String mimetype; + + private String encoding; + } + + /** * Interface contract for simple anonymous classes that implement document transformations */