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:
David Caruana
2007-06-05 10:41:51 +00:00
parent 546eccf561
commit ac9960758f
28 changed files with 1081 additions and 218 deletions

View File

@@ -1 +1,86 @@
##
## 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

View File

@@ -1,5 +1,6 @@
<webscript>
<shortname>Web Scripts Documentation</shortname>
<description>Web Scripts Documentation</description>
<url format="html" template="/" />
<url format="html" template="/index" />
</webscript>

View 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>&nbsp;
<tr><td><b>Message:</b><td>${status.message!"<i>&lt;Not specified&gt;</i>"}
<tr><td><b>Exception:</b><td>${status.exception!"None"}
<#if status.exception?exists>
<tr><td><td>&nbsp;
<#list status.exception.stackTrace as element>
<tr><td><td>${element}
</#list>
</#if>
</table>
</body>
</html>

View File

@@ -3,6 +3,19 @@
<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 -->
<!-- -->

View File

@@ -24,10 +24,12 @@
*/
package org.alfresco.web.scripts;
import java.io.IOException;
import java.io.Writer;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.alfresco.repo.jscript.Node;
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.web.scripts.WebScriptDescription.RequiredAuthentication;
import org.alfresco.web.scripts.WebScriptDescription.RequiredTransaction;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
@@ -48,6 +52,9 @@ import org.alfresco.web.scripts.WebScriptDescription.RequiredTransaction;
*/
public abstract class AbstractWebScript implements WebScript
{
// Logger
private static final Log logger = LogFactory.getLog(AbstractWebScript.class);
// dependencies
private WebScriptContext scriptContext;
private WebScriptRegistry scriptRegistry;
@@ -55,6 +62,10 @@ public abstract class AbstractWebScript implements WebScript
private ServiceRegistry serviceRegistry;
private DescriptorService descriptorService;
// Status Template cache
private Map<String, StatusTemplate> statusTemplates = new HashMap<String, StatusTemplate>();
private ReentrantReadWriteLock statusTemplateLock = new ReentrantReadWriteLock();
//
// Initialisation
@@ -102,6 +113,15 @@ public abstract class AbstractWebScript implements WebScript
public void init(WebScriptRegistry 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
*
* @param req web script request
* @param res web script response
* @param customModel custom model entries
*
* @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
Map<String, Object> model = new HashMap<String, Object>(7, 1.0f);
@@ -302,6 +321,188 @@ public abstract class AbstractWebScript implements WebScript
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
*
@@ -312,4 +513,26 @@ public abstract class AbstractWebScript implements WebScript
{
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;
}
}

View File

@@ -31,11 +31,12 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.repo.jscript.Node;
import org.alfresco.repo.jscript.ScriptableHashMap;
import org.alfresco.repo.template.TemplateNode;
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.LogFactory;
import org.mozilla.javascript.Context;
@@ -76,12 +77,30 @@ public class DeclarativeWebScript extends AbstractWebScript
*/
final public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
{
// retrieve requested format
String format = req.getFormat();
if (format == null || format.length() == 0)
{
format = getDescription().getDefaultFormat();
}
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
Map<String, Object> model = executeImpl(req, res);
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)
@@ -89,7 +108,7 @@ public class DeclarativeWebScript extends AbstractWebScript
if (logger.isDebugEnabled())
logger.debug("Executing script " + executeScript);
Map<String, Object> scriptModel = createScriptModel(req, res, model);
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);
@@ -97,33 +116,48 @@ public class DeclarativeWebScript extends AbstractWebScript
mergeScriptModelIntoTemplateModel(returnModel, model);
}
// process requested format
String format = req.getFormat();
if (format == null || format.length() == 0)
{
format = getDescription().getDefaultFormat();
}
// create model for template rendering
Map<String, Object> templateModel = createTemplateModel(req, res, model);
String mimetype = getWebScriptRegistry().getFormatRegistry().getMimeType(req.getAgent(), format);
if (mimetype == null)
// is a redirect to a status specific template required?
if (status.getRedirect())
{
throw new WebScriptException("Web Script format '" + format + "' is not registered");
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("Response content type: " + mimetype);
logger.debug("Rendering response: content type=" + mimetype + ", status=" + statusCode);
try
{
Map<String, Object> templateModel = createTemplateModel(req, res, model);
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);
}
}
@@ -192,10 +226,9 @@ public class DeclarativeWebScript extends AbstractWebScript
* Execute custom Java logic
*
* @param req Web Script request
* @param res Web Script response
* @return custom service model
*/
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptResponse res)
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status)
{
return null;
}

View File

