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

@@ -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,12 +52,19 @@ 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;
private WebScriptDescription description;
private ServiceRegistry serviceRegistry;
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)
{
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);
@@ -301,6 +320,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,57 +77,90 @@ public class DeclarativeWebScript extends AbstractWebScript
*/
final public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
{
// construct data model for template
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
// retrieve requested format
String format = req.getFormat();
if (format == null || format.length() == 0)
{
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
{
// 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);
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
*
@@ -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,9 +668,30 @@ 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,23 +387,24 @@ public class TestWebScriptServer
{
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.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;
}

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,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
*/
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

@@ -40,13 +40,21 @@ public abstract class WebScriptRequestImpl implements WebScriptRequest
*/
public String getExtensionPath()
{
String servicePath = getServiceMatch().getPath();
String extensionPath = getPathInfo();
int extIdx = extensionPath.indexOf(servicePath);
if (extIdx != -1)
String extensionPath = "";
WebScriptMatch match = getServiceMatch();
if (match != null)
{
int extLength = (servicePath.endsWith("/") ? servicePath.length() : servicePath.length() + 1);
extensionPath = extensionPath.substring(extIdx + extLength);
String servicePath = getServiceMatch().getPath();
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,30 +73,37 @@ public abstract class WebScriptRequestImpl implements WebScriptRequest
public String getFormat()
{
String format = null;
FormatStyle style = getServiceMatch().getWebScript().getDescription().getFormatStyle();
// extract format from extension
if (style == FormatStyle.extension || style == FormatStyle.any)
WebScriptMatch match = getServiceMatch();
if (match != null)
{
String pathInfo = getPathInfo();
int extIdx = pathInfo.lastIndexOf('.');
if (extIdx != -1)
FormatStyle style = getServiceMatch().getWebScript().getDescription().getFormatStyle();
// extract format from extension
if (style == FormatStyle.extension || style == FormatStyle.any)
{
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)
String pathInfo = getPathInfo();
if (pathInfo != null)
{
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()
{
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,94 +83,159 @@ 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
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 (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();
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();
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)
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)
{
authenticatedExecute(scriptReq, scriptRes);
TransactionUtil.executeInUserTransaction(transactionService, work);
}
else
{
// encapsulate script within transaction
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");
TransactionUtil.executeInNonPropagatingUserTransaction(transactionService, work);
}
}
}
else
finally
{
String msg = "Script url (" + method + ") " + scriptUrl + " does not map to a Web Script.";
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
@@ -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()
*/
@@ -91,5 +112,5 @@ public class WebScriptServletResponse implements WebScriptResponse
{
return url;
}
}

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");
// get ticket
authenticationService.authenticate(username, password == null ? null : password.toCharArray());
// add ticket to model for javascript and template access
if (password == null)
{
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Password not specified");
}
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()
*/
@@ -105,5 +126,5 @@ public class WebScriptPortletResponse implements WebScriptResponse
}
return portletUrl.toString();
}
}