mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Web Scripts:
- support url extension for specifying required response format - update scriptUrl method to handle various forms of specifying format on url - refactor web script request hierarchy; remove copy & paste - add reset web script registry to web script "Test Server" git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5803 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -40,6 +40,7 @@ import javax.servlet.ServletContext;
|
||||
import org.alfresco.service.cmr.repository.FileTypeImageSize;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.alfresco.util.AbstractLifecycleBean;
|
||||
import org.alfresco.web.scripts.WebScriptDescription.FormatStyle;
|
||||
import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
|
||||
import org.alfresco.web.scripts.WebScriptDescription.RequiredTransaction;
|
||||
import org.alfresco.web.scripts.WebScriptDescription.URI;
|
||||
@@ -238,7 +239,9 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
||||
serviceImpl.init(this);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Found Web Script " + id + " (desc: " + serviceDescPath + ", impl: " + serviceImplName + ", auth: " + serviceDesc.getRequiredAuthentication() + ", trx: " + serviceDesc.getRequiredTransaction() + ")");
|
||||
logger.debug("Found Web Script " + id + " (desc: " + serviceDescPath + ", impl: " + serviceImplName + ", auth: " +
|
||||
serviceDesc.getRequiredAuthentication() + ", trx: " + serviceDesc.getRequiredTransaction() + ", format: " +
|
||||
serviceDesc.getFormatStyle() + ")");
|
||||
|
||||
// register service and its urls
|
||||
webscriptsById.put(id, serviceImpl);
|
||||
@@ -256,6 +259,14 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
||||
{
|
||||
uriTemplate = uriTemplate.substring(0, tokenIdx);
|
||||
}
|
||||
if (serviceDesc.getFormatStyle() != WebScriptDescription.FormatStyle.argument)
|
||||
{
|
||||
int extIdx = uriTemplate.lastIndexOf(".");
|
||||
if (extIdx != -1)
|
||||
{
|
||||
uriTemplate = uriTemplate.substring(0, extIdx);
|
||||
}
|
||||
}
|
||||
|
||||
// index service by static part of url (ensuring no other service has already claimed the url)
|
||||
String uriIdx = serviceDesc.getMethod().toString() + ":" + uriTemplate;
|
||||
@@ -338,7 +349,7 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
||||
List urlElements = rootElement.elements("url");
|
||||
if (urlElements == null || urlElements.size() == 0)
|
||||
{
|
||||
throw new WebScriptException("Expected at one <url> element");
|
||||
throw new WebScriptException("Expected at least one <url> element");
|
||||
}
|
||||
List<WebScriptDescription.URI> uris = new ArrayList<WebScriptDescription.URI>();
|
||||
Iterator iterElements = urlElements.iterator();
|
||||
@@ -402,6 +413,28 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
||||
}
|
||||
}
|
||||
|
||||
// retrieve format
|
||||
String defaultFormat = uris.get(0).getFormat();
|
||||
FormatStyle formatStyle = FormatStyle.any;
|
||||
Element formatElement = rootElement.element("format");
|
||||
if (formatElement != null)
|
||||
{
|
||||
String formatStyleStr = formatElement.getTextTrim();
|
||||
if (formatStyleStr != null && formatStyleStr.length() > 0)
|
||||
{
|
||||
formatStyle = FormatStyle.valueOf(formatStyleStr);
|
||||
if (formatStyle == null)
|
||||
{
|
||||
throw new WebScriptException("Format Style '" + formatStyle + "' is not a valid value");
|
||||
}
|
||||
}
|
||||
String defaultFormatStr = formatElement.attributeValue("default");
|
||||
if (defaultFormatStr != null && defaultFormatStr.length() > 0)
|
||||
{
|
||||
defaultFormat = defaultFormatStr;
|
||||
}
|
||||
}
|
||||
|
||||
// construct service description
|
||||
WebScriptDescriptionImpl serviceDesc = new WebScriptDescriptionImpl();
|
||||
serviceDesc.setStore(store);
|
||||
@@ -414,7 +447,8 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
||||
serviceDesc.setRequiredTransaction(reqTrx);
|
||||
serviceDesc.setMethod(method);
|
||||
serviceDesc.setUris(uris.toArray(new WebScriptDescription.URI[uris.size()]));
|
||||
serviceDesc.setDefaultFormat(uris.get(0).getFormat());
|
||||
serviceDesc.setDefaultFormat(defaultFormat);
|
||||
serviceDesc.setFormatStyle(formatStyle);
|
||||
return serviceDesc;
|
||||
}
|
||||
catch(DocumentException e)
|
||||
|
@@ -26,6 +26,8 @@ package org.alfresco.web.scripts;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.web.scripts.WebScriptDescription.FormatStyle;
|
||||
|
||||
import freemarker.template.TemplateBooleanModel;
|
||||
import freemarker.template.TemplateMethodModelEx;
|
||||
import freemarker.template.TemplateModelException;
|
||||
@@ -73,15 +75,23 @@ public final class ScriptUrlMethod implements TemplateMethodModelEx
|
||||
{
|
||||
prefixServiceUrl = ((TemplateBooleanModel)args.get(1)).getAsBoolean();
|
||||
}
|
||||
|
||||
if (arg0 instanceof TemplateScalarModel)
|
||||
{
|
||||
String arg = ((TemplateScalarModel)arg0).getAsString();
|
||||
String url = prefixServiceUrl ? req.getServicePath() : "";
|
||||
url += arg;
|
||||
url += (arg.length() != 0) ? "&" : "";
|
||||
url += "guest=" + (req.isGuest() ? "true" : "");
|
||||
url += (req.getFormat().length() != 0) ? "&format=" + req.getFormat() : "";
|
||||
result = res.encodeScriptUrl(url);
|
||||
|
||||
StringBuffer buf = new StringBuffer(128);
|
||||
buf.append(prefixServiceUrl ? req.getServicePath() : "");
|
||||
buf.append(arg);
|
||||
buf.append(arg.length() != 0 ? "&" : "");
|
||||
buf.append("guest=" + (req.isGuest() ? "true" : ""));
|
||||
if (req.getFormatStyle() == FormatStyle.argument)
|
||||
{
|
||||
buf.append("&format=");
|
||||
buf.append(req.getFormat());
|
||||
}
|
||||
|
||||
result = res.encodeScriptUrl(buf.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -323,6 +323,12 @@ public class TestWebScriptServer
|
||||
out.println();
|
||||
}
|
||||
|
||||
else if (command[0].equals("reset"))
|
||||
{
|
||||
registry.reset();
|
||||
out.println("Registry reset.");
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return "Syntax Error.\n";
|
||||
|
@@ -55,6 +55,15 @@ public interface WebScriptDescription
|
||||
requiresnew
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumeration of ways to specify format
|
||||
*/
|
||||
public enum FormatStyle
|
||||
{
|
||||
any, // any of the following styles
|
||||
extension, // /a/b/c.x
|
||||
argument // /a/b/c?format=x
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the root path of the store of this web script
|
||||
@@ -132,6 +141,13 @@ public interface WebScriptDescription
|
||||
*/
|
||||
public URI[] getURIs();
|
||||
|
||||
/**
|
||||
* Gets the style of Format discriminator supported by this web script
|
||||
*
|
||||
* @return format style
|
||||
*/
|
||||
public FormatStyle getFormatStyle();
|
||||
|
||||
/**
|
||||
* Gets a URI by format
|
||||
*
|
||||
|
@@ -45,6 +45,7 @@ public class WebScriptDescriptionImpl implements WebScriptDescription
|
||||
private String description;
|
||||
private RequiredAuthentication requiredAuthentication;
|
||||
private RequiredTransaction requiredTransaction;
|
||||
private FormatStyle formatStyle;
|
||||
private String httpMethod;
|
||||
private URI[] uris;
|
||||
private String defaultFormat;
|
||||
@@ -204,6 +205,24 @@ public class WebScriptDescriptionImpl implements WebScriptDescription
|
||||
return this.requiredTransaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the format style
|
||||
*
|
||||
* @param formatStyle
|
||||
*/
|
||||
public void setFormatStyle(FormatStyle formatStyle)
|
||||
{
|
||||
this.formatStyle = formatStyle;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptDescription#getFormatStyle()
|
||||
*/
|
||||
public FormatStyle getFormatStyle()
|
||||
{
|
||||
return this.formatStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the service http method
|
||||
*
|
||||
|
@@ -24,6 +24,8 @@
|
||||
*/
|
||||
package org.alfresco.web.scripts;
|
||||
|
||||
import org.alfresco.web.scripts.WebScriptDescription.FormatStyle;
|
||||
|
||||
|
||||
/**
|
||||
* Web Script Request
|
||||
@@ -76,6 +78,13 @@ public interface WebScriptRequest
|
||||
*/
|
||||
public String getURL();
|
||||
|
||||
/**
|
||||
* Gets the service specific path
|
||||
*
|
||||
* @return request path e.g. /search/keyword
|
||||
*/
|
||||
public String getPathInfo();
|
||||
|
||||
/**
|
||||
* Gets the query String
|
||||
*
|
||||
@@ -125,6 +134,13 @@ public interface WebScriptRequest
|
||||
*/
|
||||
public String getFormat();
|
||||
|
||||
/**
|
||||
* Get the style the Format was specified in
|
||||
*
|
||||
* @return format style (excludes any)
|
||||
*/
|
||||
public FormatStyle getFormatStyle();
|
||||
|
||||
/**
|
||||
* Get User Agent
|
||||
*
|
||||
|
122
source/java/org/alfresco/web/scripts/WebScriptRequestImpl.java
Normal file
122
source/java/org/alfresco/web/scripts/WebScriptRequestImpl.java
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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 org.alfresco.web.scripts.WebScriptDescription.FormatStyle;
|
||||
|
||||
|
||||
/**
|
||||
* Basic Implementation of a Web Script Request
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public abstract class WebScriptRequestImpl implements WebScriptRequest
|
||||
{
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getExtensionPath()
|
||||
*/
|
||||
public String getExtensionPath()
|
||||
{
|
||||
String servicePath = getServiceMatch().getPath();
|
||||
String extensionPath = getPathInfo();
|
||||
int extIdx = extensionPath.indexOf(servicePath);
|
||||
if (extIdx != -1)
|
||||
{
|
||||
int extLength = (servicePath.endsWith("/") ? servicePath.length() : servicePath.length() + 1);
|
||||
extensionPath = extensionPath.substring(extIdx + extLength);
|
||||
}
|
||||
return extensionPath;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#isGuest()
|
||||
*/
|
||||
public boolean isGuest()
|
||||
{
|
||||
return Boolean.valueOf(getParameter("guest"));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getFormat()
|
||||
*/
|
||||
public String getFormat()
|
||||
{
|
||||
String format = null;
|
||||
FormatStyle style = getServiceMatch().getWebScript().getDescription().getFormatStyle();
|
||||
|
||||
// extract format from extension
|
||||
if (style == FormatStyle.extension || style == FormatStyle.any)
|
||||
{
|
||||
String pathInfo = getPathInfo();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return (format == null || format.length() == 0) ? "" : format;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getFormatStyle()
|
||||
*/
|
||||
public FormatStyle getFormatStyle()
|
||||
{
|
||||
FormatStyle style = getServiceMatch().getWebScript().getDescription().getFormatStyle();
|
||||
if (style != FormatStyle.any)
|
||||
{
|
||||
return style;
|
||||
}
|
||||
else
|
||||
{
|
||||
String argFormat = getParameter("format");
|
||||
if (argFormat != null && argFormat.length() > 0)
|
||||
{
|
||||
return FormatStyle.argument;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FormatStyle.extension;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -104,7 +104,12 @@ public abstract class WebScriptRuntime
|
||||
{
|
||||
String user = AuthenticationUtil.getCurrentUserName();
|
||||
String locale = I18NUtil.getLocale().toString();
|
||||
logger.debug("Invoking Web Script " + description.getId() + (user == null ? " (unauthenticated)" : " (authenticated as " + user + ")" + " (" + locale + ")"));
|
||||
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)
|
||||
|
@@ -36,7 +36,7 @@ import org.alfresco.web.config.ServerConfigElement;
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class WebScriptServletRequest implements WebScriptRequest
|
||||
public class WebScriptServletRequest extends WebScriptRequestImpl
|
||||
{
|
||||
/** Server Config */
|
||||
private ServerConfigElement serverConfig;
|
||||
@@ -82,23 +82,17 @@ public class WebScriptServletRequest implements WebScriptRequest
|
||||
{
|
||||
return req;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the matching API Service for this request
|
||||
*
|
||||
* @return the service match
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getServiceMatch()
|
||||
*/
|
||||
public WebScriptMatch getServiceMatch()
|
||||
{
|
||||
return serviceMatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get server portion of the request
|
||||
*
|
||||
* e.g. scheme://host:port
|
||||
*
|
||||
* @return server path
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getServerPath()
|
||||
*/
|
||||
public String getServerPath()
|
||||
{
|
||||
@@ -112,36 +106,38 @@ public class WebScriptServletRequest implements WebScriptRequest
|
||||
{
|
||||
return req.getContextPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Alfresco Web Script Context Path
|
||||
*
|
||||
* @return service url e.g. /alfresco/service
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getServiceContextPath()
|
||||
*/
|
||||
public String getServiceContextPath()
|
||||
{
|
||||
return req.getContextPath() + req.getServletPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Alfresco Service Path
|
||||
*
|
||||
* @return service url e.g. /alfresco/service/search/keyword
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getServicePath()
|
||||
*/
|
||||
public String getServicePath()
|
||||
{
|
||||
return getServiceContextPath() + req.getPathInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full request URL
|
||||
*
|
||||
* @return request url e.g. /alfresco/service/search/keyword?q=term
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getURL()
|
||||
*/
|
||||
public String getURL()
|
||||
{
|
||||
return getServicePath() + (req.getQueryString() != null ? "?" + req.getQueryString() : "");
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getPathInfo()
|
||||
*/
|
||||
public String getPathInfo()
|
||||
{
|
||||
return req.getPathInfo();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getQueryString()
|
||||
@@ -169,52 +165,7 @@ public class WebScriptServletRequest implements WebScriptRequest
|
||||
{
|
||||
return req.getParameter(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path extension beyond the path registered for this service
|
||||
*
|
||||
* e.g.
|
||||
* a) service registered path = /search/engine
|
||||
* b) request path = /search/engine/external
|
||||
*
|
||||
* => /external
|
||||
*
|
||||
* @return extension path
|
||||
*/
|
||||
public String getExtensionPath()
|
||||
{
|
||||
String servicePath = serviceMatch.getPath();
|
||||
String extensionPath = req.getPathInfo();
|
||||
int extIdx = extensionPath.indexOf(servicePath);
|
||||
if (extIdx != -1)
|
||||
{
|
||||
int extLength = (servicePath.endsWith("/") ? servicePath.length() : servicePath.length() + 1);
|
||||
extensionPath = extensionPath.substring(extIdx + extLength);
|
||||
}
|
||||
return extensionPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if Guest User?
|
||||
*
|
||||
* @return true => guest user
|
||||
*/
|
||||
public boolean isGuest()
|
||||
{
|
||||
return Boolean.valueOf(getParameter("guest"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Requested Format
|
||||
*
|
||||
* @return content type requested
|
||||
*/
|
||||
public String getFormat()
|
||||
{
|
||||
String format = getParameter("format");
|
||||
return (format == null || format.length() == 0) ? "" : format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get User Agent
|
||||
*
|
||||
|
204
source/java/org/alfresco/web/scripts/WebScriptURLRequest.java
Normal file
204
source/java/org/alfresco/web/scripts/WebScriptURLRequest.java
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* 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 java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* Web Script Request implementation that acts upon a string representation
|
||||
* of a URL
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public abstract class WebScriptURLRequest extends WebScriptRequestImpl
|
||||
{
|
||||
/** Script Url components */
|
||||
protected String contextPath;
|
||||
protected String servletPath;
|
||||
protected String pathInfo;
|
||||
protected String queryString;
|
||||
protected Map<String, String> queryArgs;
|
||||
|
||||
/** Service bound to this request */
|
||||
protected WebScriptMatch serviceMatch;
|
||||
|
||||
|
||||
/**
|
||||
* Splits a Web Script Url into its component parts
|
||||
*
|
||||
* @param scriptUrl url e.g. /alfresco/service/mytasks?f=1
|
||||
* @return url parts [0] = context (e.g. alfresco), [1] = servlet (e.g. service), [2] = script (e.g. mytasks), [3] = args (e.g. f=1)
|
||||
*/
|
||||
public static String[] splitURL(String scriptUrl)
|
||||
{
|
||||
String[] urlParts = new String[4];
|
||||
String path;
|
||||
String queryString;
|
||||
|
||||
int argsIndex = scriptUrl.indexOf("?");
|
||||
if (argsIndex != -1)
|
||||
{
|
||||
path = scriptUrl.substring(0, argsIndex);
|
||||
queryString = scriptUrl.substring(argsIndex + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
path = scriptUrl;
|
||||
queryString = null;
|
||||
}
|
||||
|
||||
String[] pathSegments = path.split("/");
|
||||
String pathInfo = "";
|
||||
for (int i = 3; i < pathSegments.length; i++)
|
||||
{
|
||||
pathInfo += "/" + pathSegments[i];
|
||||
}
|
||||
|
||||
urlParts[0] = "/" + pathSegments[1]; // context path
|
||||
urlParts[1] = "/" + pathSegments[2]; // servlet path
|
||||
urlParts[2] = pathInfo; // path info
|
||||
urlParts[3] = queryString; // query string
|
||||
|
||||
return urlParts;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param scriptUrl
|
||||
* @param serviceMatch
|
||||
*/
|
||||
public WebScriptURLRequest(String scriptUrl, WebScriptMatch serviceMatch)
|
||||
{
|
||||
this(splitURL(scriptUrl), serviceMatch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param scriptUrlParts
|
||||
* @param serviceMatch
|
||||
*/
|
||||
public WebScriptURLRequest(String[] scriptUrlParts, WebScriptMatch serviceMatch)
|
||||
{
|
||||
this.contextPath = scriptUrlParts[0];
|
||||
this.servletPath = scriptUrlParts[1];
|
||||
this.pathInfo = scriptUrlParts[2];
|
||||
this.queryString = scriptUrlParts[3];
|
||||
this.queryArgs = new HashMap<String, String>();
|
||||
if (this.queryString != null)
|
||||
{
|
||||
String[] args = this.queryString.split("&");
|
||||
for (String arg : args)
|
||||
{
|
||||
String[] parts = arg.split("=");
|
||||
// TODO: Handle multi-value parameters
|
||||
this.queryArgs.put(parts[0], parts.length == 2 ? parts[1] : "");
|
||||
}
|
||||
}
|
||||
this.serviceMatch = serviceMatch;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getServiceMatch()
|
||||
*/
|
||||
public WebScriptMatch getServiceMatch()
|
||||
{
|
||||
return serviceMatch;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getContextPath()
|
||||
*/
|
||||
public String getContextPath()
|
||||
{
|
||||
return contextPath;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getServiceContextPath()
|
||||
*/
|
||||
public String getServiceContextPath()
|
||||
{
|
||||
return getContextPath() + servletPath;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getServicePath()
|
||||
*/
|
||||
public String getServicePath()
|
||||
{
|
||||
return getServiceContextPath() + pathInfo;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getURL()
|
||||
*/
|
||||
public String getURL()
|
||||
{
|
||||
return getServicePath() + (queryString != null ? "?" + queryString : "");
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getPathInfo()
|
||||
*/
|
||||
public String getPathInfo()
|
||||
{
|
||||
return pathInfo;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getQueryString()
|
||||
*/
|
||||
public String getQueryString()
|
||||
{
|
||||
return queryString;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getParameterNames()
|
||||
*/
|
||||
public String[] getParameterNames()
|
||||
{
|
||||
Set<String> keys = queryArgs.keySet();
|
||||
String[] names = new String[keys.size()];
|
||||
keys.toArray(names);
|
||||
return names;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getParameter(java.lang.String)
|
||||
*/
|
||||
public String getParameter(String name)
|
||||
{
|
||||
return queryArgs.get(name);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -44,8 +44,8 @@ import org.alfresco.web.scripts.WebScriptRegistry;
|
||||
import org.alfresco.web.scripts.WebScriptRequest;
|
||||
import org.alfresco.web.scripts.WebScriptResponse;
|
||||
import org.alfresco.web.scripts.WebScriptRuntime;
|
||||
import org.alfresco.web.scripts.WebScriptURLRequest;
|
||||
import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
|
||||
import org.alfresco.web.scripts.portlet.WebScriptPortletRequest;
|
||||
import org.alfresco.web.ui.common.component.SelfRenderingComponent;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -228,7 +228,7 @@ public class UIWebScript extends SelfRenderingComponent
|
||||
super(registry, txnService);
|
||||
this.fc = fc;
|
||||
this.scriptUrl = scriptUrl;
|
||||
this.script = WebScriptPortletRequest.getScriptUrlParts(scriptUrl)[2];
|
||||
this.script = WebScriptURLRequest.splitURL(scriptUrl)[2];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -248,7 +248,7 @@ public class UIWebScript extends SelfRenderingComponent
|
||||
@Override
|
||||
protected WebScriptRequest createRequest(WebScriptMatch match)
|
||||
{
|
||||
return new WebScriptJSFRequest(fc, match, this.scriptUrl);
|
||||
return new WebScriptJSFRequest(this.scriptUrl, match);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -24,27 +24,16 @@
|
||||
*/
|
||||
package org.alfresco.web.scripts.jsf;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.web.scripts.WebScriptMatch;
|
||||
import org.alfresco.web.scripts.WebScriptRequest;
|
||||
import org.alfresco.web.scripts.portlet.WebScriptPortletRequest;
|
||||
import org.alfresco.web.scripts.WebScriptURLRequest;
|
||||
|
||||
/**
|
||||
* Implementation of a WebScript Request for the JSF environment.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class WebScriptJSFRequest implements WebScriptRequest
|
||||
public class WebScriptJSFRequest extends WebScriptURLRequest
|
||||
{
|
||||
private WebScriptMatch match;
|
||||
private FacesContext fc;
|
||||
private String[] scriptUrlParts;
|
||||
private Map<String, String> args = new HashMap<String, String>(4, 1.0f);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -52,47 +41,19 @@ public class WebScriptJSFRequest implements WebScriptRequest
|
||||
* @param fc FacesContext
|
||||
* @param match WebScriptMatch that matched this webscript
|
||||
* @param scriptUrl The script URL this request is for
|
||||
*/
|
||||
WebScriptJSFRequest(FacesContext fc, WebScriptMatch match, String scriptUrl)
|
||||
*/
|
||||
public WebScriptJSFRequest(String scriptUrl, WebScriptMatch match)
|
||||
{
|
||||
this.fc = fc;
|
||||
this.match = match;
|
||||
this.scriptUrlParts = WebScriptPortletRequest.getScriptUrlParts(scriptUrl);
|
||||
if (this.scriptUrlParts[3] != null)
|
||||
{
|
||||
String[] parts = this.scriptUrlParts[3].split("&");
|
||||
for (String argument : parts)
|
||||
{
|
||||
int sepIndex = argument.indexOf('=');
|
||||
if (sepIndex != -1)
|
||||
{
|
||||
String value = "";
|
||||
if (argument.length() > sepIndex + 1)
|
||||
{
|
||||
value = argument.substring(sepIndex + 1);
|
||||
}
|
||||
this.args.put(argument.substring(0, sepIndex), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
this(splitURL(scriptUrl), match);
|
||||
}
|
||||
|
||||
public WebScriptJSFRequest(String[] scriptUrlParts, WebScriptMatch match)
|
||||
{
|
||||
super(scriptUrlParts, match);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the matching API Service for this request
|
||||
*
|
||||
* @return the service match
|
||||
*/
|
||||
public WebScriptMatch getServiceMatch()
|
||||
{
|
||||
return this.match;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get server portion of the request
|
||||
*
|
||||
* e.g. scheme://host:port
|
||||
*
|
||||
* @return server path
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getServerPath()
|
||||
*/
|
||||
public String getServerPath()
|
||||
{
|
||||
@@ -100,126 +61,13 @@ public class WebScriptJSFRequest implements WebScriptRequest
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getContextPath()
|
||||
*/
|
||||
public String getContextPath()
|
||||
{
|
||||
return fc.getExternalContext().getRequestContextPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Alfresco Web Script Context Path
|
||||
*
|
||||
* @return service url e.g. /alfresco/service
|
||||
*/
|
||||
public String getServiceContextPath()
|
||||
{
|
||||
return fc.getExternalContext().getRequestContextPath() + scriptUrlParts[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Alfresco Service Path
|
||||
*
|
||||
* @return service url e.g. /alfresco/service/search/keyword
|
||||
*/
|
||||
public String getServicePath()
|
||||
{
|
||||
return getServiceContextPath() + scriptUrlParts[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full request URL
|
||||
*
|
||||
* @return request url e.g. /alfresco/service/search/keyword?q=term
|
||||
*/
|
||||
public String getURL()
|
||||
{
|
||||
return getServicePath() + (scriptUrlParts[3] != null ? "?" + scriptUrlParts[3] : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getQueryString()
|
||||
*/
|
||||
public String getQueryString()
|
||||
{
|
||||
return scriptUrlParts[3];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getParameterNames()
|
||||
*/
|
||||
public String[] getParameterNames()
|
||||
{
|
||||
Set<String> keys = this.args.keySet();
|
||||
String[] names = new String[keys.size()];
|
||||
keys.toArray(names);
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getParameter(java.lang.String)
|
||||
*/
|
||||
public String getParameter(String name)
|
||||
{
|
||||
return this.args.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path extension beyond the path registered for this service
|
||||
*
|
||||
* e.g.
|
||||
* a) service registered path = /search/engine
|
||||
* b) request path = /search/engine/external
|
||||
*
|
||||
* => /external
|
||||
*
|
||||
* @return extension path
|
||||
*/
|
||||
public String getExtensionPath()
|
||||
{
|
||||
String servicePath = this.scriptUrlParts[2];
|
||||
if (servicePath.indexOf('/') != -1)
|
||||
{
|
||||
return servicePath.substring(servicePath.indexOf('/'));
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if Guest User?
|
||||
*
|
||||
* @return true => guest user
|
||||
*/
|
||||
public boolean isGuest()
|
||||
{
|
||||
return Boolean.valueOf(getParameter("guest"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Requested Format
|
||||
*
|
||||
* @return content type requested
|
||||
*/
|
||||
public String getFormat()
|
||||
{
|
||||
String format = getParameter("format");
|
||||
return (format == null || format.length() == 0) ? "" : format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get User Agent
|
||||
*
|
||||
* TODO: Expand on known agents
|
||||
*
|
||||
* @return MSIE / Firefox
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getAgent()
|
||||
*/
|
||||
public String getAgent()
|
||||
{
|
||||
// NOTE: unknown in the JSF environment
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -47,6 +47,7 @@ import org.alfresco.web.scripts.WebScriptMatch;
|
||||
import org.alfresco.web.scripts.WebScriptRequest;
|
||||
import org.alfresco.web.scripts.WebScriptResponse;
|
||||
import org.alfresco.web.scripts.WebScriptRuntime;
|
||||
import org.alfresco.web.scripts.WebScriptURLRequest;
|
||||
import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -211,7 +212,7 @@ public class WebScriptPortlet implements Portlet
|
||||
super(registry, transactionService);
|
||||
this.req = req;
|
||||
this.res = res;
|
||||
this.requestUrlParts = WebScriptPortletRequest.getScriptUrlParts(requestUrl);
|
||||
this.requestUrlParts = WebScriptURLRequest.splitURL(requestUrl);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@@ -24,14 +24,10 @@
|
||||
*/
|
||||
package org.alfresco.web.scripts.portlet;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.portlet.PortletRequest;
|
||||
|
||||
import org.alfresco.web.scripts.WebScriptMatch;
|
||||
import org.alfresco.web.scripts.WebScriptRequest;
|
||||
import org.alfresco.web.scripts.WebScriptURLRequest;
|
||||
|
||||
|
||||
/**
|
||||
@@ -39,61 +35,11 @@ import org.alfresco.web.scripts.WebScriptRequest;
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class WebScriptPortletRequest implements WebScriptRequest
|
||||
public class WebScriptPortletRequest extends WebScriptURLRequest
|
||||
{
|
||||
/** Portlet Request */
|
||||
private PortletRequest req;
|
||||
|
||||
/** Script Url components */
|
||||
private String contextPath;
|
||||
private String servletPath;
|
||||
private String pathInfo;
|
||||
private String queryString;
|
||||
private Map<String, String> queryArgs;
|
||||
|
||||
/** Service bound to this request */
|
||||
private WebScriptMatch serviceMatch;
|
||||
|
||||
|
||||
/**
|
||||
* Splits a portlet scriptUrl into its component parts
|
||||
*
|
||||
* @param scriptUrl url e.g. /alfresco/service/mytasks?f=1
|
||||
* @return url parts [0] = context (e.g. alfresco), [1] = servlet (e.g. service), [2] = script (e.g. mytasks), [3] = args (e.g. f=1)
|
||||
*/
|
||||
public static String[] getScriptUrlParts(String scriptUrl)
|
||||
{
|
||||
String[] urlParts = new String[4];
|
||||
String path;
|
||||
String queryString;
|
||||
|
||||
int argsIndex = scriptUrl.indexOf("?");
|
||||
if (argsIndex != -1)
|
||||
{
|
||||
path = scriptUrl.substring(0, argsIndex);
|
||||
queryString = scriptUrl.substring(argsIndex + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
path = scriptUrl;
|
||||
queryString = null;
|
||||
}
|
||||
|
||||
String[] pathSegments = path.split("/");
|
||||
String pathInfo = "";
|
||||
for (int i = 3; i < pathSegments.length; i++)
|
||||
{
|
||||
pathInfo += "/" + pathSegments[i];
|
||||
}
|
||||
|
||||
urlParts[0] = "/" + pathSegments[1]; // context path
|
||||
urlParts[1] = "/" + pathSegments[2]; // servlet path
|
||||
urlParts[2] = pathInfo; // path info
|
||||
urlParts[3] = queryString; // query string
|
||||
|
||||
return urlParts;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct
|
||||
@@ -102,37 +48,22 @@ public class WebScriptPortletRequest implements WebScriptRequest
|
||||
* @param scriptUrl
|
||||
* @param serviceMatch
|
||||
*/
|
||||
WebScriptPortletRequest(PortletRequest req, String scriptUrl, WebScriptMatch serviceMatch)
|
||||
public WebScriptPortletRequest(PortletRequest req, String scriptUrl, WebScriptMatch serviceMatch)
|
||||
{
|
||||
this(req, getScriptUrlParts(scriptUrl), serviceMatch);
|
||||
this(req, splitURL(scriptUrl), serviceMatch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param req
|
||||
* 'param scriptUrlParts
|
||||
* @param scriptUrlParts
|
||||
* @param serviceMatch
|
||||
*/
|
||||
WebScriptPortletRequest(PortletRequest req, String[] scriptUrlParts, WebScriptMatch serviceMatch)
|
||||
public WebScriptPortletRequest(PortletRequest req, String[] scriptUrlParts, WebScriptMatch serviceMatch)
|
||||
{
|
||||
super(scriptUrlParts, serviceMatch);
|
||||
this.req = req;
|
||||
this.contextPath = scriptUrlParts[0];
|
||||
this.servletPath = scriptUrlParts[1];
|
||||
this.pathInfo = scriptUrlParts[2];
|
||||
this.queryString = scriptUrlParts[3];
|
||||
this.queryArgs = new HashMap<String, String>();
|
||||
if (this.queryString != null)
|
||||
{
|
||||
String[] args = this.queryString.split("&");
|
||||
for (String arg : args)
|
||||
{
|
||||
String[] parts = arg.split("=");
|
||||
// TODO: Handle multi-value parameters
|
||||
this.queryArgs.put(parts[0], parts.length == 2 ? parts[1] : "");
|
||||
}
|
||||
}
|
||||
this.serviceMatch = serviceMatch;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,14 +76,6 @@ public class WebScriptPortletRequest implements WebScriptRequest
|
||||
return req;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getServiceMatch()
|
||||
*/
|
||||
public WebScriptMatch getServiceMatch()
|
||||
{
|
||||
return serviceMatch;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getServerPath()
|
||||
*/
|
||||
@@ -161,98 +84,6 @@ public class WebScriptPortletRequest implements WebScriptRequest
|
||||
return req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getContextPath()
|
||||
*/
|
||||
public String getContextPath()
|
||||
{
|
||||
return contextPath;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getServiceContextPath()
|
||||
*/
|
||||
public String getServiceContextPath()
|
||||
{
|
||||
return getContextPath() + servletPath;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getServicePath()
|
||||
*/
|
||||
public String getServicePath()
|
||||
{
|
||||
return getServiceContextPath() + pathInfo;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getURL()
|
||||
*/
|
||||
public String getURL()
|
||||
{
|
||||
return getServicePath() + (queryString != null ? "?" + queryString : "");
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getQueryString()
|
||||
*/
|
||||
public String getQueryString()
|
||||
{
|
||||
return queryString;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getParameterNames()
|
||||
*/
|
||||
public String[] getParameterNames()
|
||||
{
|
||||
Set<String> keys = queryArgs.keySet();
|
||||
String[] names = new String[keys.size()];
|
||||
keys.toArray(names);
|
||||
return names;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getParameter(java.lang.String)
|
||||
*/
|
||||
public String getParameter(String name)
|
||||
{
|
||||
return queryArgs.get(name);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getExtensionPath()
|
||||
*/
|
||||
public String getExtensionPath()
|
||||
{
|
||||
String servicePath = serviceMatch.getPath();
|
||||
String extensionPath = pathInfo;
|
||||
int extIdx = extensionPath.indexOf(servicePath);
|
||||
if (extIdx != -1)
|
||||
{
|
||||
int extLength = (servicePath.endsWith("/") ? servicePath.length() : servicePath.length() + 1);
|
||||
extensionPath = extensionPath.substring(extIdx + extLength);
|
||||
}
|
||||
return extensionPath;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#isGuest()
|
||||
*/
|
||||
public boolean isGuest()
|
||||
{
|
||||
return Boolean.valueOf(queryArgs.get("guest"));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getFormat()
|
||||
*/
|
||||
public String getFormat()
|
||||
{
|
||||
String format = queryArgs.get("format");
|
||||
return (format == null || format.length() == 0) ? "" : format;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getAgent()
|
||||
*/
|
||||
|
Reference in New Issue
Block a user