@@ -81,7 +81,7 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
// map of web scripts by url
// 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
private Map<String, Path> packageByPath = new TreeMap<String, Path>();
@@ -258,6 +258,7 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
for (URI uri : serviceDesc.getURIs())
{
// establish static part of url template
boolean wildcard = false;
String uriTemplate = uri.getURI();
int queryArgIdx = uriTemplate.indexOf('?');
if (queryArgIdx != -1)
@@ -268,6 +269,7 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
if (tokenIdx != -1)
{
uriTemplate = uriTemplate.substring(0, tokenIdx);
wildcard = true;
}
if (serviceDesc.getFormatStyle() != WebScriptDescription.FormatStyle.argument)
{
@@ -282,7 +284,8 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
String uriIdx = serviceDesc.getMethod().toString() + ":" + uriTemplate;
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()))
{
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
{
webscriptsByURL.put(uriIdx, serviceImpl);
URLIndex urlIndex = new URLIndex(uriTemplate, wildcard, serviceImpl);
webscriptsByURL.put(uriIdx, urlIndex);
if (logger.isDebugEnabled())
logger.debug("Registered Web Script URL '" + uriIdx + "'");
@@ -357,7 +361,7 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
subpath = path.createChildPath(part);
uriByPath.put(subpath.getPath(), subpath);
if (logger.isDebugEnabled())
logger.debug("Registered Web Script URI " + subpath.getPath());
logger.debug("Registered Web Script URI Path " + subpath.getPath());
}
path = subpath;
}
@@ -387,7 +391,8 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
}
// 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
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)
{
long startTime = System.currentTimeMillis();
// TODO: Replace with more efficient approach
String matchedPath = null;
DeclarativeWebScriptMatch apiServiceMatch = null;
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();
if (match.startsWith(indexedPath))
URLIndex urlIndex = entry.getValue();
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(matchPath, service.getValue());
apiServiceMatch = new DeclarativeWebScriptMatch(urlIndex.path, urlIndex.script);
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;
}
@@ -634,6 +658,7 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
{
private String path;
private WebScript service;
private Kind kind;
/**
* Construct
@@ -643,10 +668,31 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
*/
public DeclarativeWebScriptMatch(String path, WebScript service)
{
this.kind = Kind.FULL;
this.path = path;
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)
* @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;
}
}

View File

@@ -24,6 +24,8 @@
*/
package org.alfresco.web.scripts;
import java.io.IOException;
import org.alfresco.repo.template.FreeMarkerProcessor;
import org.alfresco.repo.template.QNameAwareObjectWrapper;
import org.alfresco.service.cmr.repository.ProcessorExtension;
@@ -37,6 +39,7 @@ import org.springframework.context.ApplicationListener;
import freemarker.cache.MruCacheStorage;
import freemarker.cache.TemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
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
*/

View File

@@ -353,12 +353,7 @@ public class TestWebScriptServer
command[0].equals("post") ||
command[0].equals("delete"))
{
if (command.length < 2)
{
return "Syntax Error.\n";
}
String uri = command[1];
String uri = (command.length > 1) ? command[1] : null;
MockHttpServletResponse res = submitRequest(command[0], uri);
bout.write(res.getContentAsByteArray());
out.println();
@@ -392,7 +387,11 @@ public class TestWebScriptServer
{
MockHttpServletRequest req = new MockHttpServletRequest(method, uri);
// set parameters
req.setContextPath("/alfresco");
req.setServletPath("/service");
if (uri != null)
{
int iArgIndex = uri.indexOf('?');
if (iArgIndex != -1 && iArgIndex != uri.length() -1)
{
@@ -404,11 +403,8 @@ public class TestWebScriptServer
req.addParameter(parts[0], (parts.length == 2) ? parts[1] : null);
}
}
// set paths
req.setContextPath("/alfresco");
req.setServletPath("/service");
req.setPathInfo(iArgIndex == -1 ? uri : uri.substring(0, iArgIndex));
}
return req;
}

View File

@@ -24,6 +24,8 @@
*/
package org.alfresco.web.scripts;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.error.AlfrescoRuntimeException;
/**
@@ -35,6 +37,15 @@ public class WebScriptException extends AlfrescoRuntimeException
{
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)
{
super(msgId);
@@ -54,4 +65,10 @@ public class WebScriptException extends AlfrescoRuntimeException
{
super(msgId, args, cause);
}
public int getStatus()
{
return status;
}
}

View File

@@ -26,12 +26,24 @@ package org.alfresco.web.scripts;
/**
* Represents a URL to Web Script match
* Represents a URL request to Web Script match
*
* @author davidc
*/
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
@@ -43,7 +55,7 @@ public interface WebScriptMatch
/**
* Gets the matching web script
*
* @return service
* @return service (or null, if match kind is URI)
*/
public WebScript getWebScript();

View File

