mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Web Scripts:
- Addition of reponse status code and template support - Appropriate status codes added to login & ticket web scripts - Web Script Index page also mapped to / url - Various fixes applied to url to web script mapping git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5846 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -1 +1,86 @@
|
|||||||
testserver.help=alfresco/messages/webscripts-test-help.txt
|
##
|
||||||
|
## Web Script Response Codes
|
||||||
|
##
|
||||||
|
webscript.code.100.name=Continue
|
||||||
|
webscript.code.100.description=Client can continue.
|
||||||
|
webscript.code.101.name=Switching Protocols
|
||||||
|
webscript.code.101.description=The server is switching protocols according to Upgrade header.
|
||||||
|
webscript.code.200.name=OK
|
||||||
|
webscript.code.200.description=The request succeeded normally.
|
||||||
|
webscript.code.201.name=Created
|
||||||
|
webscript.code.201.description=Request succeeded and created a new resource on the server.
|
||||||
|
webscript.code.202.name=Accepted
|
||||||
|
webscript.code.202.description=Request was accepted for processing, but was not completed.
|
||||||
|
webscript.code.203.name=Non authoritative information
|
||||||
|
webscript.code.203.description=The meta information presented by the client did not originate from the server.
|
||||||
|
webscript.code.204.name=No ContentSC_NO_CONTENT
|
||||||
|
webscript.code.204.description=The request succeeded but that there was no new information to return.
|
||||||
|
webscript.code.205.name=Reset Content
|
||||||
|
webscript.code.205.description=The agent SHOULD reset the document view which caused the request to be sent.
|
||||||
|
webscript.code.206.name=Partial Content
|
||||||
|
webscript.code.206.description=The server has fulfilled the partial GET request for the resource.
|
||||||
|
webscript.code.300.name=Multiple Choices
|
||||||
|
webscript.code.300.description=The requested resource corresponds to any one of a set of representations, each with its own specific location.
|
||||||
|
webscript.code.301.name=Moved Permanently
|
||||||
|
webscript.code.301.description=The resource has permanently moved to a new location, and that future references should use a new URI with their requests.
|
||||||
|
webscript.code.302.name=Moved Temporarily
|
||||||
|
webscript.code.302.description=The resource has temporarily moved to another location, but that future references should still use the original URI to access the resource.
|
||||||
|
webscript.code.303.name=See Other
|
||||||
|
webscript.code.303.description=The response to the request can be found under a different URI.
|
||||||
|
webscript.code.304.name=Not Modified
|
||||||
|
webscript.code.304.description=A conditional GET operation found that the resource was available and not modified.
|
||||||
|
webscript.code.305.name=Use Proxy
|
||||||
|
webscript.code.305.description=The requested resource MUST be accessed through the proxy given by the Location field.
|
||||||
|
webscript.code.400.name=Bad Request
|
||||||
|
webscript.code.400.description=Request sent by the client was syntactically incorrect.
|
||||||
|
webscript.code.401.name=Unauthorized
|
||||||
|
webscript.code.401.description=The request requires HTTP authentication.
|
||||||
|
webscript.code.402.name=Payment Required
|
||||||
|
webscript.code.402.description=Reserved for future use.
|
||||||
|
webscript.code.403.name=Forbidden
|
||||||
|
webscript.code.403.description=Server understood the request but refused to fulfill it.
|
||||||
|
webscript.code.404.name=Not Found
|
||||||
|
webscript.code.404.description=Requested resource is not available.
|
||||||
|
webscript.code.405.name=Method Not Allowed
|
||||||
|
webscript.code.405.description=The method specified in the Request-Line is not allowed for the resource identified by the Request-URI.
|
||||||
|
webscript.code.406.name=Not Acceptable
|
||||||
|
webscript.code.406.description=The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request.
|
||||||
|
webscript.code.407.name=Proxy Authentication Required
|
||||||
|
webscript.code.407.description=The client MUST first authenticate itself with the proxy.
|
||||||
|
webscript.code.408.name=Request Timeout
|
||||||
|
webscript.code.408.description=The client did not produce a request within the time that the server was prepared to wait.
|
||||||
|
webscript.code.409.name=Conflict
|
||||||
|
webscript.code.409.description=Request could not be completed due to a conflict with the current state of the resource.
|
||||||
|
webscript.code.410.name=Gone
|
||||||
|
webscript.code.410.description=Resource is no longer available at the server and no forwarding address is known.
|
||||||
|
webscript.code.411.name=Length required
|
||||||
|
webscript.code.411.description=Request cannot be handled without a defined Content-Length.
|
||||||
|
webscript.code.412.name=Precondition Failed
|
||||||
|
webscript.code.412.description=The precondition given in one or more of the request-header fields evaluated to false when it was tested on the server.
|
||||||
|
webscript.code.413.name=Request Entity Too Large
|
||||||
|
webscript.code.413.description=The server is refusing to process the request because the request entity is larger than the server is willing or able to process.
|
||||||
|
webscript.code.414.name=Request URI Too Long
|
||||||
|
webscript.code.414.description=The server is refusing to service the request because the Request-URI is longer than the server is willing to interpret.
|
||||||
|
webscript.code.415.name=Unsupported Media Type
|
||||||
|
webscript.code.415.description=The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method.
|
||||||
|
webscript.code.416.name=Requested Range Not Satisfiable
|
||||||
|
webscript.code.416.description=The server cannot serve the requested byte range.
|
||||||
|
webscript.code.417.name=Expectation Failed
|
||||||
|
webscript.code.417.description=Server could not meet the expectation given in the Expect request header.
|
||||||
|
webscript.code.500.name=Internal Error
|
||||||
|
webscript.code.500.description=An error inside the HTTP server which prevented it from fulfilling the request.
|
||||||
|
webscript.code.501.name=Not Implemented
|
||||||
|
webscript.code.501.description=The HTTP server does not support the functionality needed to fulfill the request.
|
||||||
|
webscript.code.502.name=Bad Gateway
|
||||||
|
webscript.code.502.description=HTTP server received an invalid response from a server it consulted when acting as a proxy or gateway.
|
||||||
|
webscript.code.503.name=Service Unavailable
|
||||||
|
webscript.code.503.description=The HTTP server is temporarily overloaded, and unable to handle the request.
|
||||||
|
webscript.code.504.name=Gateway Timeout
|
||||||
|
webscript.code.504.description=Server did not receive a timely response from the upstream server while acting as a gateway or proxy.
|
||||||
|
webscript.code.505.name=HTTP version not supported
|
||||||
|
webscript.code.505.description=Server does not support or refuses to support the HTTP protocol version that was used in the request message.
|
||||||
|
|
||||||
|
##
|
||||||
|
## Test Web Script Server Help
|
||||||
|
##
|
||||||
|
testserver.help=alfresco/messages/webscripts-test-help.txt
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
<webscript>
|
<webscript>
|
||||||
<shortname>Web Scripts Documentation</shortname>
|
<shortname>Web Scripts Documentation</shortname>
|
||||||
<description>Web Scripts Documentation</description>
|
<description>Web Scripts Documentation</description>
|
||||||
|
<url format="html" template="/" />
|
||||||
<url format="html" template="/index" />
|
<url format="html" template="/index" />
|
||||||
</webscript>
|
</webscript>
|
33
config/alfresco/templates/webscripts/status.ftl
Normal file
33
config/alfresco/templates/webscripts/status.ftl
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>Web Script Status ${status.code} - ${status.codeName}</title>
|
||||||
|
<link rel="stylesheet" href="${url.context}/css/main.css" TYPE="text/css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><img src="${url.context}/images/logo/AlfrescoLogo32.png" alt="Alfresco" /></td>
|
||||||
|
<td><nobr><span class="mainTitle">Web Script Status ${status.code} - ${status.codeName}</span></nobr></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<br>
|
||||||
|
<table>
|
||||||
|
<tr><td>The Web Script <a href="${url.full}">${url.service}</a> has responded with a status of ${status.code} - ${status.codeName}.
|
||||||
|
</table>
|
||||||
|
<br>
|
||||||
|
<table>
|
||||||
|
<tr><td><b>${status.code} Description:</b><td> ${status.codeDescription}
|
||||||
|
<tr><td>
|
||||||
|
<tr><td><b>Message:</b><td>${status.message!"<i><Not specified></i>"}
|
||||||
|
<tr><td><b>Exception:</b><td>${status.exception!"None"}
|
||||||
|
<#if status.exception?exists>
|
||||||
|
<tr><td><td>
|
||||||
|
<#list status.exception.stackTrace as element>
|
||||||
|
<tr><td><td>${element}
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -3,6 +3,19 @@
|
|||||||
|
|
||||||
<beans>
|
<beans>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- Web Script Resource Bundles -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<bean id="webscripts.resources" class="org.alfresco.i18n.ResourceBundleBootstrapComponent">
|
||||||
|
<property name="resourceBundles">
|
||||||
|
<list>
|
||||||
|
<value>alfresco.messages.webscripts</value>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<!-- API Definition & Implementation Storage -->
|
<!-- API Definition & Implementation Storage -->
|
||||||
<!-- -->
|
<!-- -->
|
||||||
|
@@ -24,10 +24,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.web.scripts;
|
package org.alfresco.web.scripts;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
import org.alfresco.repo.jscript.Node;
|
import org.alfresco.repo.jscript.Node;
|
||||||
import org.alfresco.repo.jscript.ScriptableHashMap;
|
import org.alfresco.repo.jscript.ScriptableHashMap;
|
||||||
@@ -39,6 +41,8 @@ import org.alfresco.service.cmr.repository.TemplateService;
|
|||||||
import org.alfresco.service.descriptor.DescriptorService;
|
import org.alfresco.service.descriptor.DescriptorService;
|
||||||
import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
|
import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
|
||||||
import org.alfresco.web.scripts.WebScriptDescription.RequiredTransaction;
|
import org.alfresco.web.scripts.WebScriptDescription.RequiredTransaction;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,12 +52,19 @@ import org.alfresco.web.scripts.WebScriptDescription.RequiredTransaction;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractWebScript implements WebScript
|
public abstract class AbstractWebScript implements WebScript
|
||||||
{
|
{
|
||||||
|
// Logger
|
||||||
|
private static final Log logger = LogFactory.getLog(AbstractWebScript.class);
|
||||||
|
|
||||||
// dependencies
|
// dependencies
|
||||||
private WebScriptContext scriptContext;
|
private WebScriptContext scriptContext;
|
||||||
private WebScriptRegistry scriptRegistry;
|
private WebScriptRegistry scriptRegistry;
|
||||||
private WebScriptDescription description;
|
private WebScriptDescription description;
|
||||||
private ServiceRegistry serviceRegistry;
|
private ServiceRegistry serviceRegistry;
|
||||||
private DescriptorService descriptorService;
|
private DescriptorService descriptorService;
|
||||||
|
|
||||||
|
// Status Template cache
|
||||||
|
private Map<String, StatusTemplate> statusTemplates = new HashMap<String, StatusTemplate>();
|
||||||
|
private ReentrantReadWriteLock statusTemplateLock = new ReentrantReadWriteLock();
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -102,6 +113,15 @@ public abstract class AbstractWebScript implements WebScript
|
|||||||
public void init(WebScriptRegistry scriptRegistry)
|
public void init(WebScriptRegistry scriptRegistry)
|
||||||
{
|
{
|
||||||
this.scriptRegistry = scriptRegistry;
|
this.scriptRegistry = scriptRegistry;
|
||||||
|
this.statusTemplateLock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.statusTemplates.clear();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
this.statusTemplateLock.writeLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -184,12 +204,11 @@ public abstract class AbstractWebScript implements WebScript
|
|||||||
* Create a model for script usage
|
* Create a model for script usage
|
||||||
*
|
*
|
||||||
* @param req web script request
|
* @param req web script request
|
||||||
* @param res web script response
|
|
||||||
* @param customModel custom model entries
|
* @param customModel custom model entries
|
||||||
*
|
*
|
||||||
* @return script model
|
* @return script model
|
||||||
*/
|
*/
|
||||||
final protected Map<String, Object> createScriptModel(WebScriptRequest req, WebScriptResponse res, Map<String, Object> customModel)
|
final protected Map<String, Object> createScriptModel(WebScriptRequest req, Map<String, Object> customModel)
|
||||||
{
|
{
|
||||||
// create script model
|
// create script model
|
||||||
Map<String, Object> model = new HashMap<String, Object>(7, 1.0f);
|
Map<String, Object> model = new HashMap<String, Object>(7, 1.0f);
|
||||||
@@ -301,6 +320,188 @@ public abstract class AbstractWebScript implements WebScript
|
|||||||
{
|
{
|
||||||
getWebScriptRegistry().getTemplateProcessor().processString(template, model, writer);
|
getWebScriptRegistry().getTemplateProcessor().processString(template, model, writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render an explicit response status template
|
||||||
|
*
|
||||||
|
* @param req web script request
|
||||||
|
* @param res web script response
|
||||||
|
* @param status web script status
|
||||||
|
* @param format format
|
||||||
|
* @param model model
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
final protected void sendStatus(WebScriptRequest req, WebScriptResponse res, WebScriptStatus status, String format, Map<String, Object> model)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
// locate status template
|
||||||
|
// NOTE: search order...
|
||||||
|
// NOTE: package path is recursed to root package
|
||||||
|
// 1) script located <scriptid>.<format>.<status>.ftl
|
||||||
|
// 2) script located <scriptid>.<format>.status.ftl
|
||||||
|
// 3) package located <scriptpath>/<format>.<status>.ftl
|
||||||
|
// 4) package located <scriptpath>/<format>.status.ftl
|
||||||
|
// 5) default <status>.ftl
|
||||||
|
// 6) default status.ftl
|
||||||
|
|
||||||
|
int statusCode = status.getCode();
|
||||||
|
String statusFormat = (format == null) ? "" : format;
|
||||||
|
String scriptId = getDescription().getId();
|
||||||
|
StatusTemplate template = getStatusTemplate(scriptId, statusCode, statusFormat);
|
||||||
|
|
||||||
|
// render output
|
||||||
|
String mimetype = getWebScriptRegistry().getFormatRegistry().getMimeType(req.getAgent(), template.format);
|
||||||
|
if (mimetype == null)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Web Script format '" + template.format + "' is not registered");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Sending status " + statusCode + " (Template: " + template.path + ")");
|
||||||
|
logger.debug("Rendering response: content type=" + mimetype);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.reset();
|
||||||
|
res.setStatus(statusCode);
|
||||||
|
res.setContentType(mimetype + ";charset=UTF-8");
|
||||||
|
renderTemplate(template.path, model, res.getWriter());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find status template
|
||||||
|
*
|
||||||
|
* Note: This method caches template search results
|
||||||
|
*
|
||||||
|
* @param scriptId
|
||||||
|
* @param statusCode
|
||||||
|
* @param format
|
||||||
|
* @return status template (or null if not found)
|
||||||
|
*/
|
||||||
|
private StatusTemplate getStatusTemplate(String scriptId, int statusCode, String format)
|
||||||
|
{
|
||||||
|
StatusTemplate statusTemplate = null;
|
||||||
|
statusTemplateLock.readLock().lock();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String key = statusCode + "." + format;
|
||||||
|
statusTemplate = statusTemplates.get(key);
|
||||||
|
if (statusTemplate == null)
|
||||||
|
{
|
||||||
|
// Upgrade read lock to write lock
|
||||||
|
statusTemplateLock.readLock().unlock();
|
||||||
|
statusTemplateLock.writeLock().lock();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Check again
|
||||||
|
statusTemplate = statusTemplates.get(key);
|
||||||
|
if (statusTemplate == null)
|
||||||
|
{
|
||||||
|
// Locate template in web script store
|
||||||
|
statusTemplate = getScriptStatusTemplate(scriptId, statusCode, format);
|
||||||
|
if (statusTemplate == null)
|
||||||
|
{
|
||||||
|
WebScriptPath path = getWebScriptRegistry().getPackage(Path.concatPath("/", getDescription().getScriptPath()));
|
||||||
|
statusTemplate = getPackageStatusTemplate(path, statusCode, format);
|
||||||
|
if (statusTemplate == null)
|
||||||
|
{
|
||||||
|
statusTemplate = getDefaultStatusTemplate(statusCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Caching template " + statusTemplate.path + " for web script " + scriptId + " and status " + statusCode + " (format: " + format + ")");
|
||||||
|
|
||||||
|
statusTemplates.put(key, statusTemplate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Downgrade lock to read
|
||||||
|
statusTemplateLock.readLock().lock();
|
||||||
|
statusTemplateLock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return statusTemplate;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
statusTemplateLock.readLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a script specific status template
|
||||||
|
*
|
||||||
|
* @param scriptId
|
||||||
|
* @param statusCode
|
||||||
|
* @param format
|
||||||
|
* @return status template (or null, if not found)
|
||||||
|
*/
|
||||||
|
private StatusTemplate getScriptStatusTemplate(String scriptId, int statusCode, String format)
|
||||||
|
{
|
||||||
|
String path = scriptId + "." + format + "." + statusCode + ".ftl";
|
||||||
|
if (getWebScriptRegistry().getTemplateProcessor().hasTemplate(path))
|
||||||
|
{
|
||||||
|
return new StatusTemplate(path, format);
|
||||||
|
}
|
||||||
|
path = scriptId + "." + format + ".status.ftl";
|
||||||
|
if (getWebScriptRegistry().getTemplateProcessor().hasTemplate(path))
|
||||||
|
{
|
||||||
|
return new StatusTemplate(path, format);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a package specific status template
|
||||||
|
*
|
||||||
|
* @param scriptPath
|
||||||
|
* @param statusCode
|
||||||
|
* @param format
|
||||||
|
* @return status template (or null, if not found)
|
||||||
|
*/
|
||||||
|
private StatusTemplate getPackageStatusTemplate(WebScriptPath scriptPath, int statusCode, String format)
|
||||||
|
{
|
||||||
|
while(scriptPath != null)
|
||||||
|
{
|
||||||
|
String path = Path.concatPath(scriptPath.getPath(), format + "." + statusCode + ".ftl");
|
||||||
|
if (getWebScriptRegistry().getTemplateProcessor().hasTemplate(path))
|
||||||
|
{
|
||||||
|
return new StatusTemplate(path, format);
|
||||||
|
}
|
||||||
|
path = Path.concatPath(scriptPath.getPath(), format + ".status.ftl");
|
||||||
|
if (getWebScriptRegistry().getTemplateProcessor().hasTemplate(path))
|
||||||
|
{
|
||||||
|
return new StatusTemplate(path, format);
|
||||||
|
}
|
||||||
|
scriptPath = scriptPath.getParent();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find default status template
|
||||||
|
*
|
||||||
|
* @param statusCode
|
||||||
|
* @return status template
|
||||||
|
*/
|
||||||
|
private StatusTemplate getDefaultStatusTemplate(int statusCode)
|
||||||
|
{
|
||||||
|
String path = statusCode + ".ftl";
|
||||||
|
if (getWebScriptRegistry().getTemplateProcessor().hasTemplate(path))
|
||||||
|
{
|
||||||
|
return new StatusTemplate(path, WebScriptResponse.HTML_FORMAT);
|
||||||
|
}
|
||||||
|
path = "status.ftl";
|
||||||
|
if (getWebScriptRegistry().getTemplateProcessor().hasTemplate(path))
|
||||||
|
{
|
||||||
|
return new StatusTemplate(path, WebScriptResponse.HTML_FORMAT);
|
||||||
|
}
|
||||||
|
throw new WebScriptException("Default status template /status.ftl could not be found");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a script
|
* Execute a script
|
||||||
@@ -312,4 +513,26 @@ public abstract class AbstractWebScript implements WebScript
|
|||||||
{
|
{
|
||||||
getWebScriptRegistry().getScriptProcessor().executeScript(location, model);
|
getWebScriptRegistry().getScriptProcessor().executeScript(location, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Status Template
|
||||||
|
*/
|
||||||
|
private class StatusTemplate
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Construct
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* @param format
|
||||||
|
*/
|
||||||
|
private StatusTemplate(String path, String format)
|
||||||
|
{
|
||||||
|
this.path = path;
|
||||||
|
this.format = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String path;
|
||||||
|
private String format;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -31,11 +31,12 @@ import java.util.Collection;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.alfresco.repo.jscript.Node;
|
import org.alfresco.repo.jscript.Node;
|
||||||
import org.alfresco.repo.jscript.ScriptableHashMap;
|
import org.alfresco.repo.jscript.ScriptableHashMap;
|
||||||
import org.alfresco.repo.template.TemplateNode;
|
import org.alfresco.repo.template.TemplateNode;
|
||||||
import org.alfresco.service.cmr.repository.ScriptLocation;
|
import org.alfresco.service.cmr.repository.ScriptLocation;
|
||||||
import org.alfresco.service.cmr.repository.TemplateException;
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.mozilla.javascript.Context;
|
import org.mozilla.javascript.Context;
|
||||||
@@ -76,57 +77,90 @@ public class DeclarativeWebScript extends AbstractWebScript
|
|||||||
*/
|
*/
|
||||||
final public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
|
final public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
|
||||||
{
|
{
|
||||||
// construct data model for template
|
// retrieve requested format
|
||||||
Map<String, Object> model = executeImpl(req, res);
|
|
||||||
if (model == null)
|
|
||||||
{
|
|
||||||
model = new HashMap<String, Object>(7, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// execute script if it exists
|
|
||||||
if (executeScript != null)
|
|
||||||
{
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
logger.debug("Executing script " + executeScript);
|
|
||||||
|
|
||||||
Map<String, Object> scriptModel = createScriptModel(req, res, model);
|
|
||||||
// add return model allowing script to add items to template model
|
|
||||||
Map<String, Object> returnModel = new ScriptableHashMap<String, Object>();
|
|
||||||
scriptModel.put("model", returnModel);
|
|
||||||
executeScript(executeScript, scriptModel);
|
|
||||||
mergeScriptModelIntoTemplateModel(returnModel, model);
|
|
||||||
}
|
|
||||||
|
|
||||||
// process requested format
|
|
||||||
String format = req.getFormat();
|
String format = req.getFormat();
|
||||||
if (format == null || format.length() == 0)
|
if (format == null || format.length() == 0)
|
||||||
{
|
{
|
||||||
format = getDescription().getDefaultFormat();
|
format = getDescription().getDefaultFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
String mimetype = getWebScriptRegistry().getFormatRegistry().getMimeType(req.getAgent(), format);
|
|
||||||
if (mimetype == null)
|
|
||||||
{
|
|
||||||
throw new WebScriptException("Web Script format '" + format + "' is not registered");
|
|
||||||
}
|
|
||||||
|
|
||||||
// render output
|
|
||||||
res.setContentType(mimetype + ";charset=UTF-8");
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
logger.debug("Response content type: " + mimetype);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// establish mimetype from format
|
||||||
|
String mimetype = getWebScriptRegistry().getFormatRegistry().getMimeType(req.getAgent(), format);
|
||||||
|
if (mimetype == null)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Web Script format '" + format + "' is not registered");
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct data model for template
|
||||||
|
WebScriptStatus status = new WebScriptStatus();
|
||||||
|
Map<String, Object> model = executeImpl(req, status);
|
||||||
|
if (model == null)
|
||||||
|
{
|
||||||
|
model = new HashMap<String, Object>(7, 1.0f);
|
||||||
|
}
|
||||||
|
model.put("status", status);
|
||||||
|
|
||||||
|
// execute script if it exists
|
||||||
|
if (executeScript != null)
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Executing script " + executeScript);
|
||||||
|
|
||||||
|
Map<String, Object> scriptModel = createScriptModel(req, model);
|
||||||
|
// add return model allowing script to add items to template model
|
||||||
|
Map<String, Object> returnModel = new ScriptableHashMap<String, Object>();
|
||||||
|
scriptModel.put("model", returnModel);
|
||||||
|
executeScript(executeScript, scriptModel);
|
||||||
|
mergeScriptModelIntoTemplateModel(returnModel, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create model for template rendering
|
||||||
Map<String, Object> templateModel = createTemplateModel(req, res, model);
|
Map<String, Object> templateModel = createTemplateModel(req, res, model);
|
||||||
renderFormatTemplate(format, templateModel, res.getWriter());
|
|
||||||
|
// is a redirect to a status specific template required?
|
||||||
|
if (status.getRedirect())
|
||||||
|
{
|
||||||
|
sendStatus(req, res, status, format, templateModel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// render output
|
||||||
|
int statusCode = status.getCode();
|
||||||
|
if (statusCode != HttpServletResponse.SC_OK)
|
||||||
|
{
|
||||||
|
res.setStatus(statusCode);
|
||||||
|
}
|
||||||
|
res.setContentType(mimetype + ";charset=UTF-8");
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Rendering response: content type=" + mimetype + ", status=" + statusCode);
|
||||||
|
|
||||||
|
renderFormatTemplate(format, templateModel, res.getWriter());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(TemplateException e)
|
catch(Throwable e)
|
||||||
{
|
{
|
||||||
throw new WebScriptException("Failed to process format '" + format + "'", e);
|
// extract status code, if specified
|
||||||
|
int statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
|
||||||
|
if (e instanceof WebScriptException)
|
||||||
|
{
|
||||||
|
statusCode = ((WebScriptException)e).getStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
// send status
|
||||||
|
WebScriptStatus status = new WebScriptStatus();
|
||||||
|
status.setCode(statusCode);
|
||||||
|
status.setMessage(e.getMessage());
|
||||||
|
status.setException(e);
|
||||||
|
Map<String, Object> customModel = new HashMap<String, Object>();
|
||||||
|
customModel.put("status", status);
|
||||||
|
Map<String, Object> templateModel = createTemplateModel(req, res, customModel);
|
||||||
|
sendStatus(req, res, status, format, templateModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge script generated model into template-ready model
|
* Merge script generated model into template-ready model
|
||||||
*
|
*
|
||||||
@@ -192,10 +226,9 @@ public class DeclarativeWebScript extends AbstractWebScript
|
|||||||
* Execute custom Java logic
|
* Execute custom Java logic
|
||||||
*
|
*
|
||||||
* @param req Web Script request
|
* @param req Web Script request
|
||||||
* @param res Web Script response
|
|
||||||
* @return custom service model
|
* @return custom service model
|
||||||
*/
|
*/
|
||||||
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptResponse res)
|
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@@ -81,7 +81,7 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
|||||||
|
|
||||||
// map of web scripts by url
|
// map of web scripts by url
|
||||||
// NOTE: The map is sorted by url (descending order)
|
// NOTE: The map is sorted by url (descending order)
|
||||||
private Map<String, WebScript> webscriptsByURL = new TreeMap<String, WebScript>(Collections.reverseOrder());
|
private Map<String, URLIndex> webscriptsByURL = new TreeMap<String, URLIndex>(Collections.reverseOrder());
|
||||||
|
|
||||||
// map of web script packages by path
|
// map of web script packages by path
|
||||||
private Map<String, Path> packageByPath = new TreeMap<String, Path>();
|
private Map<String, Path> packageByPath = new TreeMap<String, Path>();
|
||||||
@@ -258,6 +258,7 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
|||||||
for (URI uri : serviceDesc.getURIs())
|
for (URI uri : serviceDesc.getURIs())
|
||||||
{
|
{
|
||||||
// establish static part of url template
|
// establish static part of url template
|
||||||
|
boolean wildcard = false;
|
||||||
String uriTemplate = uri.getURI();
|
String uriTemplate = uri.getURI();
|
||||||
int queryArgIdx = uriTemplate.indexOf('?');
|
int queryArgIdx = uriTemplate.indexOf('?');
|
||||||
if (queryArgIdx != -1)
|
if (queryArgIdx != -1)
|
||||||
@@ -268,6 +269,7 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
|||||||
if (tokenIdx != -1)
|
if (tokenIdx != -1)
|
||||||
{
|
{
|
||||||
uriTemplate = uriTemplate.substring(0, tokenIdx);
|
uriTemplate = uriTemplate.substring(0, tokenIdx);
|
||||||
|
wildcard = true;
|
||||||
}
|
}
|
||||||
if (serviceDesc.getFormatStyle() != WebScriptDescription.FormatStyle.argument)
|
if (serviceDesc.getFormatStyle() != WebScriptDescription.FormatStyle.argument)
|
||||||
{
|
{
|
||||||
@@ -282,7 +284,8 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
|||||||
String uriIdx = serviceDesc.getMethod().toString() + ":" + uriTemplate;
|
String uriIdx = serviceDesc.getMethod().toString() + ":" + uriTemplate;
|
||||||
if (webscriptsByURL.containsKey(uriIdx))
|
if (webscriptsByURL.containsKey(uriIdx))
|
||||||
{
|
{
|
||||||
WebScript existingService = webscriptsByURL.get(uriIdx);
|
URLIndex urlIndex = webscriptsByURL.get(uriIdx);
|
||||||
|
WebScript existingService = urlIndex.script;
|
||||||
if (!existingService.getDescription().getId().equals(serviceDesc.getId()))
|
if (!existingService.getDescription().getId().equals(serviceDesc.getId()))
|
||||||
{
|
{
|
||||||
String msg = "Web Script document " + serviceDesc.getDescPath() + " is attempting to define the url '" + uriIdx + "' already defined by " + existingService.getDescription().getDescPath();
|
String msg = "Web Script document " + serviceDesc.getDescPath() + " is attempting to define the url '" + uriIdx + "' already defined by " + existingService.getDescription().getDescPath();
|
||||||
@@ -291,7 +294,8 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
webscriptsByURL.put(uriIdx, serviceImpl);
|
URLIndex urlIndex = new URLIndex(uriTemplate, wildcard, serviceImpl);
|
||||||
|
webscriptsByURL.put(uriIdx, urlIndex);
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Registered Web Script URL '" + uriIdx + "'");
|
logger.debug("Registered Web Script URL '" + uriIdx + "'");
|
||||||
@@ -357,7 +361,7 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
|||||||
subpath = path.createChildPath(part);
|
subpath = path.createChildPath(part);
|
||||||
uriByPath.put(subpath.getPath(), subpath);
|
uriByPath.put(subpath.getPath(), subpath);
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Registered Web Script URI " + subpath.getPath());
|
logger.debug("Registered Web Script URI Path " + subpath.getPath());
|
||||||
}
|
}
|
||||||
path = subpath;
|
path = subpath;
|
||||||
}
|
}
|
||||||
@@ -387,7 +391,8 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
// retrieve script path
|
// retrieve script path
|
||||||
String scriptPath = serviceDescPath.substring(0, serviceDescPath.lastIndexOf('/'));
|
int iPathIdx = serviceDescPath.lastIndexOf('/');
|
||||||
|
String scriptPath = serviceDescPath.substring(0, iPathIdx == -1 ? 0 : iPathIdx);
|
||||||
|
|
||||||
// retrieve script id
|
// retrieve script id
|
||||||
String id = serviceDescPath.substring(0, serviceDescPath.lastIndexOf(".desc.xml"));
|
String id = serviceDescPath.substring(0, serviceDescPath.lastIndexOf(".desc.xml"));
|
||||||
@@ -569,19 +574,38 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
|||||||
*/
|
*/
|
||||||
public WebScriptMatch findWebScript(String method, String uri)
|
public WebScriptMatch findWebScript(String method, String uri)
|
||||||
{
|
{
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
// TODO: Replace with more efficient approach
|
// TODO: Replace with more efficient approach
|
||||||
|
String matchedPath = null;
|
||||||
DeclarativeWebScriptMatch apiServiceMatch = null;
|
DeclarativeWebScriptMatch apiServiceMatch = null;
|
||||||
String match = method.toString().toUpperCase() + ":" + uri;
|
String match = method.toString().toUpperCase() + ":" + uri;
|
||||||
for (Map.Entry<String, WebScript> service : webscriptsByURL.entrySet())
|
|
||||||
|
// locate full match - on URI and METHOD
|
||||||
|
for (Map.Entry<String, URLIndex> entry : webscriptsByURL.entrySet())
|
||||||
{
|
{
|
||||||
String indexedPath = service.getKey();
|
URLIndex urlIndex = entry.getValue();
|
||||||
if (match.startsWith(indexedPath))
|
String index = entry.getKey();
|
||||||
|
if ((urlIndex.wildcardPath && match.startsWith(index)) || (!urlIndex.wildcardPath && match.equals(index)))
|
||||||
{
|
{
|
||||||
String matchPath = indexedPath.substring(indexedPath.indexOf(':') +1);
|
apiServiceMatch = new DeclarativeWebScriptMatch(urlIndex.path, urlIndex.script);
|
||||||
apiServiceMatch = new DeclarativeWebScriptMatch(matchPath, service.getValue());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if ((urlIndex.wildcardPath && uri.startsWith(urlIndex.path)) || (!urlIndex.wildcardPath && uri.equals(urlIndex.path)))
|
||||||
|
{
|
||||||
|
matchedPath = urlIndex.path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// locate URI match
|
||||||
|
if (apiServiceMatch == null && matchedPath != null)
|
||||||
|
{
|
||||||
|
apiServiceMatch = new DeclarativeWebScriptMatch(matchedPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Web Script index lookup for uri " + uri + " took " + (System.currentTimeMillis() - startTime) + "ms");
|
||||||
|
|
||||||
return apiServiceMatch;
|
return apiServiceMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -634,6 +658,7 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
|||||||
{
|
{
|
||||||
private String path;
|
private String path;
|
||||||
private WebScript service;
|
private WebScript service;
|
||||||
|
private Kind kind;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct
|
* Construct
|
||||||
@@ -643,9 +668,30 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
|||||||
*/
|
*/
|
||||||
public DeclarativeWebScriptMatch(String path, WebScript service)
|
public DeclarativeWebScriptMatch(String path, WebScript service)
|
||||||
{
|
{
|
||||||
|
this.kind = Kind.FULL;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.service = service;
|
this.service = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* @param service
|
||||||
|
*/
|
||||||
|
public DeclarativeWebScriptMatch(String path)
|
||||||
|
{
|
||||||
|
this.kind = Kind.URI;
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.web.scripts.WebScriptMatch#getKind()
|
||||||
|
*/
|
||||||
|
public Kind getKind()
|
||||||
|
{
|
||||||
|
return this.kind;
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.alfresco.web.scripts.WebScriptMatch#getPath()
|
* @see org.alfresco.web.scripts.WebScriptMatch#getPath()
|
||||||
@@ -664,4 +710,21 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web Script URL Index Entry
|
||||||
|
*/
|
||||||
|
private static class URLIndex
|
||||||
|
{
|
||||||
|
private URLIndex(String path, boolean wildcardPath, WebScript script)
|
||||||
|
{
|
||||||
|
this.path = path;
|
||||||
|
this.wildcardPath = wildcardPath;
|
||||||
|
this.script = script;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String path;
|
||||||
|
private boolean wildcardPath;
|
||||||
|
private WebScript script;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.web.scripts;
|
package org.alfresco.web.scripts;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.alfresco.repo.template.FreeMarkerProcessor;
|
import org.alfresco.repo.template.FreeMarkerProcessor;
|
||||||
import org.alfresco.repo.template.QNameAwareObjectWrapper;
|
import org.alfresco.repo.template.QNameAwareObjectWrapper;
|
||||||
import org.alfresco.service.cmr.repository.ProcessorExtension;
|
import org.alfresco.service.cmr.repository.ProcessorExtension;
|
||||||
@@ -37,6 +39,7 @@ import org.springframework.context.ApplicationListener;
|
|||||||
import freemarker.cache.MruCacheStorage;
|
import freemarker.cache.MruCacheStorage;
|
||||||
import freemarker.cache.TemplateLoader;
|
import freemarker.cache.TemplateLoader;
|
||||||
import freemarker.template.Configuration;
|
import freemarker.template.Configuration;
|
||||||
|
import freemarker.template.Template;
|
||||||
import freemarker.template.TemplateExceptionHandler;
|
import freemarker.template.TemplateExceptionHandler;
|
||||||
|
|
||||||
|
|
||||||
@@ -106,6 +109,26 @@ public class TemplateProcessor extends FreeMarkerProcessor implements Applicatio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a template exists
|
||||||
|
*
|
||||||
|
* @param template
|
||||||
|
* @return true => exists
|
||||||
|
*/
|
||||||
|
public boolean hasTemplate(String templatePath)
|
||||||
|
{
|
||||||
|
boolean hasTemplate = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Template template = templateConfig.getTemplate(templatePath);
|
||||||
|
hasTemplate = (template != null);
|
||||||
|
}
|
||||||
|
catch(IOException e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return hasTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise FreeMarker Configuration
|
* Initialise FreeMarker Configuration
|
||||||
*/
|
*/
|
||||||
|
@@ -353,12 +353,7 @@ public class TestWebScriptServer
|
|||||||
command[0].equals("post") ||
|
command[0].equals("post") ||
|
||||||
command[0].equals("delete"))
|
command[0].equals("delete"))
|
||||||
{
|
{
|
||||||
if (command.length < 2)
|
String uri = (command.length > 1) ? command[1] : null;
|
||||||
{
|
|
||||||
return "Syntax Error.\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
String uri = command[1];
|
|
||||||
MockHttpServletResponse res = submitRequest(command[0], uri);
|
MockHttpServletResponse res = submitRequest(command[0], uri);
|
||||||
bout.write(res.getContentAsByteArray());
|
bout.write(res.getContentAsByteArray());
|
||||||
out.println();
|
out.println();
|
||||||
@@ -392,23 +387,24 @@ public class TestWebScriptServer
|
|||||||
{
|
{
|
||||||
MockHttpServletRequest req = new MockHttpServletRequest(method, uri);
|
MockHttpServletRequest req = new MockHttpServletRequest(method, uri);
|
||||||
|
|
||||||
// set parameters
|
|
||||||
int iArgIndex = uri.indexOf('?');
|
|
||||||
if (iArgIndex != -1 && iArgIndex != uri.length() -1)
|
|
||||||
{
|
|
||||||
String uriArgs = uri.substring(iArgIndex +1);
|
|
||||||
String[] args = uriArgs.split("&");
|
|
||||||
for (String arg : args)
|
|
||||||
{
|
|
||||||
String[] parts = arg.split("=");
|
|
||||||
req.addParameter(parts[0], (parts.length == 2) ? parts[1] : null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set paths
|
|
||||||
req.setContextPath("/alfresco");
|
req.setContextPath("/alfresco");
|
||||||
req.setServletPath("/service");
|
req.setServletPath("/service");
|
||||||
req.setPathInfo(iArgIndex == -1 ? uri : uri.substring(0, iArgIndex));
|
|
||||||
|
if (uri != null)
|
||||||
|
{
|
||||||
|
int iArgIndex = uri.indexOf('?');
|
||||||
|
if (iArgIndex != -1 && iArgIndex != uri.length() -1)
|
||||||
|
{
|
||||||
|
String uriArgs = uri.substring(iArgIndex +1);
|
||||||
|
String[] args = uriArgs.split("&");
|
||||||
|
for (String arg : args)
|
||||||
|
{
|
||||||
|
String[] parts = arg.split("=");
|
||||||
|
req.addParameter(parts[0], (parts.length == 2) ? parts[1] : null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req.setPathInfo(iArgIndex == -1 ? uri : uri.substring(0, iArgIndex));
|
||||||
|
}
|
||||||
|
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.web.scripts;
|
package org.alfresco.web.scripts;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,6 +37,15 @@ public class WebScriptException extends AlfrescoRuntimeException
|
|||||||
{
|
{
|
||||||
private static final long serialVersionUID = -7338963365877285084L;
|
private static final long serialVersionUID = -7338963365877285084L;
|
||||||
|
|
||||||
|
private int status = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
|
||||||
|
|
||||||
|
|
||||||
|
public WebScriptException(int status, String msgId)
|
||||||
|
{
|
||||||
|
this(msgId);
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
public WebScriptException(String msgId)
|
public WebScriptException(String msgId)
|
||||||
{
|
{
|
||||||
super(msgId);
|
super(msgId);
|
||||||
@@ -54,4 +65,10 @@ public class WebScriptException extends AlfrescoRuntimeException
|
|||||||
{
|
{
|
||||||
super(msgId, args, cause);
|
super(msgId, args, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getStatus()
|
||||||
|
{
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -26,13 +26,25 @@ package org.alfresco.web.scripts;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a URL to Web Script match
|
* Represents a URL request to Web Script match
|
||||||
*
|
*
|
||||||
* @author davidc
|
* @author davidc
|
||||||
*/
|
*/
|
||||||
public interface WebScriptMatch
|
public interface WebScriptMatch
|
||||||
{
|
{
|
||||||
|
public enum Kind
|
||||||
|
{
|
||||||
|
/** URL request matches on URI only */
|
||||||
|
URI,
|
||||||
|
/** URL request matches on URI and Method */
|
||||||
|
FULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the kind of Match
|
||||||
|
*/
|
||||||
|
public Kind getKind();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the part of the request URL that matched the Web Script URL Template
|
* Gets the part of the request URL that matched the Web Script URL Template
|
||||||
*
|
*
|
||||||
@@ -43,7 +55,7 @@ public interface WebScriptMatch
|
|||||||
/**
|
/**
|
||||||
* Gets the matching web script
|
* Gets the matching web script
|
||||||
*
|
*
|
||||||
* @return service
|
* @return service (or null, if match kind is URI)
|
||||||
*/
|
*/
|
||||||
public WebScript getWebScript();
|
public WebScript getWebScript();
|
||||||
|
|
||||||
|
@@ -40,13 +40,21 @@ public abstract class WebScriptRequestImpl implements WebScriptRequest
|
|||||||
*/
|
*/
|
||||||
public String getExtensionPath()
|
public String getExtensionPath()
|
||||||
{
|
{
|
||||||
String servicePath = getServiceMatch().getPath();
|
String extensionPath = "";
|
||||||
String extensionPath = getPathInfo();
|
WebScriptMatch match = getServiceMatch();
|
||||||
int extIdx = extensionPath.indexOf(servicePath);
|
if (match != null)
|
||||||
if (extIdx != -1)
|
|
||||||
{
|
{
|
||||||
int extLength = (servicePath.endsWith("/") ? servicePath.length() : servicePath.length() + 1);
|
String servicePath = getServiceMatch().getPath();
|
||||||
extensionPath = extensionPath.substring(extIdx + extLength);
|
extensionPath = getPathInfo();
|
||||||
|
if (extensionPath != null)
|
||||||
|
{
|
||||||
|
int extIdx = extensionPath.indexOf(servicePath);
|
||||||
|
if (extIdx != -1)
|
||||||
|
{
|
||||||
|
int extLength = (servicePath.endsWith("/") ? servicePath.length() : servicePath.length() + 1);
|
||||||
|
extensionPath = extensionPath.substring(extIdx + extLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return extensionPath;
|
return extensionPath;
|
||||||
}
|
}
|
||||||
@@ -65,30 +73,37 @@ public abstract class WebScriptRequestImpl implements WebScriptRequest
|
|||||||
public String getFormat()
|
public String getFormat()
|
||||||
{
|
{
|
||||||
String format = null;
|
String format = null;
|
||||||
FormatStyle style = getServiceMatch().getWebScript().getDescription().getFormatStyle();
|
WebScriptMatch match = getServiceMatch();
|
||||||
|
if (match != null)
|
||||||
// extract format from extension
|
|
||||||
if (style == FormatStyle.extension || style == FormatStyle.any)
|
|
||||||
{
|
{
|
||||||
String pathInfo = getPathInfo();
|
FormatStyle style = getServiceMatch().getWebScript().getDescription().getFormatStyle();
|
||||||
int extIdx = pathInfo.lastIndexOf('.');
|
|
||||||
if (extIdx != -1)
|
// extract format from extension
|
||||||
|
if (style == FormatStyle.extension || style == FormatStyle.any)
|
||||||
{
|
{
|
||||||
format = pathInfo.substring(extIdx +1);
|
String pathInfo = getPathInfo();
|
||||||
}
|
if (pathInfo != null)
|
||||||
}
|
|
||||||
|
|
||||||
// extract format from argument
|
|
||||||
if (style == FormatStyle.argument || style == FormatStyle.any)
|
|
||||||
{
|
|
||||||
String argFormat = getParameter("format");
|
|
||||||
if (argFormat != null)
|
|
||||||
{
|
|
||||||
if (format != null && format.length() > 0)
|
|
||||||
{
|
{
|
||||||
throw new WebScriptException("Format specified both in extension and format argument");
|
int extIdx = pathInfo.lastIndexOf('.');
|
||||||
|
if (extIdx != -1)
|
||||||
|
{
|
||||||
|
format = pathInfo.substring(extIdx +1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract format from argument
|
||||||
|
if (style == FormatStyle.argument || style == FormatStyle.any)
|
||||||
|
{
|
||||||
|
String argFormat = getParameter("format");
|
||||||
|
if (argFormat != null)
|
||||||
|
{
|
||||||
|
if (format != null && format.length() > 0)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Format specified both in extension and format argument");
|
||||||
|
}
|
||||||
|
format = argFormat;
|
||||||
}
|
}
|
||||||
format = argFormat;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +115,12 @@ public abstract class WebScriptRequestImpl implements WebScriptRequest
|
|||||||
*/
|
*/
|
||||||
public FormatStyle getFormatStyle()
|
public FormatStyle getFormatStyle()
|
||||||
{
|
{
|
||||||
FormatStyle style = getServiceMatch().getWebScript().getDescription().getFormatStyle();
|
WebScriptMatch match = getServiceMatch();
|
||||||
|
if (match == null)
|
||||||
|
{
|
||||||
|
return FormatStyle.any;
|
||||||
|
}
|
||||||
|
FormatStyle style = match.getWebScript().getDescription().getFormatStyle();
|
||||||
if (style != FormatStyle.any)
|
if (style != FormatStyle.any)
|
||||||
{
|
{
|
||||||
return style;
|
return style;
|
||||||
|
@@ -44,6 +44,12 @@ public interface WebScriptResponse
|
|||||||
public static final String JSON_FORMAT = "json";
|
public static final String JSON_FORMAT = "json";
|
||||||
public static final String OPENSEARCH_DESCRIPTION_FORMAT = "opensearchdescription";
|
public static final String OPENSEARCH_DESCRIPTION_FORMAT = "opensearchdescription";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Response Status
|
||||||
|
*
|
||||||
|
* @param status
|
||||||
|
*/
|
||||||
|
public void setStatus(int status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the Content Type
|
* Sets the Content Type
|
||||||
@@ -68,6 +74,11 @@ public interface WebScriptResponse
|
|||||||
*/
|
*/
|
||||||
public OutputStream getOutputStream() throws IOException;
|
public OutputStream getOutputStream() throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears response buffer
|
||||||
|
*/
|
||||||
|
public void reset();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode a script URL
|
* Encode a script URL
|
||||||
*
|
*
|
||||||
|
@@ -25,8 +25,14 @@
|
|||||||
package org.alfresco.web.scripts;
|
package org.alfresco.web.scripts;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.alfresco.i18n.I18NUtil;
|
import org.alfresco.i18n.I18NUtil;
|
||||||
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.transaction.TransactionUtil;
|
import org.alfresco.repo.transaction.TransactionUtil;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
@@ -77,94 +83,159 @@ public abstract class WebScriptRuntime
|
|||||||
long startRuntime = System.currentTimeMillis();
|
long startRuntime = System.currentTimeMillis();
|
||||||
|
|
||||||
String method = getScriptMethod();
|
String method = getScriptMethod();
|
||||||
String scriptUrl = getScriptUrl();
|
String scriptUrl = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// extract script url
|
||||||
|
scriptUrl = getScriptUrl();
|
||||||
|
if (scriptUrl == null || scriptUrl.length() == 0)
|
||||||
|
{
|
||||||
|
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Script URL not specified");
|
||||||
|
}
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Processing script url (" + method + ") " + scriptUrl);
|
logger.debug("Processing script url (" + method + ") " + scriptUrl);
|
||||||
|
|
||||||
WebScriptMatch match = registry.findWebScript(method, scriptUrl);
|
WebScriptMatch match = registry.findWebScript(method, scriptUrl);
|
||||||
if (match != null)
|
if (match == null || match.getKind() == WebScriptMatch.Kind.URI)
|
||||||
{
|
{
|
||||||
// setup web script context
|
if (match == null)
|
||||||
final WebScriptRequest scriptReq = createRequest(match);
|
|
||||||
final WebScriptResponse scriptRes = createResponse();
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
logger.debug("Agent: " + scriptReq.getAgent());
|
|
||||||
|
|
||||||
long startScript = System.currentTimeMillis();
|
|
||||||
final WebScript script = match.getWebScript();
|
|
||||||
final WebScriptDescription description = script.getDescription();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
|
String msg = "Script url " + scriptUrl + " does not map to a Web Script.";
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug(msg);
|
||||||
|
throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, msg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String msg = "Script url " + scriptUrl + " does not support the method " + method;
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug(msg);
|
||||||
|
throw new WebScriptException(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create web script request & response
|
||||||
|
final WebScriptRequest scriptReq = createRequest(match);
|
||||||
|
final WebScriptResponse scriptRes = createResponse();
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Agent: " + scriptReq.getAgent());
|
||||||
|
|
||||||
|
long startScript = System.currentTimeMillis();
|
||||||
|
final WebScript script = match.getWebScript();
|
||||||
|
final WebScriptDescription description = script.getDescription();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
String user = AuthenticationUtil.getCurrentUserName();
|
||||||
|
String locale = I18NUtil.getLocale().toString();
|
||||||
|
String reqFormat = scriptReq.getFormat();
|
||||||
|
String format = (reqFormat == null || reqFormat.length() == 0) ? "default" : scriptReq.getFormat();
|
||||||
|
WebScriptDescription desc = scriptReq.getServiceMatch().getWebScript().getDescription();
|
||||||
|
logger.debug("Format style: " + desc.getFormatStyle());
|
||||||
|
logger.debug("Default format: " + desc.getDefaultFormat());
|
||||||
|
logger.debug("Invoking Web Script " + description.getId() + (user == null ? " (unauthenticated)" : " (authenticated as " + user + ") (format " + format + ") (" + locale + ")"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (description.getRequiredTransaction() == RequiredTransaction.none)
|
||||||
|
{
|
||||||
|
authenticatedExecute(scriptReq, scriptRes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// encapsulate script within transaction
|
||||||
|
TransactionUtil.TransactionWork<Object> work = new TransactionUtil.TransactionWork<Object>()
|
||||||
{
|
{
|
||||||
String user = AuthenticationUtil.getCurrentUserName();
|
public Object doWork() throws Throwable
|
||||||
String locale = I18NUtil.getLocale().toString();
|
{
|
||||||
String reqFormat = scriptReq.getFormat();
|
if (logger.isDebugEnabled())
|
||||||
String format = (reqFormat == null || reqFormat.length() == 0) ? "default" : scriptReq.getFormat();
|
logger.debug("Begin transaction: " + description.getRequiredTransaction());
|
||||||
WebScriptDescription desc = scriptReq.getServiceMatch().getWebScript().getDescription();
|
|
||||||
logger.debug("Format style: " + desc.getFormatStyle());
|
authenticatedExecute(scriptReq, scriptRes);
|
||||||
logger.debug("Default format: " + desc.getDefaultFormat());
|
|
||||||
logger.debug("Invoking Web Script " + description.getId() + (user == null ? " (unauthenticated)" : " (authenticated as " + user + ") (format " + format + ") (" + locale + ")"));
|
if (logger.isDebugEnabled())
|
||||||
}
|
logger.debug("End transaction: " + description.getRequiredTransaction());
|
||||||
|
|
||||||
if (description.getRequiredTransaction() == RequiredTransaction.none)
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (description.getRequiredTransaction() == RequiredTransaction.required)
|
||||||
{
|
{
|
||||||
authenticatedExecute(scriptReq, scriptRes);
|
TransactionUtil.executeInUserTransaction(transactionService, work);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// encapsulate script within transaction
|
TransactionUtil.executeInNonPropagatingUserTransaction(transactionService, work);
|
||||||
TransactionUtil.TransactionWork<Object> work = new TransactionUtil.TransactionWork<Object>()
|
|
||||||
{
|
|
||||||
public Object doWork() throws Throwable
|
|
||||||
{
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
logger.debug("Begin transaction: " + description.getRequiredTransaction());
|
|
||||||
|
|
||||||
authenticatedExecute(scriptReq, scriptRes);
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
logger.debug("End transaction: " + description.getRequiredTransaction());
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (description.getRequiredTransaction() == RequiredTransaction.required)
|
|
||||||
{
|
|
||||||
TransactionUtil.executeInUserTransaction(transactionService, work);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TransactionUtil.executeInNonPropagatingUserTransaction(transactionService, work);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(IOException e)
|
|
||||||
{
|
|
||||||
throw new WebScriptException("Failed to execute script", e);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
{
|
|
||||||
long endScript = System.currentTimeMillis();
|
|
||||||
logger.debug("Web Script " + description.getId() + " executed in " + (endScript - startScript) + "ms");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
finally
|
||||||
{
|
{
|
||||||
String msg = "Script url (" + method + ") " + scriptUrl + " does not map to a Web Script.";
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug(msg);
|
{
|
||||||
|
long endScript = System.currentTimeMillis();
|
||||||
|
logger.debug("Web Script " + description.getId() + " executed in " + (endScript - startScript) + "ms");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Throwable e)
|
||||||
|
{
|
||||||
|
// extract status code, if specified
|
||||||
|
int statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
|
||||||
|
if (e instanceof WebScriptException)
|
||||||
|
{
|
||||||
|
statusCode = ((WebScriptException)e).getStatus();
|
||||||
|
}
|
||||||
|
|
||||||
throw new WebScriptException(msg);
|
// create web script status for status template rendering
|
||||||
|
WebScriptStatus status = new WebScriptStatus();
|
||||||
|
status.setCode(statusCode);
|
||||||
|
status.setMessage(e.getMessage());
|
||||||
|
status.setException(e);
|
||||||
|
|
||||||
|
// create basic model for status template rendering
|
||||||
|
WebScriptRequest req = createRequest(null);
|
||||||
|
WebScriptResponse res = createResponse();
|
||||||
|
Map<String, Object> model = new HashMap<String, Object>();
|
||||||
|
model.put("status", status);
|
||||||
|
model.put("url", new URLModel(req));
|
||||||
|
|
||||||
|
// locate status template
|
||||||
|
// NOTE: search order...
|
||||||
|
// 1) root located <status>.ftl
|
||||||
|
// 2) root located status.ftl
|
||||||
|
String templatePath = "/" + statusCode + ".ftl";
|
||||||
|
if (!registry.getTemplateProcessor().hasTemplate(templatePath))
|
||||||
|
{
|
||||||
|
templatePath = "/status.ftl";
|
||||||
|
if (!registry.getTemplateProcessor().hasTemplate(templatePath))
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Failed to find status template " + status + " (format: " + WebScriptResponse.HTML_FORMAT + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// render output
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Sending status " + statusCode + " (Template: " + templatePath + ")");
|
||||||
|
logger.debug("Rendering response: content type=" + MimetypeMap.MIMETYPE_HTML);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.reset();
|
||||||
|
res.setStatus(statusCode);
|
||||||
|
res.setContentType(MimetypeMap.MIMETYPE_HTML + ";charset=UTF-8");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
registry.getTemplateProcessor().process(templatePath, model, res.getWriter());
|
||||||
|
}
|
||||||
|
catch (IOException e1)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Internal error", e1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -196,7 +267,7 @@ public abstract class WebScriptRuntime
|
|||||||
}
|
}
|
||||||
else if (required == RequiredAuthentication.user && isGuest)
|
else if (required == RequiredAuthentication.user && isGuest)
|
||||||
{
|
{
|
||||||
throw new WebScriptException("Web Script " + desc.getId() + " requires user authentication; however, a guest has attempted access.");
|
throw new WebScriptException(HttpServletResponse.SC_UNAUTHORIZED, "Web Script " + desc.getId() + " requires user authentication; however, a guest has attempted access.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -220,7 +291,6 @@ public abstract class WebScriptRuntime
|
|||||||
//
|
//
|
||||||
if (authenticate(required, isGuest))
|
if (authenticate(required, isGuest))
|
||||||
{
|
{
|
||||||
//
|
|
||||||
// Execute Web Script
|
// Execute Web Script
|
||||||
wrappedExecute(scriptReq, scriptRes);
|
wrappedExecute(scriptReq, scriptRes);
|
||||||
}
|
}
|
||||||
|
@@ -120,7 +120,8 @@ public class WebScriptServletRequest extends WebScriptRequestImpl
|
|||||||
*/
|
*/
|
||||||
public String getServicePath()
|
public String getServicePath()
|
||||||
{
|
{
|
||||||
return getServiceContextPath() + req.getPathInfo();
|
String pathInfo = req.getPathInfo();
|
||||||
|
return getServiceContextPath() + ((pathInfo == null) ? "" : req.getPathInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@@ -28,7 +28,6 @@ import java.io.IOException;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,6 +59,14 @@ public class WebScriptServletResponse implements WebScriptResponse
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.web.scripts.WebScriptResponse#setStatus(int)
|
||||||
|
*/
|
||||||
|
public void setStatus(int status)
|
||||||
|
{
|
||||||
|
res.setStatus(status);
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.alfresco.web.scripts.WebScriptResponse#setContentType(java.lang.String)
|
* @see org.alfresco.web.scripts.WebScriptResponse#setContentType(java.lang.String)
|
||||||
*/
|
*/
|
||||||
@@ -68,6 +75,20 @@ public class WebScriptServletResponse implements WebScriptResponse
|
|||||||
res.setContentType(contentType);
|
res.setContentType(contentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.web.scripts.WebScriptResponse#reset()
|
||||||
|
*/
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
res.reset();
|
||||||
|
}
|
||||||
|
catch(IllegalStateException e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.alfresco.web.scripts.WebScriptResponse#getWriter()
|
* @see org.alfresco.web.scripts.WebScriptResponse#getWriter()
|
||||||
*/
|
*/
|
||||||
@@ -91,5 +112,5 @@ public class WebScriptServletResponse implements WebScriptResponse
|
|||||||
{
|
{
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
178
source/java/org/alfresco/web/scripts/WebScriptStatus.java
Normal file
178
source/java/org/alfresco/web/scripts/WebScriptStatus.java
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing"
|
||||||
|
*/
|
||||||
|
package org.alfresco.web.scripts;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.alfresco.i18n.I18NUtil;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web Script Status
|
||||||
|
*
|
||||||
|
* Records the outcome of a Web Script.
|
||||||
|
*
|
||||||
|
* @author davidc
|
||||||
|
*/
|
||||||
|
public class WebScriptStatus
|
||||||
|
{
|
||||||
|
private Throwable exception = null;
|
||||||
|
private int code = HttpServletResponse.SC_OK;
|
||||||
|
private String message = null;
|
||||||
|
private boolean redirect = false;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param exception
|
||||||
|
*/
|
||||||
|
public void setException(Throwable exception)
|
||||||
|
{
|
||||||
|
this.exception = exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return exception
|
||||||
|
*/
|
||||||
|
public Throwable getException()
|
||||||
|
{
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Throwable jsGet_exception()
|
||||||
|
{
|
||||||
|
return getException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
public void setMessage(String message)
|
||||||
|
{
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void jsSet_message(String message)
|
||||||
|
{
|
||||||
|
setMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return message
|
||||||
|
*/
|
||||||
|
public String getMessage()
|
||||||
|
{
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String jsGet_message()
|
||||||
|
{
|
||||||
|
return getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param redirect redirect to status code response
|
||||||
|
*/
|
||||||
|
public void setRedirect(boolean redirect)
|
||||||
|
{
|
||||||
|
this.redirect = redirect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void jsSet_redirect(boolean redirect)
|
||||||
|
{
|
||||||
|
setRedirect(redirect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return redirect to status code response
|
||||||
|
*/
|
||||||
|
public boolean getRedirect()
|
||||||
|
{
|
||||||
|
return redirect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean jsGet_redirect()
|
||||||
|
{
|
||||||
|
return getRedirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.servlet.http.HTTPServletResponse
|
||||||
|
*
|
||||||
|
* @param code status code
|
||||||
|
*/
|
||||||
|
public void setCode(int code)
|
||||||
|
{
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void jsSet_code(int code)
|
||||||
|
{
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return status code
|
||||||
|
*/
|
||||||
|
public int getCode()
|
||||||
|
{
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int jsGet_code()
|
||||||
|
{
|
||||||
|
return getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the short name of the status code
|
||||||
|
*
|
||||||
|
* @return status code name
|
||||||
|
*/
|
||||||
|
public String getCodeName()
|
||||||
|
{
|
||||||
|
return I18NUtil.getMessage("webscript.code." + code + ".name");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String jsGet_codeName()
|
||||||
|
{
|
||||||
|
return getCodeName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the description of the status code
|
||||||
|
*
|
||||||
|
* @return status code description
|
||||||
|
*/
|
||||||
|
public String getCodeDescription()
|
||||||
|
{
|
||||||
|
return I18NUtil.getMessage("webscript.code." + code + ".description");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String jsGet_codeDescription()
|
||||||
|
{
|
||||||
|
return getCodeDescription();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -29,7 +29,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.alfresco.web.scripts.DeclarativeWebScript;
|
import org.alfresco.web.scripts.DeclarativeWebScript;
|
||||||
import org.alfresco.web.scripts.WebScriptRequest;
|
import org.alfresco.web.scripts.WebScriptRequest;
|
||||||
import org.alfresco.web.scripts.WebScriptResponse;
|
import org.alfresco.web.scripts.WebScriptStatus;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,7 +44,7 @@ public class Index extends DeclarativeWebScript
|
|||||||
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptResponse res)
|
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status)
|
||||||
{
|
{
|
||||||
Map<String, Object> model = new HashMap<String, Object>(7, 1.0f);
|
Map<String, Object> model = new HashMap<String, Object>(7, 1.0f);
|
||||||
model.put("webscripts", getWebScriptRegistry().getWebScripts());
|
model.put("webscripts", getWebScriptRegistry().getWebScripts());
|
||||||
|
@@ -31,7 +31,7 @@ import org.alfresco.web.scripts.DeclarativeWebScript;
|
|||||||
import org.alfresco.web.scripts.WebScriptException;
|
import org.alfresco.web.scripts.WebScriptException;
|
||||||
import org.alfresco.web.scripts.WebScriptPath;
|
import org.alfresco.web.scripts.WebScriptPath;
|
||||||
import org.alfresco.web.scripts.WebScriptRequest;
|
import org.alfresco.web.scripts.WebScriptRequest;
|
||||||
import org.alfresco.web.scripts.WebScriptResponse;
|
import org.alfresco.web.scripts.WebScriptStatus;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,7 +46,7 @@ public class IndexPackage extends DeclarativeWebScript
|
|||||||
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptResponse res)
|
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status)
|
||||||
{
|
{
|
||||||
// extract web script package
|
// extract web script package
|
||||||
String packagePath = req.getExtensionPath();
|
String packagePath = req.getExtensionPath();
|
||||||
|
@@ -31,7 +31,7 @@ import org.alfresco.web.scripts.DeclarativeWebScript;
|
|||||||
import org.alfresco.web.scripts.WebScriptException;
|
import org.alfresco.web.scripts.WebScriptException;
|
||||||
import org.alfresco.web.scripts.WebScriptPath;
|
import org.alfresco.web.scripts.WebScriptPath;
|
||||||
import org.alfresco.web.scripts.WebScriptRequest;
|
import org.alfresco.web.scripts.WebScriptRequest;
|
||||||
import org.alfresco.web.scripts.WebScriptResponse;
|
import org.alfresco.web.scripts.WebScriptStatus;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,7 +46,7 @@ public class IndexURI extends DeclarativeWebScript
|
|||||||
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptResponse res)
|
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status)
|
||||||
{
|
{
|
||||||
// extract web script package
|
// extract web script package
|
||||||
String uriPath = req.getExtensionPath();
|
String uriPath = req.getExtensionPath();
|
||||||
|
@@ -31,7 +31,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.alfresco.web.scripts.DeclarativeWebScript;
|
import org.alfresco.web.scripts.DeclarativeWebScript;
|
||||||
import org.alfresco.web.scripts.WebScriptRequest;
|
import org.alfresco.web.scripts.WebScriptRequest;
|
||||||
import org.alfresco.web.scripts.WebScriptResponse;
|
import org.alfresco.web.scripts.WebScriptStatus;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,7 +46,7 @@ public class IndexUpdate extends DeclarativeWebScript
|
|||||||
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptResponse res)
|
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status)
|
||||||
{
|
{
|
||||||
List<String> tasks = new ArrayList<String>();
|
List<String> tasks = new ArrayList<String>();
|
||||||
|
|
||||||
|
@@ -42,7 +42,7 @@ import org.alfresco.util.ParameterCheck;
|
|||||||
import org.alfresco.web.scripts.DeclarativeWebScript;
|
import org.alfresco.web.scripts.DeclarativeWebScript;
|
||||||
import org.alfresco.web.scripts.WebScriptException;
|
import org.alfresco.web.scripts.WebScriptException;
|
||||||
import org.alfresco.web.scripts.WebScriptRequest;
|
import org.alfresco.web.scripts.WebScriptRequest;
|
||||||
import org.alfresco.web.scripts.WebScriptResponse;
|
import org.alfresco.web.scripts.WebScriptStatus;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ public class KeywordSearch extends DeclarativeWebScript
|
|||||||
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptResponse res)
|
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// process arguments
|
// process arguments
|
||||||
|
@@ -27,11 +27,14 @@ package org.alfresco.web.scripts.bean;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||||
import org.alfresco.web.scripts.DeclarativeWebScript;
|
import org.alfresco.web.scripts.DeclarativeWebScript;
|
||||||
import org.alfresco.web.scripts.WebScriptException;
|
import org.alfresco.web.scripts.WebScriptException;
|
||||||
import org.alfresco.web.scripts.WebScriptRequest;
|
import org.alfresco.web.scripts.WebScriptRequest;
|
||||||
import org.alfresco.web.scripts.WebScriptResponse;
|
import org.alfresco.web.scripts.WebScriptStatus;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,26 +60,34 @@ public class Login extends DeclarativeWebScript
|
|||||||
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptResponse res)
|
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status)
|
||||||
{
|
{
|
||||||
// extract username and password
|
// extract username and password
|
||||||
String username = req.getParameter("u");
|
String username = req.getParameter("u");
|
||||||
if (username == null || username.length() == 0)
|
if (username == null || username.length() == 0)
|
||||||
{
|
{
|
||||||
throw new WebScriptException("Username has not been specified");
|
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Username not specified");
|
||||||
}
|
}
|
||||||
String password = req.getParameter("pw");
|
String password = req.getParameter("pw");
|
||||||
|
if (password == null)
|
||||||
// get ticket
|
{
|
||||||
authenticationService.authenticate(username, password == null ? null : password.toCharArray());
|
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Password not specified");
|
||||||
|
}
|
||||||
// add ticket to model for javascript and template access
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// get ticket
|
||||||
|
authenticationService.authenticate(username, password.toCharArray());
|
||||||
|
|
||||||
|
// add ticket to model for javascript and template access
|
||||||
Map<String, Object> model = new HashMap<String, Object>(7, 1.0f);
|
Map<String, Object> model = new HashMap<String, Object>(7, 1.0f);
|
||||||
model.put("ticket", authenticationService.getCurrentTicket());
|
model.put("ticket", authenticationService.getCurrentTicket());
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
catch(AuthenticationException e)
|
||||||
|
{
|
||||||
|
throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "Login failed");
|
||||||
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
authenticationService.clearCurrentSecurityContext();
|
authenticationService.clearCurrentSecurityContext();
|
||||||
|
@@ -27,13 +27,15 @@ package org.alfresco.web.scripts.bean;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.authentication.TicketComponent;
|
import org.alfresco.repo.security.authentication.TicketComponent;
|
||||||
import org.alfresco.web.scripts.DeclarativeWebScript;
|
import org.alfresco.web.scripts.DeclarativeWebScript;
|
||||||
import org.alfresco.web.scripts.WebScriptException;
|
import org.alfresco.web.scripts.WebScriptException;
|
||||||
import org.alfresco.web.scripts.WebScriptRequest;
|
import org.alfresco.web.scripts.WebScriptRequest;
|
||||||
import org.alfresco.web.scripts.WebScriptResponse;
|
import org.alfresco.web.scripts.WebScriptStatus;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,15 +61,19 @@ public class LoginTicket extends DeclarativeWebScript
|
|||||||
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptResponse res)
|
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status)
|
||||||
{
|
{
|
||||||
// retrieve ticket from request and current ticket
|
// retrieve ticket from request and current ticket
|
||||||
String ticket = req.getExtensionPath();
|
String ticket = req.getExtensionPath();
|
||||||
if (ticket == null && ticket.length() == 0)
|
if (ticket == null && ticket.length() == 0)
|
||||||
{
|
{
|
||||||
throw new WebScriptException("Ticket not specified");
|
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Ticket not specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// construct model for ticket
|
||||||
|
Map<String, Object> model = new HashMap<String, Object>(7, 1.0f);
|
||||||
|
model.put("ticket", ticket);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String ticketUser = ticketComponent.validateTicket(ticket);
|
String ticketUser = ticketComponent.validateTicket(ticket);
|
||||||
@@ -75,17 +81,18 @@ public class LoginTicket extends DeclarativeWebScript
|
|||||||
// do not go any further if tickets are different
|
// do not go any further if tickets are different
|
||||||
if (!AuthenticationUtil.getCurrentUserName().equals(ticketUser))
|
if (!AuthenticationUtil.getCurrentUserName().equals(ticketUser))
|
||||||
{
|
{
|
||||||
// TODO: 404 error
|
status.setRedirect(true);
|
||||||
throw new WebScriptException("Ticket not found");
|
status.setCode(HttpServletResponse.SC_NOT_FOUND);
|
||||||
|
status.setMessage("Ticket not found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(AuthenticationException e)
|
catch(AuthenticationException e)
|
||||||
{
|
{
|
||||||
throw new WebScriptException("Ticket not found");
|
status.setRedirect(true);
|
||||||
|
status.setCode(HttpServletResponse.SC_NOT_FOUND);
|
||||||
|
status.setMessage("Ticket not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Object> model = new HashMap<String, Object>(7, 1.0f);
|
|
||||||
model.put("ticket", ticket);
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,6 +27,8 @@ package org.alfresco.web.scripts.bean;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.authentication.TicketComponent;
|
import org.alfresco.repo.security.authentication.TicketComponent;
|
||||||
@@ -34,7 +36,7 @@ import org.alfresco.service.cmr.security.AuthenticationService;
|
|||||||
import org.alfresco.web.scripts.DeclarativeWebScript;
|
import org.alfresco.web.scripts.DeclarativeWebScript;
|
||||||
import org.alfresco.web.scripts.WebScriptException;
|
import org.alfresco.web.scripts.WebScriptException;
|
||||||
import org.alfresco.web.scripts.WebScriptRequest;
|
import org.alfresco.web.scripts.WebScriptRequest;
|
||||||
import org.alfresco.web.scripts.WebScriptResponse;
|
import org.alfresco.web.scripts.WebScriptStatus;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,15 +71,19 @@ public class LoginTicketDelete extends DeclarativeWebScript
|
|||||||
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptResponse res)
|
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status)
|
||||||
{
|
{
|
||||||
// retrieve ticket from request and current ticket
|
// retrieve ticket from request and current ticket
|
||||||
String ticket = req.getExtensionPath();
|
String ticket = req.getExtensionPath();
|
||||||
if (ticket == null && ticket.length() == 0)
|
if (ticket == null && ticket.length() == 0)
|
||||||
{
|
{
|
||||||
throw new WebScriptException("Ticket not specified");
|
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Ticket not specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// construct model for ticket
|
||||||
|
Map<String, Object> model = new HashMap<String, Object>(7, 1.0f);
|
||||||
|
model.put("ticket", ticket);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String ticketUser = ticketComponent.validateTicket(ticket);
|
String ticketUser = ticketComponent.validateTicket(ticket);
|
||||||
@@ -85,20 +91,23 @@ public class LoginTicketDelete extends DeclarativeWebScript
|
|||||||
// do not go any further if tickets are different
|
// do not go any further if tickets are different
|
||||||
if (!AuthenticationUtil.getCurrentUserName().equals(ticketUser))
|
if (!AuthenticationUtil.getCurrentUserName().equals(ticketUser))
|
||||||
{
|
{
|
||||||
// TODO: 404 error
|
status.setRedirect(true);
|
||||||
throw new WebScriptException("Ticket not found");
|
status.setCode(HttpServletResponse.SC_NOT_FOUND);
|
||||||
|
status.setMessage("Ticket not found");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// delete the ticket
|
||||||
|
authenticationService.invalidateTicket(ticket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(AuthenticationException e)
|
catch(AuthenticationException e)
|
||||||
{
|
{
|
||||||
throw new WebScriptException("Ticket not found");
|
status.setRedirect(true);
|
||||||
|
status.setCode(HttpServletResponse.SC_NOT_FOUND);
|
||||||
|
status.setMessage("Ticket not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the ticket
|
|
||||||
authenticationService.invalidateTicket(ticket);
|
|
||||||
|
|
||||||
Map<String, Object> model = new HashMap<String, Object>(7, 1.0f);
|
|
||||||
model.put("ticket", ticket);
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -36,7 +36,7 @@ import org.alfresco.repo.content.MimetypeMap;
|
|||||||
import org.alfresco.web.config.OpenSearchConfigElement;
|
import org.alfresco.web.config.OpenSearchConfigElement;
|
||||||
import org.alfresco.web.scripts.DeclarativeWebScript;
|
import org.alfresco.web.scripts.DeclarativeWebScript;
|
||||||
import org.alfresco.web.scripts.WebScriptRequest;
|
import org.alfresco.web.scripts.WebScriptRequest;
|
||||||
import org.alfresco.web.scripts.WebScriptResponse;
|
import org.alfresco.web.scripts.WebScriptStatus;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ public class SearchEngines extends DeclarativeWebScript
|
|||||||
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptResponse res)
|
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status)
|
||||||
{
|
{
|
||||||
String urlType = req.getParameter("type");
|
String urlType = req.getParameter("type");
|
||||||
if (urlType == null || urlType.length() == 0)
|
if (urlType == null || urlType.length() == 0)
|
||||||
|
@@ -105,6 +105,13 @@ public class WebScriptJSFResponse implements WebScriptResponse
|
|||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.web.scripts.WebScriptResponse#reset()
|
||||||
|
*/
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.alfresco.web.scripts.WebScriptResponse#getOutputStream()
|
* @see org.alfresco.web.scripts.WebScriptResponse#getOutputStream()
|
||||||
*/
|
*/
|
||||||
@@ -121,6 +128,13 @@ public class WebScriptJSFResponse implements WebScriptResponse
|
|||||||
return fc.getResponseWriter();
|
return fc.getResponseWriter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.web.scripts.WebScriptResponse#setStatus(int)
|
||||||
|
*/
|
||||||
|
public void setStatus(int status)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.alfresco.web.scripts.WebScriptResponse#setContentType(java.lang.String)
|
* @see org.alfresco.web.scripts.WebScriptResponse#setContentType(java.lang.String)
|
||||||
*/
|
*/
|
||||||
@@ -128,4 +142,5 @@ public class WebScriptJSFResponse implements WebScriptResponse
|
|||||||
{
|
{
|
||||||
// Alfresco JSF framework only supports the default of text-html
|
// Alfresco JSF framework only supports the default of text-html
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -66,6 +66,13 @@ public class WebScriptPortletResponse implements WebScriptResponse
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.web.scripts.WebScriptResponse#setStatus(int)
|
||||||
|
*/
|
||||||
|
public void setStatus(int status)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.alfresco.web.scripts.WebScriptResponse#setContentType(java.lang.String)
|
* @see org.alfresco.web.scripts.WebScriptResponse#setContentType(java.lang.String)
|
||||||
*/
|
*/
|
||||||
@@ -74,6 +81,20 @@ public class WebScriptPortletResponse implements WebScriptResponse
|
|||||||
res.setContentType(contentType);
|
res.setContentType(contentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.web.scripts.WebScriptResponse#reset()
|
||||||
|
*/
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
res.reset();
|
||||||
|
}
|
||||||
|
catch(IllegalStateException e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.alfresco.web.scripts.WebScriptResponse#getWriter()
|
* @see org.alfresco.web.scripts.WebScriptResponse#getWriter()
|
||||||
*/
|
*/
|
||||||
@@ -105,5 +126,5 @@ public class WebScriptPortletResponse implements WebScriptResponse
|
|||||||
}
|
}
|
||||||
return portletUrl.toString();
|
return portletUrl.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user