diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/search/query.post.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/search/query.post.desc.xml
index 163c7acbab..512c858832 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/search/query.post.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/search/query.post.desc.xml
@@ -31,6 +31,7 @@ It is recommended that “includeAllowableActions” be used with query statemen
/api/query
user
+
CMIS
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/allowableactions.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/allowableactions.get.desc.xml
index 12a2fd6469..d2e2ee5315 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/allowableactions.get.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/allowableactions.get.desc.xml
@@ -4,6 +4,7 @@
/api/node/{store_type}/{store_id}/{id}/permissions
/api/path/{store_type}/{store_id}/{id}/permissions
guest
+
argument
CMIS
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/checkedout.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/checkedout.get.desc.xml
index af8cb3f32c..a0aa4362eb 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/checkedout.get.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/checkedout.get.desc.xml
@@ -30,6 +30,7 @@ If no “maxItems” value is provided, then the Repository will determine an ap
/api/checkedout?folderId={folderId?}&includeDescendants={includeDescendants?}&filter={filter?}&skipCount={skipCount?}&maxItems={maxItems?}&includeAllowableActions={includeAllowableActions?}
user
+
CMIS
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.desc.xml
index 01d7e4de0e..f94e72a592 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.desc.xml
@@ -37,6 +37,7 @@ If no “maxItems” value is provided, then the Repository will determine an ap
/api/node/{store_type}/{store_id}/{id}/children?types={types}&filter={filter?}&skipCount={skipCount?}&maxItems={maxItems?}&includeAllowableActions={includeAllowableActions?}
/api/path/{store_type}/{store_id}/{id}/children?types={types}&filter={filter?}&skipCount={skipCount?}&maxItems={maxItems?}&includeAllowableActions={includeAllowableActions?}
guest
+
argument
CMIS
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/content.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/content.get.desc.xml
index ae2d6837a0..281e93cacc 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/content.get.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/content.get.desc.xml
@@ -26,6 +26,7 @@ Each CMIS protocol binding will provide a way for fetching a sub-range within a
/api/node/{store_type}/{store_id}/{id}/content{property}?a={attach?}
/api/path/{store_type}/{store_id}/{id}/content{property}?a={attach?}
guest
+
argument
CMIS
public_api
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/descendants.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/descendants.get.desc.xml
index 06cd1c561c..20dad2939f 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/descendants.get.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/descendants.get.desc.xml
@@ -35,6 +35,7 @@ If “includeAllowableActions” is TRUE, the repository will return the allowab
/api/node/{store_type}/{store_id}/{id}/descendants?types={types}&filter={filter?}&depth={depth?}&includeAllowableActions={includeAllowableActions?}
/api/path/{store_type}/{store_id}/{id}/descendants?types={types}&filter={filter?}&depth={depth?}&includeAllowableActions={includeAllowableActions?}
guest
+
argument
CMIS
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/item.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/item.get.desc.xml
index 598fae884e..6a2f11aaf4 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/item.get.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/item.get.desc.xml
@@ -30,6 +30,7 @@ PropertyCollection includes changeToken (if applicable to repository)
/api/path/{store_type}/{store_id}/{id}?filter={filter?}&returnVersion={returnVersion?}&filter={filter?}&includeAllowableActions={includeAllowableActions?}
guest
+
argument
CMIS
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/parent.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/parent.get.desc.xml
index d3db7639a1..be630d2193 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/parent.get.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/parent.get.desc.xml
@@ -29,6 +29,7 @@ If “includeAllowableActions” is TRUE, the repository will return the allowab
/api/node/{store_type}/{store_id}/{id}/parent?returnToRoot={returnToRoot}&filter={filter?}&includeAllowableActions={includeAllowableActions?}
/api/path/{store_type}/{store_id}/{id}/parent?returnToRoot={returnToRoot}&filter={filter?}&includeAllowableActions={includeAllowableActions?}
guest
+
argument
CMIS
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/parents.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/parents.get.desc.xml
index c98373e2db..df4a71e423 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/parents.get.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/parents.get.desc.xml
@@ -27,6 +27,7 @@ If “includeAllowableActions” is TRUE, the repository will return the allowab
/api/node/{store_type}/{store_id}/{id}/parents?filter={filter?}&includeAllowableActions={includeAllowableActions?}
/api/path/{store_type}/{store_id}/{id}/parents?filter={filter?}&includeAllowableActions={includeAllowableActions?}
guest
+
argument
CMIS
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/pwc.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/pwc.get.desc.xml
index 9b98336e51..4f3b020b9d 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/pwc.get.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/pwc.get.desc.xml
@@ -3,6 +3,7 @@
Retrieves the properties of a private working copy
/api/pwc/{store_type}/{store_id}/{id}?filter={filter?}
user
+
argument
CMIS
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/relationship.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/relationship.get.desc.xml
index 9ae462ecdb..533e36b6c5 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/relationship.get.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/relationship.get.desc.xml
@@ -4,6 +4,7 @@
/api/rel/{store_type}/{store_id}/{id}/type/{rel_type}/target/{target_store_type}/{target_store_id}/{target_id}?filter={filter?}&includeAllowableActions={includeAllowableActions?}
guest
+
argument
CMIS
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/type.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/type.get.desc.xml
index 7408978008..e75fc801c1 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/type.get.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/type.get.desc.xml
@@ -21,6 +21,7 @@ When includeInheritedProperties is true, the repository SHOULD return all proper
/api/type/{typeId}?includeInheritedProperties={includeInheritedProperties?}
user
+
CMIS
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/typechildren.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/typechildren.get.desc.xml
index 50950eb17f..5f0c5c86dc 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/typechildren.get.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/typechildren.get.desc.xml
@@ -3,6 +3,7 @@
Retrieve list of all child Types
/api/type/{typeId}/children?includePropertyDefinitions={includePropertyDefinitions?}&skipCount={skipCount?}&maxItems={maxItems?}
user
+
CMIS
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/typedescendants.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/typedescendants.get.desc.xml
index ea10576f49..31f858d94f 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/typedescendants.get.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/typedescendants.get.desc.xml
@@ -3,6 +3,7 @@
Retrieve list of all descendant Types
/api/type/{typeId}/descendants?includePropertyDefinitions={includePropertyDefinitions?}&skipCount={skipCount?}&maxItems={maxItems?}
user
+
CMIS
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/types.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/types.get.desc.xml
index 07e0cedc7f..3e880f5a42 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/types.get.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/types.get.desc.xml
@@ -28,6 +28,7 @@ If “returnPropertyDefinitions” is False, then the Repository will return onl
/api/types?type={type?}&includePropertyDefinitions={includePropertyDefinitions?}&skipCount={skipCount?}&maxItems={maxItems?}
user
+
CMIS
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/unfiled.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/unfiled.get.desc.xml
index 327e5b9c33..8f3237a878 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/unfiled.get.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/unfiled.get.desc.xml
@@ -3,6 +3,7 @@
Retrieve list of documents that are not in any folder
/api/unfiled
guest
+
CMIS
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/versions.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/versions.get.desc.xml
index b7cd1b1d87..82e489ff47 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/versions.get.desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/versions.get.desc.xml
@@ -21,6 +21,7 @@ Returns all versions the user can access including checked-out version and priva
/api/node/{store_type}/{store_id}/{id}/versions?filter={filter?}
/api/path/{store_type}/{store_id}/{id}/versions?filter={filter?}
user
+
argument
CMIS
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/cmis/rest/test/BulkCreateSystemTest.java b/source/java/org/alfresco/repo/cmis/rest/test/BulkCreateSystemTest.java
index dc1b1cd303..bf3a61aa4e 100644
--- a/source/java/org/alfresco/repo/cmis/rest/test/BulkCreateSystemTest.java
+++ b/source/java/org/alfresco/repo/cmis/rest/test/BulkCreateSystemTest.java
@@ -57,13 +57,12 @@ public class BulkCreateSystemTest
abdera.getFactory().registerExtension(new CMISExtensionFactory());
AbderaClient client = new AbderaClient(abdera);
- client.setMaxConnectionsTotal(1);
client.usePreemptiveAuthentication(true);
client.addCredentials("http://localhost:8080", null, "basic", new UsernamePasswordCredentials("admin", "admin"));
String root = createFolder(client,
"http://localhost:8080/alfresco/service/api/path/workspace/SpacesStore/Company%20Home/children",
- "testfolder7");
+ "testfolder14");
for (int i = 0; i < 100; i++)
{
diff --git a/source/java/org/alfresco/repo/web/scripts/RepoStore.java b/source/java/org/alfresco/repo/web/scripts/RepoStore.java
index cd416d6049..64fd39f019 100644
--- a/source/java/org/alfresco/repo/web/scripts/RepoStore.java
+++ b/source/java/org/alfresco/repo/web/scripts/RepoStore.java
@@ -243,7 +243,7 @@ public class RepoStore implements Store, TenantDeployer
"Web Script Store " + repoStore.toString() + repoPath + " must exist; it was not found");
}
}
- });
+ }, true, false);
}
}, AuthenticationUtil.getSystemUserName());
@@ -364,7 +364,7 @@ public class RepoStore implements Store, TenantDeployer
return documentPaths != null ? documentPaths.toArray(new String[documentPaths.size()]) : new String[0];
}
- });
+ }, true, false);
}
}, AuthenticationUtil.getSystemUserName());
}
@@ -423,7 +423,7 @@ public class RepoStore implements Store, TenantDeployer
}
return documentPaths.toArray(new String[documentPaths.size()]);
}
- });
+ }, true, false);
}
}, AuthenticationUtil.getSystemUserName());
}
@@ -499,7 +499,7 @@ public class RepoStore implements Store, TenantDeployer
return documentPaths.toArray(new String[documentPaths.size()]);
}
- });
+ }, true, false);
}
}, AuthenticationUtil.getSystemUserName());
}
@@ -521,7 +521,7 @@ public class RepoStore implements Store, TenantDeployer
findNodeRef(documentPath), ContentModel.PROP_CONTENT);
return reader.getLastModified();
}
- });
+ }, true, false);
}
}, AuthenticationUtil.getSystemUserName());
}
@@ -542,7 +542,7 @@ public class RepoStore implements Store, TenantDeployer
NodeRef nodeRef = findNodeRef(documentPath);
return (nodeRef != null);
}
- });
+ }, true, false);
}
}, AuthenticationUtil.getSystemUserName());
}
@@ -573,7 +573,7 @@ public class RepoStore implements Store, TenantDeployer
}
return reader.getContentInputStream();
}
- });
+ }, true, false);
}
}, AuthenticationUtil.getSystemUserName());
}
@@ -867,9 +867,9 @@ public class RepoStore implements Store, TenantDeployer
}
return location;
}
- });
+ }, true, false);
}
- }, AuthenticationUtil.getSystemUserName());
+ }, AuthenticationUtil.getSystemUserName());
}
}
diff --git a/source/java/org/alfresco/repo/web/scripts/RepositoryContainer.java b/source/java/org/alfresco/repo/web/scripts/RepositoryContainer.java
index 3ff95da1e6..1a49ec9add 100644
--- a/source/java/org/alfresco/repo/web/scripts/RepositoryContainer.java
+++ b/source/java/org/alfresco/repo/web/scripts/RepositoryContainer.java
@@ -24,7 +24,12 @@
*/
package org.alfresco.repo.web.scripts;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
@@ -32,6 +37,7 @@ import javax.servlet.http.HttpServletResponse;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
+import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.model.Repository;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
@@ -40,6 +46,7 @@ import org.alfresco.repo.tenant.TenantAdminService;
import org.alfresco.repo.tenant.TenantDeployer;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
+import org.alfresco.repo.transaction.TransactionListener;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.TemplateService;
@@ -47,15 +54,19 @@ import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.descriptor.DescriptorService;
import org.alfresco.web.scripts.AbstractRuntimeContainer;
import org.alfresco.web.scripts.Authenticator;
+import org.alfresco.web.scripts.Cache;
import org.alfresco.web.scripts.Description;
import org.alfresco.web.scripts.Registry;
+import org.alfresco.web.scripts.Runtime;
import org.alfresco.web.scripts.ServerModel;
import org.alfresco.web.scripts.WebScript;
import org.alfresco.web.scripts.WebScriptException;
import org.alfresco.web.scripts.WebScriptRequest;
import org.alfresco.web.scripts.WebScriptResponse;
+import org.alfresco.web.scripts.WrappingWebScriptResponse;
import org.alfresco.web.scripts.Description.RequiredAuthentication;
import org.alfresco.web.scripts.Description.RequiredTransaction;
+import org.alfresco.web.scripts.Description.TransactionCapability;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.ObjectFactory;
@@ -71,6 +82,9 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten
// Logger
protected static final Log logger = LogFactory.getLog(RepositoryContainer.class);
+ // Transaction key for buffered response
+ private static String BUFFERED_RESPONSE_KEY = RepositoryContainer.class.getName() + ".bufferedresponse";
+
/** Component Dependencies */
private Repository repository;
private RepositoryImageResolver imageResolver;
@@ -92,7 +106,8 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten
/**
* @param registryFactory
*/
- public void setRegistryFactory(ObjectFactory registryFactory) {
+ public void setRegistryFactory(ObjectFactory registryFactory)
+ {
this.registryFactory = registryFactory;
}
@@ -314,9 +329,22 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten
try
{
if (logger.isDebugEnabled())
- logger.debug("Begin retry transaction block: " + description.getRequiredTransaction());
+ logger.debug("Begin retry transaction block: " + description.getRequiredTransaction() + "," + description.getTransactionCapability());
+
+ WebScriptResponse redirectedRes = scriptRes;
+ if (description.getTransactionCapability() == TransactionCapability.readwrite)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Creating Transactional Response for ReadWrite transaction");
+
+ // create buffered response that's sensitive transaction boundary
+ BufferedResponse bufferedRes = new BufferedResponse(scriptRes);
+ AlfrescoTransactionSupport.bindResource(BUFFERED_RESPONSE_KEY, bufferedRes);
+ AlfrescoTransactionSupport.bindListener(bufferedRes);
+ redirectedRes = bufferedRes;
+ }
- script.execute(scriptReq, scriptRes);
+ script.execute(scriptReq, redirectedRes);
}
catch(Exception e)
{
@@ -356,21 +384,16 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten
finally
{
if (logger.isDebugEnabled())
- logger.debug("End retry transaction block: " + description.getRequiredTransaction());
+ logger.debug("End retry transaction block: " + description.getRequiredTransaction() + "," + description.getTransactionCapability());
}
return null;
}
};
- if (description.getRequiredTransaction() == RequiredTransaction.required)
- {
- retryingTransactionHelper.doInTransaction(work);
- }
- else
- {
- retryingTransactionHelper.doInTransaction(work, false, true);
- }
+ boolean readonly = description.getTransactionCapability() == TransactionCapability.readonly;
+ boolean requiresNew = description.getRequiredTransaction() == RequiredTransaction.requiresnew;
+ retryingTransactionHelper.doInTransaction(work, readonly, requiresNew);
}
}
@@ -465,4 +488,213 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten
{
webScriptsRegistryCache.remove(tenantAdminService.getCurrentUserDomain());
}
+
+
+ /**
+ * Transactional Buffered Response
+ */
+ private static class BufferedResponse implements TransactionListener, WrappingWebScriptResponse
+ {
+ private WebScriptResponse res;
+ private ByteArrayOutputStream outputStream;
+ private OutputStreamWriter outputWriter;
+
+ /**
+ * Construct
+ *
+ * @param res
+ */
+ public BufferedResponse(WebScriptResponse res)
+ {
+ this.res = res;
+ this.outputStream = new ByteArrayOutputStream(4096);
+ try
+ {
+ this.outputWriter = new OutputStreamWriter(outputStream, "UTF-8");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new AlfrescoRuntimeException("Failed to create buffered response", e);
+ };
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.web.scripts.WrappingWebScriptResponse#getNext()
+ */
+ public WebScriptResponse getNext()
+ {
+ return res;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptResponse#addHeader(java.lang.String, java.lang.String)
+ */
+ public void addHeader(String name, String value)
+ {
+ res.addHeader(name, value);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptResponse#encodeScriptUrl(java.lang.String)
+ */
+ public String encodeScriptUrl(String url)
+ {
+ return res.encodeScriptUrl(url);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptResponse#getEncodeScriptUrlFunction(java.lang.String)
+ */
+ public String getEncodeScriptUrlFunction(String name)
+ {
+ return res.getEncodeScriptUrlFunction(name);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptResponse#getOutputStream()
+ */
+ public OutputStream getOutputStream() throws IOException
+ {
+ return outputStream;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptResponse#getRuntime()
+ */
+ public Runtime getRuntime()
+ {
+ return res.getRuntime();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptResponse#getWriter()
+ */
+ public Writer getWriter() throws IOException
+ {
+ return outputWriter;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptResponse#reset()
+ */
+ public void reset()
+ {
+ outputStream.reset();
+ res.reset();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptResponse#setCache(org.alfresco.web.scripts.Cache)
+ */
+ public void setCache(Cache cache)
+ {
+ res.setCache(cache);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptResponse#setContentType(java.lang.String)
+ */
+ public void setContentType(String contentType)
+ {
+ res.setContentType(contentType);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptResponse#setContentEncoding(java.lang.String)
+ */
+ public void setContentEncoding(String contentEncoding)
+ {
+ res.setContentEncoding(contentEncoding);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptResponse#setHeader(java.lang.String, java.lang.String)
+ */
+ public void setHeader(String name, String value)
+ {
+ res.setHeader(name, value);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptResponse#setStatus(int)
+ */
+ public void setStatus(int status)
+ {
+ res.setStatus(status);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.repo.transaction.TransactionListener#afterCommit()
+ */
+ public void afterCommit()
+ {
+ writeResponse();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.repo.transaction.TransactionListener#afterRollback()
+ */
+ public void afterRollback()
+ {
+ writeResponse();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.repo.transaction.TransactionListener#beforeCommit(boolean)
+ */
+ public void beforeCommit(boolean readOnly)
+ {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.repo.transaction.TransactionListener#beforeCompletion()
+ */
+ public void beforeCompletion()
+ {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.repo.transaction.TransactionListener#flush()
+ */
+ public void flush()
+ {
+ }
+
+ /**
+ * Write buffered response to underlying response
+ */
+ private void writeResponse()
+ {
+ try
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Writing Transactional response: size=" + outputStream.size());
+
+ outputStream.flush();
+ outputStream.writeTo(res.getOutputStream());
+ }
+ catch (IOException e)
+ {
+ throw new AlfrescoRuntimeException("Failed to commit buffered response", e);
+ }
+ }
+ }
}
diff --git a/source/java/org/alfresco/repo/web/scripts/bean/AVMRemoteStore.java b/source/java/org/alfresco/repo/web/scripts/bean/AVMRemoteStore.java
index b75f89340e..4abe864aa5 100644
--- a/source/java/org/alfresco/repo/web/scripts/bean/AVMRemoteStore.java
+++ b/source/java/org/alfresco/repo/web/scripts/bean/AVMRemoteStore.java
@@ -46,7 +46,6 @@ import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.web.scripts.Status;
import org.alfresco.web.scripts.WebScriptException;
import org.alfresco.web.scripts.WebScriptResponse;
-import org.alfresco.web.scripts.servlet.WebScriptServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -167,11 +166,10 @@ public class AVMRemoteStore extends BaseRemoteStore
}
// set mimetype for the content and the character encoding + length for the stream
- WebScriptServletResponse httpRes = (WebScriptServletResponse)res;
- httpRes.setContentType(mimetype);
- httpRes.getHttpServletResponse().setCharacterEncoding(reader.getEncoding());
- httpRes.getHttpServletResponse().setDateHeader("Last-Modified", desc.getModDate());
- httpRes.setHeader("Content-Length", Long.toString(reader.getSize()));
+ res.setContentType(mimetype);
+ res.setContentEncoding(reader.getEncoding());
+ res.setHeader("Last-Modified", Long.toString(desc.getModDate()));
+ res.setHeader("Content-Length", Long.toString(reader.getSize()));
if (logger.isDebugEnabled())
logger.debug("AVMRemoteStore.getDocument() " + mimetype + " of size: " + reader.getSize());
diff --git a/source/java/org/alfresco/repo/web/scripts/bean/SearchProxy.java b/source/java/org/alfresco/repo/web/scripts/bean/SearchProxy.java
index bf56f81657..1b6976c6f5 100644
--- a/source/java/org/alfresco/repo/web/scripts/bean/SearchProxy.java
+++ b/source/java/org/alfresco/repo/web/scripts/bean/SearchProxy.java
@@ -47,7 +47,7 @@ import org.alfresco.web.scripts.WebScriptException;
import org.alfresco.web.scripts.WebScriptRequest;
import org.alfresco.web.scripts.WebScriptResponse;
import org.alfresco.web.scripts.servlet.HTTPProxy;
-import org.alfresco.web.scripts.servlet.WebScriptServletResponse;
+import org.alfresco.web.scripts.servlet.WebScriptServletRuntime;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Attribute;
@@ -166,11 +166,12 @@ public class SearchProxy extends AbstractWebScript implements InitializingBean
// issue request against search engine
// NOTE: This web script must be executed in a HTTP servlet environment
- if (!(res instanceof WebScriptServletResponse))
+ if (!(res.getRuntime() instanceof WebScriptServletRuntime))
{
throw new WebScriptException("Search Proxy must be executed in HTTP Servlet environment");
}
- HttpServletResponse servletRes = ((WebScriptServletResponse)res).getHttpServletResponse();
+
+ HttpServletResponse servletRes = WebScriptServletRuntime.getHttpServletResponse(res);
SearchEngineHttpProxy proxy = new SearchEngineHttpProxy(req.getServicePath() + "/" + req.getContextPath(), engine, engineUrl, servletRes);
proxy.service();
}
diff --git a/source/java/org/alfresco/repo/web/scripts/content/StreamContent.java b/source/java/org/alfresco/repo/web/scripts/content/StreamContent.java
index 03a1643108..eeb136424b 100644
--- a/source/java/org/alfresco/repo/web/scripts/content/StreamContent.java
+++ b/source/java/org/alfresco/repo/web/scripts/content/StreamContent.java
@@ -35,7 +35,6 @@ import java.util.Date;
import java.util.HashMap;
import java.util.Map;
-import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.model.ContentModel;
@@ -58,8 +57,6 @@ import org.alfresco.web.scripts.WebScriptException;
import org.alfresco.web.scripts.WebScriptRequest;
import org.alfresco.web.scripts.WebScriptResponse;
import org.alfresco.web.scripts.WebScriptStatus;
-import org.alfresco.web.scripts.servlet.WebScriptServletRequest;
-import org.alfresco.web.scripts.servlet.WebScriptServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.FileCopyUtils;
@@ -298,14 +295,6 @@ public class StreamContent extends AbstractWebScript
protected void streamContent(WebScriptRequest req, WebScriptResponse res, NodeRef nodeRef, QName propertyQName, boolean attach)
throws IOException
{
- // NOTE: This web script must be executed in a HTTP Servlet environment
- if (!(req instanceof WebScriptServletRequest))
- {
- throw new WebScriptException("Content retrieval must be executed in HTTP Servlet environment");
- }
- HttpServletRequest httpReq = ((WebScriptServletRequest)req).getHttpServletRequest();
- HttpServletResponse httpRes = ((WebScriptServletResponse)res).getHttpServletResponse();
-
if (logger.isDebugEnabled())
logger.debug("Retrieving content from node ref " + nodeRef.toString() + " (property: " + propertyQName.toString() + ") (attach: " + attach + ")");
@@ -317,14 +306,19 @@ public class StreamContent extends AbstractWebScript
// check If-Modified-Since header and set Last-Modified header as appropriate
Date modified = (Date)nodeService.getProperty(nodeRef, ContentModel.PROP_MODIFIED);
- long modifiedSince = httpReq.getDateHeader("If-Modified-Since");
+ String modifiedSinceStr = req.getHeader("If-Modified-Since");
+ if (modifiedSinceStr == null)
+ {
+ modifiedSinceStr = "-1";
+ }
+ long modifiedSince = new Long(modifiedSinceStr);
if (modifiedSince > 0L)
{
// round the date to the ignore millisecond value which is not supplied by header
long modDate = (modified.getTime() / 1000L) * 1000L;
if (modDate <= modifiedSince)
{
- httpRes.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+ res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
return;
}
}
@@ -337,7 +331,7 @@ public class StreamContent extends AbstractWebScript
}
// Stream the cotent
- streamContentImpl(req, res, reader, attach, modified, String.valueOf(modifiedSince));
+ streamContentImpl(req, res, reader, attach, modified, String.valueOf(modifiedSince));
}
/**
@@ -398,15 +392,12 @@ public class StreamContent extends AbstractWebScript
protected void streamContentImpl(WebScriptRequest req, WebScriptResponse res, ContentReader reader, boolean attach, Date modified, String eTag)
throws IOException
{
- HttpServletRequest httpReq = ((WebScriptServletRequest)req).getHttpServletRequest();
- HttpServletResponse httpRes = ((WebScriptServletResponse)res).getHttpServletResponse();
-
// handle attachment
if (attach == true)
{
// set header based on filename - will force a Save As from the browse if it doesn't recognize it
// this is better than the default response of the browser trying to display the contents
- httpRes.setHeader("Content-Disposition", "attachment");
+ res.setHeader("Content-Disposition", "attachment");
}
// establish mimetype
@@ -428,9 +419,9 @@ public class StreamContent extends AbstractWebScript
}
// set mimetype for the content and the character encoding + length for the stream
- httpRes.setContentType(mimetype);
- httpRes.setCharacterEncoding(reader.getEncoding());
- httpRes.setHeader("Content-Length", Long.toString(reader.getSize()));
+ res.setContentType(mimetype);
+ res.setContentEncoding(reader.getEncoding());
+ res.setHeader("Content-Length", Long.toString(reader.getSize()));
// set caching
Cache cache = new Cache();