@@ -39,15 +39,23 @@ public abstract class WebScriptRequestImpl implements WebScriptRequest
* @see org.alfresco.web.scripts.WebScriptRequest#getExtensionPath()
*/
public String getExtensionPath()
{
String extensionPath = "";
WebScriptMatch match = getServiceMatch();
if (match != null)
{
String servicePath = getServiceMatch().getPath();
String extensionPath = getPathInfo();
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;
}
@@ -65,18 +73,24 @@ public abstract class WebScriptRequestImpl implements WebScriptRequest
public String getFormat()
{
String format = null;
WebScriptMatch match = getServiceMatch();
if (match != null)
{
FormatStyle style = getServiceMatch().getWebScript().getDescription().getFormatStyle();
// extract format from extension
if (style == FormatStyle.extension || style == FormatStyle.any)
{
String pathInfo = getPathInfo();
if (pathInfo != null)
{
int extIdx = pathInfo.lastIndexOf('.');
if (extIdx != -1)
{
format = pathInfo.substring(extIdx +1);
}
}
}
// extract format from argument
if (style == FormatStyle.argument || style == FormatStyle.any)
@@ -91,6 +105,7 @@ public abstract class WebScriptRequestImpl implements WebScriptRequest
format = argFormat;
}
}
}
return (format == null || format.length() == 0) ? "" : format;
}
@@ -100,7 +115,12 @@ public abstract class WebScriptRequestImpl implements WebScriptRequest
*/
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)
{
return style;

View File

@@ -44,6 +44,12 @@ public interface WebScriptResponse
public static final String JSON_FORMAT = "json";
public static final String OPENSEARCH_DESCRIPTION_FORMAT = "opensearchdescription";
/**
* Sets the Response Status
*
* @param status
*/
public void setStatus(int status);
/**
* Sets the Content Type
@@ -68,6 +74,11 @@ public interface WebScriptResponse
*/
public OutputStream getOutputStream() throws IOException;
/**
* Clears response buffer
*/
public void reset();
/**
* Encode a script URL
*

View File

@@ -25,8 +25,14 @@
package org.alfresco.web.scripts;
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.repo.content.MimetypeMap;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.TransactionUtil;
import org.alfresco.service.transaction.TransactionService;
@@ -77,17 +83,40 @@ public abstract class WebScriptRuntime
long startRuntime = System.currentTimeMillis();
String method = getScriptMethod();
String scriptUrl = getScriptUrl();
String scriptUrl = null;
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())
logger.debug("Processing script url (" + 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)
{
String msg = "Script url " + scriptUrl + " does not map to a Web Script.";
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();
@@ -145,10 +174,6 @@ public abstract class WebScriptRuntime
}
}
}
catch(IOException e)
{
throw new WebScriptException("Failed to execute script", e);
}
finally
{
if (logger.isDebugEnabled())
@@ -158,13 +183,59 @@ public abstract class WebScriptRuntime
}
}
}
else
catch(Throwable e)
{
String msg = "Script url (" + method + ") " + scriptUrl + " does not map to a Web Script.";
if (logger.isDebugEnabled())
logger.debug(msg);
// 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
@@ -196,7 +267,7 @@ public abstract class WebScriptRuntime
}
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
{
@@ -220,7 +291,6 @@ public abstract class WebScriptRuntime
//
if (authenticate(required, isGuest))
{
//
// Execute Web Script
wrappedExecute(scriptReq, scriptRes);
}

View File

@@ -120,7 +120,8 @@ public class WebScriptServletRequest extends WebScriptRequestImpl
*/
public String getServicePath()
{
return getServiceContextPath() + req.getPathInfo();
String pathInfo = req.getPathInfo();
return getServiceContextPath() + ((pathInfo == null) ? "" : req.getPathInfo());
}
/* (non-Javadoc)

View File

@@ -28,7 +28,6 @@ import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
@@ -60,6 +59,14 @@ public class WebScriptServletResponse implements WebScriptResponse
return res;
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#setStatus(int)
*/
public void setStatus(int status)
{
res.setStatus(status);
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#setContentType(java.lang.String)
*/
@@ -68,6 +75,20 @@ public class WebScriptServletResponse implements WebScriptResponse
res.setContentType(contentType);
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#reset()
*/
public void reset()
{
try
{
res.reset();
}
catch(IllegalStateException e)
{
}
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#getWriter()
*/

View 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();
}
}

View File

@@ -29,7 +29,7 @@ import java.util.Map;
import org.alfresco.web.scripts.DeclarativeWebScript;
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)
*/
@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);
model.put("webscripts", getWebScriptRegistry().getWebScripts());

View File

@@ -31,7 +31,7 @@ import org.alfresco.web.scripts.DeclarativeWebScript;
import org.alfresco.web.scripts.WebScriptException;
import org.alfresco.web.scripts.WebScriptPath;
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)
*/
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptResponse res)
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status)
{
// extract web script package
String packagePath = req.getExtensionPath();

View File

@@ -31,7 +31,7 @@ import org.alfresco.web.scripts.DeclarativeWebScript;
import org.alfresco.web.scripts.WebScriptException;
import org.alfresco.web.scripts.WebScriptPath;
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)
*/
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptResponse res)
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status)
{
// extract web script package
String uriPath = req.getExtensionPath();

View File

@@ -31,7 +31,7 @@ import java.util.Map;
import org.alfresco.web.scripts.DeclarativeWebScript;
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)
*/
@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>();

View File

@@ -42,7 +42,7 @@ import org.alfresco.util.ParameterCheck;
import org.alfresco.web.scripts.DeclarativeWebScript;
import org.alfresco.web.scripts.WebScriptException;
import org.alfresco.web.scripts.WebScriptRequest;
import org.alfresco.web.scripts.WebScriptResponse;
import org.alfresco.web.scripts.WebScriptStatus;
import org.apache.commons.logging.Log;
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)
*/
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptResponse res)
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status)
{
//
// process arguments

View File

@@ -27,11 +27,14 @@ package org.alfresco.web.scripts.bean;
import java.util.HashMap;
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.web.scripts.DeclarativeWebScript;
import org.alfresco.web.scripts.WebScriptException;
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)
*/
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptResponse res)
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status)
{
// extract username and password
String username = req.getParameter("u");
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");
if (password == null)
{
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Password not specified");
}
// get ticket
authenticationService.authenticate(username, password == null ? null : password.toCharArray());
// add ticket to model for javascript and template access
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);
model.put("ticket", authenticationService.getCurrentTicket());
return model;
}
catch(AuthenticationException e)
{
throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "Login failed");
}
finally
{
authenticationService.clearCurrentSecurityContext();

View File

@@ -27,13 +27,15 @@ package org.alfresco.web.scripts.bean;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.TicketComponent;
import org.alfresco.web.scripts.DeclarativeWebScript;
import org.alfresco.web.scripts.WebScriptException;
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)
*/
@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
String ticket = req.getExtensionPath();
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
{
String ticketUser = ticketComponent.validateTicket(ticket);
@@ -75,17 +81,18 @@ public class LoginTicket extends DeclarativeWebScript
// do not go any further if tickets are different
if (!AuthenticationUtil.getCurrentUserName().equals(ticketUser))
{
// TODO: 404 error
throw new WebScriptException("Ticket not found");
status.setRedirect(true);
status.setCode(HttpServletResponse.SC_NOT_FOUND);
status.setMessage("Ticket not found");
}
}
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;
}

View File

@@ -27,6 +27,8 @@ package org.alfresco.web.scripts.bean;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
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.WebScriptException;
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)
*/
@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
String ticket = req.getExtensionPath();
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
{
String ticketUser = ticketComponent.validateTicket(ticket);
@@ -85,20 +91,23 @@ public class LoginTicketDelete extends DeclarativeWebScript
// do not go any further if tickets are different
if (!AuthenticationUtil.getCurrentUserName().equals(ticketUser))
{
// TODO: 404 error
throw new WebScriptException("Ticket not found");
status.setRedirect(true);
status.setCode(HttpServletResponse.SC_NOT_FOUND);
status.setMessage("Ticket not found");
}
else
{
// delete the ticket
authenticationService.invalidateTicket(ticket);
}
}
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;
}

View File

@@ -36,7 +36,7 @@ import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.web.config.OpenSearchConfigElement;
import org.alfresco.web.scripts.DeclarativeWebScript;
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.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)
*/
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptResponse res)
protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status)
{
String urlType = req.getParameter("type");
if (urlType == null || urlType.length() == 0)

View File

@@ -105,6 +105,13 @@ public class WebScriptJSFResponse implements WebScriptResponse
return buf.toString();
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#reset()
*/
public void reset()
{
}
/**
* @see org.alfresco.web.scripts.WebScriptResponse#getOutputStream()
*/
@@ -121,6 +128,13 @@ public class WebScriptJSFResponse implements WebScriptResponse
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)
*/
@@ -128,4 +142,5 @@ public class WebScriptJSFResponse implements WebScriptResponse
{
// Alfresco JSF framework only supports the default of text-html
}
}

View File

@@ -66,6 +66,13 @@ public class WebScriptPortletResponse implements WebScriptResponse
return res;
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#setStatus(int)
*/
public void setStatus(int status)
{
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#setContentType(java.lang.String)
*/
@@ -74,6 +81,20 @@ public class WebScriptPortletResponse implements WebScriptResponse
res.setContentType(contentType);
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#reset()
*/
public void reset()
{
try
{
res.reset();
}
catch(IllegalStateException e)
{
}
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#getWriter()
*/