Apply Pre-Commit code formatting

This commit is contained in:
alfresco-build
2025-03-17 14:00:58 +00:00
parent 5255760f6e
commit bc8424482b
7038 changed files with 1006771 additions and 982869 deletions

View File

@@ -25,15 +25,6 @@
*/
package org.alfresco.heartbeat;
import org.alfresco.heartbeat.datasender.HBData;
import org.alfresco.heartbeat.jobs.HeartBeatJobScheduler;
import org.alfresco.repo.descriptor.DescriptorDAO;
import org.alfresco.repo.thumbnail.ThumbnailDefinition;
import org.alfresco.util.PropertyCheck;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
@@ -42,20 +33,28 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.alfresco.heartbeat.datasender.HBData;
import org.alfresco.heartbeat.jobs.HeartBeatJobScheduler;
import org.alfresco.repo.descriptor.DescriptorDAO;
import org.alfresco.repo.thumbnail.ThumbnailDefinition;
import org.alfresco.util.PropertyCheck;
/**
* This class collects rendition request counts for HeartBeat. A rendition (such as "doclib") is always to the same
* target mimetype, but there may be different source mimetypes. As a result that may be multiple sets of data with
* the same rendition. It is also likely there will be multiple renditions reported in the same batch of data.
* This class collects rendition request counts for HeartBeat. A rendition (such as "doclib") is always to the same target mimetype, but there may be different source mimetypes. As a result that may be multiple sets of data with the same rendition. It is also likely there will be multiple renditions reported in the same batch of data.
* <ul>
* <li>Collector ID: <b>acs.repository.renditions</b></li>
* <li>Data:
* <ul>
* <li><b>rendition:</b> String - The name of the rendition.</li>
* <li><b>count:</b> Integer - The number of times a rendition and sourceMimetype combination has been requested.</li>
* <li><b>sourceMimetype:</b> String - The source mimetype for the rendition.</li>
* <li><b>targetMimetype:</b> String - The target mimetype for the rendition.</li>
* </ul>
* </li>
* <li>Collector ID: <b>acs.repository.renditions</b></li>
* <li>Data:
* <ul>
* <li><b>rendition:</b> String - The name of the rendition.</li>
* <li><b>count:</b> Integer - The number of times a rendition and sourceMimetype combination has been requested.</li>
* <li><b>sourceMimetype:</b> String - The source mimetype for the rendition.</li>
* <li><b>targetMimetype:</b> String - The target mimetype for the rendition.</li>
* </ul>
* </li>
* </ul>
*
* @author adavis
@@ -70,7 +69,7 @@ public class RenditionsDataCollector extends HBBaseDataCollector implements Init
private final Map<ThumbnailDefinition, Map<String, AtomicInteger>> renditionRequests = new ConcurrentHashMap<>();
public RenditionsDataCollector(String collectorId, String collectorVersion, String cronExpression,
HeartBeatJobScheduler hbJobScheduler)
HeartBeatJobScheduler hbJobScheduler)
{
super(collectorId, collectorVersion, cronExpression, hbJobScheduler);
}
@@ -91,7 +90,8 @@ public class RenditionsDataCollector extends HBBaseDataCollector implements Init
// Increment the count of renditions. Atomically creates missing parts of the Map structures.
renditionRequests.computeIfAbsent(rendition,
k -> new ConcurrentHashMap<>()).computeIfAbsent(sourceMimetype,
k -> new AtomicInteger()).incrementAndGet();
k -> new AtomicInteger())
.incrementAndGet();
}
@Override
@@ -109,7 +109,7 @@ public class RenditionsDataCollector extends HBBaseDataCollector implements Init
{
String renditionName = rendition.getName();
String targetMimetype = rendition.getMimetype();
for (Map.Entry<String, AtomicInteger> entry: renditionRequests.remove(rendition).entrySet())
for (Map.Entry<String, AtomicInteger> entry : renditionRequests.remove(rendition).entrySet())
{
String sourceMimetype = entry.getKey();
AtomicInteger count = entry.getValue();
@@ -129,7 +129,7 @@ public class RenditionsDataCollector extends HBBaseDataCollector implements Init
if (logger.isDebugEnabled())
{
logger.debug(renditionName+" "+count+" "+sourceMimetype+" "+targetMimetype);
logger.debug(renditionName + " " + count + " " + sourceMimetype + " " + targetMimetype);
}
}
}

View File

@@ -1,196 +1,196 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import jakarta.servlet.http.HttpServletRequest;
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
import org.alfresco.repo.tenant.TenantUtil;
/**
* Generates an OpenCMIS base url based on the request, repository id and binding.
*
* @author steveglover
*
*/
public abstract class AbstractBaseUrlGenerator implements BaseUrlGenerator
{
private boolean overrideContext;
private String contextOverride;
private boolean overrideServletPath;
private String servletPathOverride;
private PathGenerator pathGenerator;
public void setPathGenerator(PathGenerator pathGenerator)
{
this.pathGenerator = pathGenerator;
}
public void setOverrideContext(boolean overrideContext)
{
this.overrideContext = overrideContext;
}
private String fixup(String urlSegment)
{
StringBuilder sb = new StringBuilder();
int beginIndex = 0;
int endIndex = urlSegment.length();
if(urlSegment != null)
{
if(!urlSegment.equals("") && !urlSegment.startsWith("/"))
{
sb.append("/");
}
if(urlSegment.endsWith("/"))
{
endIndex -= 1;
}
}
sb.append(urlSegment.substring(beginIndex, endIndex));
return sb.toString();
}
public void setContextOverride(String contextOverride)
{
this.contextOverride = fixup(contextOverride);
}
public void setOverrideServletPath(boolean overrideServletPath)
{
this.overrideServletPath = overrideServletPath;
}
public void setServletPathOverride(String servletPathOverride)
{
this.servletPathOverride = fixup(servletPathOverride);
}
protected abstract String getServerPath(HttpServletRequest request);
public String getContextPath(HttpServletRequest httpReq)
{
if(overrideContext)
{
return contextOverride;
}
else
{
return httpReq.getContextPath();
}
}
public String getServletPath(HttpServletRequest req)
{
if(overrideServletPath)
{
return servletPathOverride;
}
else
{
return req.getServletPath();
}
}
@Override
public String getRequestURI(HttpServletRequest req, String repositoryId, String operation, String id)
{
StringBuilder url = new StringBuilder();
String contextPath = getContextPath(req);
if(contextPath != null && !contextPath.equals(""))
{
url.append(contextPath);
}
String servletPath = getServletPath(req);
if(servletPath != null && !servletPath.equals(""))
{
url.append(servletPath);
url.append("/");
}
if(url.length() == 0 || url.charAt(0) != '/')
{
url.append("/");
}
if(repositoryId != null)
{
url.append(repositoryId == null ? TenantUtil.DEFAULT_TENANT : repositoryId);
url.append("/");
}
if(operation != null)
{
url.append(operation);
url.append("/");
}
if(id != null)
{
url.append(id);
}
int length = url.length();
if(length > 0 && url.charAt(length - 1) == '/')
{
url.deleteCharAt(length - 1);
}
return url.toString();
}
@Override
public String getBaseUrl(HttpServletRequest req, String repositoryId, Binding binding)
{
StringBuilder url = new StringBuilder();
String serverPath = getServerPath(req);
url.append(serverPath);
String contextPath = getContextPath(req);
if(contextPath != null && !contextPath.equals(""))
{
url.append(contextPath);
}
String servletPath = getServletPath(req);
if(servletPath != null && !servletPath.equals(""))
{
url.append(servletPath);
url.append("/");
}
if(url.length() > 0 && url.charAt(url.length() - 1) != '/')
{
url.append("/");
}
pathGenerator.generatePath(req, url, repositoryId, binding);
return url.toString();
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import jakarta.servlet.http.HttpServletRequest;
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
import org.alfresco.repo.tenant.TenantUtil;
/**
* Generates an OpenCMIS base url based on the request, repository id and binding.
*
* @author steveglover
*
*/
public abstract class AbstractBaseUrlGenerator implements BaseUrlGenerator
{
private boolean overrideContext;
private String contextOverride;
private boolean overrideServletPath;
private String servletPathOverride;
private PathGenerator pathGenerator;
public void setPathGenerator(PathGenerator pathGenerator)
{
this.pathGenerator = pathGenerator;
}
public void setOverrideContext(boolean overrideContext)
{
this.overrideContext = overrideContext;
}
private String fixup(String urlSegment)
{
StringBuilder sb = new StringBuilder();
int beginIndex = 0;
int endIndex = urlSegment.length();
if (urlSegment != null)
{
if (!urlSegment.equals("") && !urlSegment.startsWith("/"))
{
sb.append("/");
}
if (urlSegment.endsWith("/"))
{
endIndex -= 1;
}
}
sb.append(urlSegment.substring(beginIndex, endIndex));
return sb.toString();
}
public void setContextOverride(String contextOverride)
{
this.contextOverride = fixup(contextOverride);
}
public void setOverrideServletPath(boolean overrideServletPath)
{
this.overrideServletPath = overrideServletPath;
}
public void setServletPathOverride(String servletPathOverride)
{
this.servletPathOverride = fixup(servletPathOverride);
}
protected abstract String getServerPath(HttpServletRequest request);
public String getContextPath(HttpServletRequest httpReq)
{
if (overrideContext)
{
return contextOverride;
}
else
{
return httpReq.getContextPath();
}
}
public String getServletPath(HttpServletRequest req)
{
if (overrideServletPath)
{
return servletPathOverride;
}
else
{
return req.getServletPath();
}
}
@Override
public String getRequestURI(HttpServletRequest req, String repositoryId, String operation, String id)
{
StringBuilder url = new StringBuilder();
String contextPath = getContextPath(req);
if (contextPath != null && !contextPath.equals(""))
{
url.append(contextPath);
}
String servletPath = getServletPath(req);
if (servletPath != null && !servletPath.equals(""))
{
url.append(servletPath);
url.append("/");
}
if (url.length() == 0 || url.charAt(0) != '/')
{
url.append("/");
}
if (repositoryId != null)
{
url.append(repositoryId == null ? TenantUtil.DEFAULT_TENANT : repositoryId);
url.append("/");
}
if (operation != null)
{
url.append(operation);
url.append("/");
}
if (id != null)
{
url.append(id);
}
int length = url.length();
if (length > 0 && url.charAt(length - 1) == '/')
{
url.deleteCharAt(length - 1);
}
return url.toString();
}
@Override
public String getBaseUrl(HttpServletRequest req, String repositoryId, Binding binding)
{
StringBuilder url = new StringBuilder();
String serverPath = getServerPath(req);
url.append(serverPath);
String contextPath = getContextPath(req);
if (contextPath != null && !contextPath.equals(""))
{
url.append(contextPath);
}
String servletPath = getServletPath(req);
if (servletPath != null && !servletPath.equals(""))
{
url.append(servletPath);
url.append("/");
}
if (url.length() > 0 && url.charAt(url.length() - 1) != '/')
{
url.append("/");
}
pathGenerator.generatePath(req, url, repositoryId, binding);
return url.toString();
}
}

View File

@@ -1,52 +1,53 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import jakarta.servlet.http.HttpServlet;
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
import org.apache.chemistry.opencmis.server.impl.atompub.CmisAtomPubServlet;
/**
* Dispatches OpenCMIS requests to the OpenCMIS AtomPub servlet.
*
* @author steveglover
*
*/
public class AtomPubCMISDispatcher extends CMISServletDispatcher
{
@Override
protected Binding getBinding()
{
return Binding.atom;
}
protected HttpServlet getServlet()
{
HttpServlet servlet = new CmisAtomPubServlet();
return servlet;
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import jakarta.servlet.http.HttpServlet;
import org.apache.chemistry.opencmis.server.impl.atompub.CmisAtomPubServlet;
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
/**
* Dispatches OpenCMIS requests to the OpenCMIS AtomPub servlet.
*
* @author steveglover
*
*/
public class AtomPubCMISDispatcher extends CMISServletDispatcher
{
@Override
protected Binding getBinding()
{
return Binding.atom;
}
protected HttpServlet getServlet()
{
HttpServlet servlet = new CmisAtomPubServlet();
return servlet;
}
}

View File

@@ -37,8 +37,11 @@ import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
*/
public interface BaseUrlGenerator
{
String getContextPath(HttpServletRequest httpReq);
String getServletPath(HttpServletRequest req);
String getBaseUrl(HttpServletRequest req, String repositoryId, Binding binding);
String getRequestURI(HttpServletRequest req, String repositoryId, String operation, String id);
String getContextPath(HttpServletRequest httpReq);
String getServletPath(HttpServletRequest req);
String getBaseUrl(HttpServletRequest req, String repositoryId, Binding binding);
String getRequestURI(HttpServletRequest req, String repositoryId, String operation, String id);
}

View File

@@ -1,52 +1,53 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import jakarta.servlet.http.HttpServlet;
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
import org.apache.chemistry.opencmis.server.impl.browser.CmisBrowserBindingServlet;
/**
* Dispatches OpenCMIS requests to the OpenCMIS Browser Binding servlet.
*
* @author steveglover
*
*/
public class BrowserCMISDispatcher extends CMISServletDispatcher
{
@Override
protected Binding getBinding()
{
return Binding.browser;
}
protected HttpServlet getServlet()
{
HttpServlet servlet = new CmisBrowserBindingServlet();
return servlet;
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import jakarta.servlet.http.HttpServlet;
import org.apache.chemistry.opencmis.server.impl.browser.CmisBrowserBindingServlet;
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
/**
* Dispatches OpenCMIS requests to the OpenCMIS Browser Binding servlet.
*
* @author steveglover
*
*/
public class BrowserCMISDispatcher extends CMISServletDispatcher
{
@Override
protected Binding getBinding()
{
return Binding.browser;
}
protected HttpServlet getServlet()
{
HttpServlet servlet = new CmisBrowserBindingServlet();
return servlet;
}
}

View File

@@ -23,20 +23,20 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import java.io.IOException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
/**
* Dispatches OpenCMIS requests to the appropriate handler.
*
* @author steveglover
*
*/
public interface CMISDispatcher
{
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException;
}
package org.alfresco.opencmis;
import java.io.IOException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
/**
* Dispatches OpenCMIS requests to the appropriate handler.
*
* @author steveglover
*
*/
public interface CMISDispatcher
{
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException;
}

View File

@@ -23,98 +23,99 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import org.apache.chemistry.opencmis.commons.enums.BindingType;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* A registry of OpenCMIS bindings to dispatchers.
*
* @author steveglover
*
*/
public interface CMISDispatcherRegistry
{
/*
* Supported CMIS bindings
*/
public static enum Binding
{
atom, browser;
public BindingType getOpenCmisBinding()
{
BindingType bindingType = null;
if(this == atom)
{
bindingType = BindingType.ATOMPUB;
}
else if(this == browser)
{
bindingType = BindingType.BROWSER;
}
return bindingType;
}
};
public static class Endpoint
{
private Binding binding;
private String version;
public Endpoint(Binding binding, String version)
{
super();
this.binding = binding;
this.version = version;
}
public Binding getBinding()
{
return binding;
}
public String getVersion()
{
return version;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result
+ ((binding == null) ? 0 : binding.hashCode());
result = prime * result
+ ((version == null) ? 0 : version.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Endpoint other = (Endpoint) obj;
if (binding != other.binding)
return false;
if (version == null) {
if (other.version != null)
return false;
} else if (!version.equals(other.version))
return false;
return true;
}
}
public void registerDispatcher(Endpoint endpoint, CMISDispatcher dispatcher);
public CMISDispatcher getDispatcher(WebScriptRequest req);
}
package org.alfresco.opencmis;
import org.apache.chemistry.opencmis.commons.enums.BindingType;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* A registry of OpenCMIS bindings to dispatchers.
*
* @author steveglover
*
*/
public interface CMISDispatcherRegistry
{
/* Supported CMIS bindings */
public static enum Binding
{
atom, browser;
public BindingType getOpenCmisBinding()
{
BindingType bindingType = null;
if (this == atom)
{
bindingType = BindingType.ATOMPUB;
}
else if (this == browser)
{
bindingType = BindingType.BROWSER;
}
return bindingType;
}
};
public static class Endpoint
{
private Binding binding;
private String version;
public Endpoint(Binding binding, String version)
{
super();
this.binding = binding;
this.version = version;
}
public Binding getBinding()
{
return binding;
}
public String getVersion()
{
return version;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result
+ ((binding == null) ? 0 : binding.hashCode());
result = prime * result
+ ((version == null) ? 0 : version.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Endpoint other = (Endpoint) obj;
if (binding != other.binding)
return false;
if (version == null)
{
if (other.version != null)
return false;
}
else if (!version.equals(other.version))
return false;
return true;
}
}
public void registerDispatcher(Endpoint endpoint, CMISDispatcher dispatcher);
public CMISDispatcher getDispatcher(WebScriptRequest req);
}

View File

@@ -23,62 +23,62 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import java.util.HashMap;
import java.util.Map;
import org.springframework.extensions.webscripts.Match;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* A registry of OpenCMIS bindings to dispatchers.
*
* @author steveglover
*
*/
public class CMISDispatcherRegistryImpl implements CMISDispatcherRegistry
{
private Map<Endpoint, CMISDispatcher> registry = new HashMap<Endpoint, CMISDispatcher>();
@Override
public void registerDispatcher(Endpoint endpoint, CMISDispatcher dispatcher)
{
registry.put(endpoint, dispatcher);
}
@Override
public CMISDispatcher getDispatcher(WebScriptRequest req)
{
CMISDispatcher dispatcher = null;
Match match = req.getServiceMatch();
Map<String, String> templateVars = match.getTemplateVars();
String bindingStr = templateVars.get("binding");
String apiVersion = templateVars.get("apiVersion");
if(bindingStr != null && apiVersion != null)
{
Binding binding = null;
try
{
binding = Binding.valueOf(bindingStr);
}
catch(IllegalArgumentException e)
{
// nothing to do, binding remains null
}
if(binding != null)
{
Endpoint endpoint = new Endpoint(binding, apiVersion);
dispatcher = registry.get(endpoint);
}
else
{
// TODO
}
}
return dispatcher;
}
}
package org.alfresco.opencmis;
import java.util.HashMap;
import java.util.Map;
import org.springframework.extensions.webscripts.Match;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* A registry of OpenCMIS bindings to dispatchers.
*
* @author steveglover
*
*/
public class CMISDispatcherRegistryImpl implements CMISDispatcherRegistry
{
private Map<Endpoint, CMISDispatcher> registry = new HashMap<Endpoint, CMISDispatcher>();
@Override
public void registerDispatcher(Endpoint endpoint, CMISDispatcher dispatcher)
{
registry.put(endpoint, dispatcher);
}
@Override
public CMISDispatcher getDispatcher(WebScriptRequest req)
{
CMISDispatcher dispatcher = null;
Match match = req.getServiceMatch();
Map<String, String> templateVars = match.getTemplateVars();
String bindingStr = templateVars.get("binding");
String apiVersion = templateVars.get("apiVersion");
if (bindingStr != null && apiVersion != null)
{
Binding binding = null;
try
{
binding = Binding.valueOf(bindingStr);
}
catch (IllegalArgumentException e)
{
// nothing to do, binding remains null
}
if (binding != null)
{
Endpoint endpoint = new Endpoint(binding, apiVersion);
dispatcher = registry.get(endpoint);
}
else
{
// TODO
}
}
return dispatcher;
}
}

View File

@@ -1,292 +1,288 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.tenant.TenantAdminService;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.web.scripts.TenantWebScriptServletRequest;
import org.alfresco.service.descriptor.Descriptor;
import org.apache.chemistry.opencmis.commons.impl.Constants;
import org.apache.chemistry.opencmis.server.shared.Dispatcher;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.extensions.webscripts.Match;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WrappingWebScriptRequest;
import org.springframework.extensions.webscripts.servlet.WebScriptServletRuntime;
/**
* Wraps an OpenCMIS HttpServletRequest, mapping urls and adding servlet attributes specific to the Alfresco implementation of OpenCMIS.
*/
@SuppressWarnings("rawtypes")
public class CMISHttpServletRequest extends HttpServletRequestWrapper
{
protected WebScriptRequest req;
protected String networkId;
protected String operation;
protected String id; // object id (or path for browser binding)
protected String serviceName;
protected BaseUrlGenerator baseUrlGenerator;
protected Binding binding;
protected Descriptor currentDescriptor;
public CMISHttpServletRequest(WebScriptRequest req, String serviceName, BaseUrlGenerator baseUrlGenerator, Binding binding, Descriptor currentDescriptor,
TenantAdminService tenantAdminService)
{
super(WebScriptServletRuntime.getHttpServletRequest(req));
this.req = req;
this.serviceName = serviceName;
this.baseUrlGenerator = baseUrlGenerator;
this.binding = binding;
String pathInfo = req.getPathInfo();
WebScriptRequest baseReq = getBaseRequest(req);
if(!pathInfo.startsWith("/cmis") && (baseReq instanceof TenantWebScriptServletRequest))
{
TenantWebScriptServletRequest servletReq = (TenantWebScriptServletRequest)baseReq;
String tenant = servletReq.getTenant();
if(tenant.equalsIgnoreCase(TenantUtil.DEFAULT_TENANT))
{
String user = AuthenticationUtil.getFullyAuthenticatedUser();
String domain = tenantAdminService.getUserDomain(user);
if(domain == null || domain.equals(TenantService.DEFAULT_DOMAIN))
{
this.networkId = tenant;
}
else
{
this.networkId = domain;
}
}
else
{
this.networkId = tenant;
}
}
Match match = req.getServiceMatch();
Map<String, String> templateVars = match.getTemplateVars();
this.operation = templateVars.get("operation");
this.id = templateVars.get("id");
addAttributes();
}
@Override
public HttpServletRequest getRequest()
{
return (HttpServletRequest) super.getRequest();
}
/*
* Recursively unwrap req if it is a WrappingWebScriptRequest
*/
private WebScriptRequest getBaseRequest(WebScriptRequest req)
{
WebScriptRequest ret = req;
while(ret instanceof WrappingWebScriptRequest)
{
WrappingWebScriptRequest wrapping = (WrappingWebScriptRequest)req;
ret = wrapping.getNext();
}
return ret;
}
protected void addAttributes()
{
if(networkId != null)
{
super.setAttribute(Constants.PARAM_REPOSITORY_ID, networkId);
}
super.setAttribute("serviceName", serviceName);
}
@Override
public Object getAttribute(String arg0)
{
if(arg0.equals(Dispatcher.BASE_URL_ATTRIBUTE))
{
return baseUrlGenerator.getBaseUrl(getRequest(), networkId, binding);
}
else
{
return super.getAttribute(arg0);
}
}
@SuppressWarnings("unchecked")
@Override
public Enumeration getAttributeNames()
{
Enumeration e = super.getAttributeNames();
List attrNames = new ArrayList();
while(e.hasMoreElements())
{
attrNames.add(e.nextElement());
}
attrNames.add(Dispatcher.BASE_URL_ATTRIBUTE);
final Iterator it = attrNames.iterator();
return new Enumeration()
{
public boolean hasMoreElements()
{
return it.hasNext();
}
public Object nextElement()
{
return it.next();
}
};
}
@Override
public String getParameter(String arg0)
{
if(arg0.equals(Constants.PARAM_REPOSITORY_ID))
{
return networkId;
}
return super.getParameter(arg0);
}
@SuppressWarnings("unchecked")
@Override
public Map getParameterMap()
{
Map map = super.getParameterMap();
Map ret = new HashedMap(map);
if(networkId != null)
{
ret.put(Constants.PARAM_REPOSITORY_ID, new String[] { networkId });
}
return ret;
}
@SuppressWarnings("unchecked")
@Override
public Enumeration getParameterNames()
{
final Enumeration e = super.getParameterNames();
List l = new ArrayList();
while(e.hasMoreElements())
{
l.add(e.nextElement());
}
if(networkId != null)
{
l.add(Constants.PARAM_REPOSITORY_ID);
}
final Iterator it = l.iterator();
Enumeration ret = new Enumeration()
{
@Override
public boolean hasMoreElements()
{
return it.hasNext();
}
@Override
public Object nextElement()
{
return it.next();
}
};
return ret;
}
@Override
public String getContextPath()
{
String contextPath = baseUrlGenerator.getContextPath(getRequest());
return contextPath;
}
@Override
public String getPathInfo()
{
StringBuilder sb = new StringBuilder("/");
sb.append(networkId == null ? TenantUtil.DEFAULT_TENANT : networkId);
if(operation != null)
{
sb.append("/");
sb.append(operation);
}
return sb.toString();
}
@Override
public String getQueryString()
{
StringBuilder queryString = new StringBuilder();
String reqQueryString = super.getQueryString();
if(networkId != null && networkId.length() > 0)
{
if (reqQueryString != null)
{
queryString.append(reqQueryString + "&");
}
queryString.append("repositoryId=" + networkId);
if(operation == null || operation.isEmpty())
{
queryString.append("&cmisselector=");
queryString.append(Constants.SELECTOR_REPOSITORY_INFO);
}
return queryString.toString();
}
return reqQueryString;
}
@Override
public String getRequestURI()
{
String requestURI = baseUrlGenerator.getRequestURI(getRequest(), networkId, operation, id);
return requestURI;
}
@Override
public String getServletPath()
{
String servletPath = baseUrlGenerator.getServletPath(getRequest());
return servletPath;
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import org.apache.chemistry.opencmis.commons.impl.Constants;
import org.apache.chemistry.opencmis.server.shared.Dispatcher;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.extensions.webscripts.Match;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WrappingWebScriptRequest;
import org.springframework.extensions.webscripts.servlet.WebScriptServletRuntime;
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.tenant.TenantAdminService;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.web.scripts.TenantWebScriptServletRequest;
import org.alfresco.service.descriptor.Descriptor;
/**
* Wraps an OpenCMIS HttpServletRequest, mapping urls and adding servlet attributes specific to the Alfresco implementation of OpenCMIS.
*/
@SuppressWarnings("rawtypes")
public class CMISHttpServletRequest extends HttpServletRequestWrapper
{
protected WebScriptRequest req;
protected String networkId;
protected String operation;
protected String id; // object id (or path for browser binding)
protected String serviceName;
protected BaseUrlGenerator baseUrlGenerator;
protected Binding binding;
protected Descriptor currentDescriptor;
public CMISHttpServletRequest(WebScriptRequest req, String serviceName, BaseUrlGenerator baseUrlGenerator, Binding binding, Descriptor currentDescriptor,
TenantAdminService tenantAdminService)
{
super(WebScriptServletRuntime.getHttpServletRequest(req));
this.req = req;
this.serviceName = serviceName;
this.baseUrlGenerator = baseUrlGenerator;
this.binding = binding;
String pathInfo = req.getPathInfo();
WebScriptRequest baseReq = getBaseRequest(req);
if (!pathInfo.startsWith("/cmis") && (baseReq instanceof TenantWebScriptServletRequest))
{
TenantWebScriptServletRequest servletReq = (TenantWebScriptServletRequest) baseReq;
String tenant = servletReq.getTenant();
if (tenant.equalsIgnoreCase(TenantUtil.DEFAULT_TENANT))
{
String user = AuthenticationUtil.getFullyAuthenticatedUser();
String domain = tenantAdminService.getUserDomain(user);
if (domain == null || domain.equals(TenantService.DEFAULT_DOMAIN))
{
this.networkId = tenant;
}
else
{
this.networkId = domain;
}
}
else
{
this.networkId = tenant;
}
}
Match match = req.getServiceMatch();
Map<String, String> templateVars = match.getTemplateVars();
this.operation = templateVars.get("operation");
this.id = templateVars.get("id");
addAttributes();
}
@Override
public HttpServletRequest getRequest()
{
return (HttpServletRequest) super.getRequest();
}
/* Recursively unwrap req if it is a WrappingWebScriptRequest */
private WebScriptRequest getBaseRequest(WebScriptRequest req)
{
WebScriptRequest ret = req;
while (ret instanceof WrappingWebScriptRequest)
{
WrappingWebScriptRequest wrapping = (WrappingWebScriptRequest) req;
ret = wrapping.getNext();
}
return ret;
}
protected void addAttributes()
{
if (networkId != null)
{
super.setAttribute(Constants.PARAM_REPOSITORY_ID, networkId);
}
super.setAttribute("serviceName", serviceName);
}
@Override
public Object getAttribute(String arg0)
{
if (arg0.equals(Dispatcher.BASE_URL_ATTRIBUTE))
{
return baseUrlGenerator.getBaseUrl(getRequest(), networkId, binding);
}
else
{
return super.getAttribute(arg0);
}
}
@SuppressWarnings("unchecked")
@Override
public Enumeration getAttributeNames()
{
Enumeration e = super.getAttributeNames();
List attrNames = new ArrayList();
while (e.hasMoreElements())
{
attrNames.add(e.nextElement());
}
attrNames.add(Dispatcher.BASE_URL_ATTRIBUTE);
final Iterator it = attrNames.iterator();
return new Enumeration() {
public boolean hasMoreElements()
{
return it.hasNext();
}
public Object nextElement()
{
return it.next();
}
};
}
@Override
public String getParameter(String arg0)
{
if (arg0.equals(Constants.PARAM_REPOSITORY_ID))
{
return networkId;
}
return super.getParameter(arg0);
}
@SuppressWarnings("unchecked")
@Override
public Map getParameterMap()
{
Map map = super.getParameterMap();
Map ret = new HashedMap(map);
if (networkId != null)
{
ret.put(Constants.PARAM_REPOSITORY_ID, new String[]{networkId});
}
return ret;
}
@SuppressWarnings("unchecked")
@Override
public Enumeration getParameterNames()
{
final Enumeration e = super.getParameterNames();
List l = new ArrayList();
while (e.hasMoreElements())
{
l.add(e.nextElement());
}
if (networkId != null)
{
l.add(Constants.PARAM_REPOSITORY_ID);
}
final Iterator it = l.iterator();
Enumeration ret = new Enumeration() {
@Override
public boolean hasMoreElements()
{
return it.hasNext();
}
@Override
public Object nextElement()
{
return it.next();
}
};
return ret;
}
@Override
public String getContextPath()
{
String contextPath = baseUrlGenerator.getContextPath(getRequest());
return contextPath;
}
@Override
public String getPathInfo()
{
StringBuilder sb = new StringBuilder("/");
sb.append(networkId == null ? TenantUtil.DEFAULT_TENANT : networkId);
if (operation != null)
{
sb.append("/");
sb.append(operation);
}
return sb.toString();
}
@Override
public String getQueryString()
{
StringBuilder queryString = new StringBuilder();
String reqQueryString = super.getQueryString();
if (networkId != null && networkId.length() > 0)
{
if (reqQueryString != null)
{
queryString.append(reqQueryString + "&");
}
queryString.append("repositoryId=" + networkId);
if (operation == null || operation.isEmpty())
{
queryString.append("&cmisselector=");
queryString.append(Constants.SELECTOR_REPOSITORY_INFO);
}
return queryString.toString();
}
return reqQueryString;
}
@Override
public String getRequestURI()
{
String requestURI = baseUrlGenerator.getRequestURI(getRequest(), networkId, operation, id);
return requestURI;
}
@Override
public String getServletPath()
{
String servletPath = baseUrlGenerator.getServletPath(getRequest());
return servletPath;
}
}

View File

@@ -25,13 +25,14 @@
*/
package org.alfresco.opencmis;
import java.util.Collections;
import java.util.Set;
import jakarta.servlet.http.HttpServletResponseWrapper;
import org.alfresco.error.AlfrescoRuntimeException;
import org.springframework.extensions.webscripts.WebScriptResponse;
import org.springframework.extensions.webscripts.servlet.WebScriptServletRuntime;
import java.util.Collections;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
/**
* Wraps an OpenCMIS HttpServletResponse for specific mapping to the Alfresco implementation of OpenCMIS.
@@ -47,11 +48,11 @@ public class CMISHttpServletResponse extends HttpServletResponseWrapper
private final static String ATTACHMENT = "attachment";
private final static String INLINE = "inline";
public CMISHttpServletResponse(WebScriptResponse res, Set<String> nonAttachContentTypes)
{
super(WebScriptServletRuntime.getHttpServletResponse(res));
public CMISHttpServletResponse(WebScriptResponse res, Set<String> nonAttachContentTypes)
{
super(WebScriptServletRuntime.getHttpServletResponse(res));
this.nonAttachContentTypes = nonAttachContentTypes;
}
}
@Override
public void setHeader(String name, String value)
@@ -69,20 +70,20 @@ public class CMISHttpServletResponse extends HttpServletResponseWrapper
{
if (HDR_CONTENT_DISPOSITION.equals(name))
{
if (! nonAttachContentTypes.contains(contentType))
if (!nonAttachContentTypes.contains(contentType))
{
if (value.startsWith(INLINE))
{
// force attachment
value = ATTACHMENT+value.substring(INLINE.length());
value = ATTACHMENT + value.substring(INLINE.length());
}
else if (! value.startsWith(ATTACHMENT))
else if (!value.startsWith(ATTACHMENT))
{
throw new AlfrescoRuntimeException("Unexpected - header could not be set: "+name+" = "+value);
throw new AlfrescoRuntimeException("Unexpected - header could not be set: " + name + " = " + value);
}
}
}
return value;
}
}
}

View File

@@ -23,39 +23,39 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import java.io.IOException;
import org.springframework.extensions.webscripts.AbstractWebScript;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
/**
* An Alfresco web script that handles dispatch of OpenCMIS requests.
*
* @author steveglover
*
*/
public class CMISWebScript extends AbstractWebScript
{
private CMISDispatcherRegistry registry;
public void setRegistry(CMISDispatcherRegistry registry)
{
this.registry = registry;
}
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
{
CMISDispatcher dispatcher = registry.getDispatcher(req);
if(dispatcher == null)
{
res.setStatus(404);
}
else
{
dispatcher.execute(req, res);
}
}
}
package org.alfresco.opencmis;
import java.io.IOException;
import org.springframework.extensions.webscripts.AbstractWebScript;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
/**
* An Alfresco web script that handles dispatch of OpenCMIS requests.
*
* @author steveglover
*
*/
public class CMISWebScript extends AbstractWebScript
{
private CMISDispatcherRegistry registry;
public void setRegistry(CMISDispatcherRegistry registry)
{
this.registry = registry;
}
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
{
CMISDispatcher dispatcher = registry.getDispatcher(req);
if (dispatcher == null)
{
res.setStatus(404);
}
else
{
dispatcher.execute(req, res);
}
}
}

View File

@@ -1,74 +1,72 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import jakarta.servlet.http.HttpServletRequest;
/**
* Generates an OpenCMIS base url based on the request, repository id and binding. The url scheme, host and port
* are overridden by a property from repository.properties or in an override file.
*
* @author steveglover
*
*/
public class DefaultBaseUrlGenerator extends AbstractBaseUrlGenerator
{
private boolean overrideServer;
private String serverOverride;
public DefaultBaseUrlGenerator()
{
}
public void setOverrideServer(boolean overrideServer)
{
this.overrideServer = overrideServer;
}
public void setServerOverride(String serverOverride)
{
this.serverOverride = serverOverride;
}
protected String getServerPath(HttpServletRequest request)
{
if(overrideServer)
{
return serverOverride;
}
else
{
StringBuilder sb = new StringBuilder();
sb.append(request.getScheme());
sb.append("://");
sb.append(request.getServerName());
sb.append(":");
sb.append(request.getServerPort());
return sb.toString();
}
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import jakarta.servlet.http.HttpServletRequest;
/**
* Generates an OpenCMIS base url based on the request, repository id and binding. The url scheme, host and port are overridden by a property from repository.properties or in an override file.
*
* @author steveglover
*
*/
public class DefaultBaseUrlGenerator extends AbstractBaseUrlGenerator
{
private boolean overrideServer;
private String serverOverride;
public DefaultBaseUrlGenerator()
{}
public void setOverrideServer(boolean overrideServer)
{
this.overrideServer = overrideServer;
}
public void setServerOverride(String serverOverride)
{
this.serverOverride = serverOverride;
}
protected String getServerPath(HttpServletRequest request)
{
if (overrideServer)
{
return serverOverride;
}
else
{
StringBuilder sb = new StringBuilder();
sb.append(request.getScheme());
sb.append("://");
sb.append(request.getServerName());
sb.append(":");
sb.append(request.getServerPort());
return sb.toString();
}
}
}

View File

@@ -1,55 +1,55 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import jakarta.servlet.http.HttpServletRequest;
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
import org.alfresco.repo.tenant.TenantUtil;
/**
* Default generator for OpenCMIS paths based on the repositoryId and binding.
*
* @author steveglover
*
*/
public class DefaultPathGenerator implements PathGenerator
{
public void generatePath(HttpServletRequest req, StringBuilder url, String repositoryId, Binding binding)
{
url.append(binding.toString());
url.append("/");
if(repositoryId != null)
{
url.append(repositoryId);
}
else
{
url.append(TenantUtil.DEFAULT_TENANT);
}
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import jakarta.servlet.http.HttpServletRequest;
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
import org.alfresco.repo.tenant.TenantUtil;
/**
* Default generator for OpenCMIS paths based on the repositoryId and binding.
*
* @author steveglover
*
*/
public class DefaultPathGenerator implements PathGenerator
{
public void generatePath(HttpServletRequest req, StringBuilder url, String repositoryId, Binding binding)
{
url.append(binding.toString());
url.append("/");
if (repositoryId != null)
{
url.append(repositoryId);
}
else
{
url.append(TenantUtil.DEFAULT_TENANT);
}
}
}

View File

@@ -37,5 +37,5 @@ import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
*/
public interface PathGenerator
{
public void generatePath(HttpServletRequest req, StringBuilder url, String repositoryId, Binding binding);
}
public void generatePath(HttpServletRequest req, StringBuilder url, String repositoryId, Binding binding);
}

View File

@@ -1,101 +1,100 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import jakarta.servlet.http.HttpServletRequest;
/**
* Generates an OpenCMIS base url based on the request, repository id and binding. The url scheme, host and port
* are overridden by any proxy http header parameters, if present.
*
* @author steveglover
*
*/
public class ProxyBaseUrlGenerator extends AbstractBaseUrlGenerator
{
public static final String FORWARDED_HOST_HEADER = "X-Forwarded-Host";
public static final String FORWARDED_PROTO_HEADER = "X-Forwarded-Proto";
public static final String HTTPS_SCHEME = "https";
public static final String HTTP_SCHEME = "http";
@Override
protected String getServerPath(HttpServletRequest request)
{
String scheme = request.getHeader(FORWARDED_PROTO_HEADER);
String serverName;
int serverPort;
if (!HTTP_SCHEME.equalsIgnoreCase(scheme) && !HTTPS_SCHEME.equalsIgnoreCase(scheme))
{
scheme = request.getScheme();
}
serverName = request.getServerName();
serverPort = request.getServerPort();
String host = request.getHeader(FORWARDED_HOST_HEADER);
if ((host != null) && (host.length() > 0))
{
int index = host.indexOf(':');
if (index < 0)
{
serverName = host;
serverPort = getDefaultPort(scheme);
}
else
{
serverName = host.substring(0, index);
try
{
serverPort = Integer.parseInt(host.substring(index + 1));
}
catch (NumberFormatException e)
{
serverPort = getDefaultPort(scheme);
}
}
}
StringBuilder sb = new StringBuilder();
sb.append(scheme);
sb.append("://");
sb.append(serverName);
sb.append(":");
sb.append(serverPort);
return sb.toString();
}
private int getDefaultPort(String scheme)
{
if (HTTPS_SCHEME.equalsIgnoreCase(scheme))
{
return 443;
}
return 80;
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import jakarta.servlet.http.HttpServletRequest;
/**
* Generates an OpenCMIS base url based on the request, repository id and binding. The url scheme, host and port are overridden by any proxy http header parameters, if present.
*
* @author steveglover
*
*/
public class ProxyBaseUrlGenerator extends AbstractBaseUrlGenerator
{
public static final String FORWARDED_HOST_HEADER = "X-Forwarded-Host";
public static final String FORWARDED_PROTO_HEADER = "X-Forwarded-Proto";
public static final String HTTPS_SCHEME = "https";
public static final String HTTP_SCHEME = "http";
@Override
protected String getServerPath(HttpServletRequest request)
{
String scheme = request.getHeader(FORWARDED_PROTO_HEADER);
String serverName;
int serverPort;
if (!HTTP_SCHEME.equalsIgnoreCase(scheme) && !HTTPS_SCHEME.equalsIgnoreCase(scheme))
{
scheme = request.getScheme();
}
serverName = request.getServerName();
serverPort = request.getServerPort();
String host = request.getHeader(FORWARDED_HOST_HEADER);
if ((host != null) && (host.length() > 0))
{
int index = host.indexOf(':');
if (index < 0)
{
serverName = host;
serverPort = getDefaultPort(scheme);
}
else
{
serverName = host.substring(0, index);
try
{
serverPort = Integer.parseInt(host.substring(index + 1));
}
catch (NumberFormatException e)
{
serverPort = getDefaultPort(scheme);
}
}
}
StringBuilder sb = new StringBuilder();
sb.append(scheme);
sb.append("://");
sb.append(serverName);
sb.append(":");
sb.append(serverPort);
return sb.toString();
}
private int getDefaultPort(String scheme)
{
if (HTTPS_SCHEME.equalsIgnoreCase(scheme))
{
return 443;
}
return 80;
}
}

View File

@@ -23,203 +23,202 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.tenant.Network;
import org.alfresco.repo.tenant.NetworksService;
import org.alfresco.repo.tenant.TenantAdminService;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
import org.alfresco.util.FileFilterMode;
import org.alfresco.util.FileFilterMode.Client;
import org.apache.chemistry.opencmis.commons.data.Acl;
import org.apache.chemistry.opencmis.commons.data.ContentStream;
import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
import org.apache.chemistry.opencmis.commons.data.Properties;
import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.RepositoryInfoImpl;
import org.apache.chemistry.opencmis.commons.spi.Holder;
/**
* Override OpenCMIS service object - for public api
*
* @author sglover
* @since PublicApi1.0
*/
public class PublicApiAlfrescoCmisService extends AlfrescoCmisServiceImpl
{
protected CMISConnector connector;
protected TenantAdminService tenantAdminService;
protected NetworksService networksService;
public PublicApiAlfrescoCmisService(CMISConnector connector, TenantAdminService tenantAdminService, NetworksService networksService)
{
super(connector);
this.connector = connector;
this.networksService = networksService;
this.tenantAdminService = tenantAdminService;
}
@Override
public String create(String repositoryId, Properties properties, String folderId,
ContentStream contentStream, VersioningState versioningState,
List<String> policies, ExtensionsData extension)
{
FileFilterMode.setClient(Client.cmis);
try
{
return super.create(
repositoryId,
properties,
folderId,
contentStream,
versioningState,
policies,
extension);
}
finally
{
FileFilterMode.clearClient();
}
}
/**
* Overridden to capture content upload for publishing to analytics service.
*/
@Override
public String createDocument(String repositoryId, Properties properties, String folderId,
ContentStream contentStream, VersioningState versioningState,
List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension)
{
String newId = super.createDocument(
repositoryId,
properties,
folderId,
contentStream,
versioningState,
policies,
addAces,
removeAces,
extension);
return newId;
}
/**
* Overridden to capture content upload for publishing to analytics service.
*/
@Override
public void setContentStream(String repositoryId, Holder<String> objectId,
Boolean overwriteFlag, Holder<String> changeToken, ContentStream contentStream,
ExtensionsData extension)
{
FileFilterMode.setClient(Client.cmis);
try
{
super.setContentStream(repositoryId, objectId, overwriteFlag, changeToken, contentStream, extension);
}
finally
{
FileFilterMode.clearClient();
}
}
@Override
public List<RepositoryInfo> getRepositoryInfos(ExtensionsData extension)
{
// for currently authenticated user
PagingResults<Network> networks = networksService.getNetworks(new PagingRequest(0, Integer.MAX_VALUE));
List<Network> page = networks.getPage();
final List<RepositoryInfo> repoInfos = new ArrayList<RepositoryInfo>(page.size() + 1);
for (Network network : page)
{
repoInfos.add(getRepositoryInfo(network));
}
return repoInfos;
}
@Override
public RepositoryInfo getRepositoryInfo(String repositoryId, ExtensionsData extension)
{
Network network = null;
try
{
checkRepositoryId(repositoryId);
network = networksService.getNetwork(repositoryId);
}
catch(Exception e)
{
// ACE-2540: Avoid information leak. Same response if repository does not exist or if user is not a member
throw new CmisObjectNotFoundException("Unknown repository '" + repositoryId + "'!");
}
return getRepositoryInfo(network);
}
private RepositoryInfo getRepositoryInfo(final Network network)
{
final String networkId = network.getTenantDomain();
final String tenantDomain = (networkId.equals(TenantUtil.SYSTEM_TENANT) || networkId.equals(TenantUtil.DEFAULT_TENANT)) ? TenantService.DEFAULT_DOMAIN : networkId;
return TenantUtil.runAsSystemTenant(new TenantRunAsWork<RepositoryInfo>()
{
public RepositoryInfo doWork()
{
RepositoryInfoImpl repoInfo = (RepositoryInfoImpl)connector.getRepositoryInfo(getContext().getCmisVersion());
repoInfo.setId(!networkId.equals("") ? networkId : TenantUtil.SYSTEM_TENANT);
repoInfo.setName(tenantDomain);
repoInfo.setDescription(tenantDomain);
return repoInfo;
}
}, tenantDomain);
}
@Override
public void checkRepositoryId(String repositoryId)
{
if(repositoryId.equals(TenantUtil.DEFAULT_TENANT) || repositoryId.equals(TenantUtil.SYSTEM_TENANT))
{
// TODO check for super admin
return;
}
if(!tenantAdminService.existsTenant(repositoryId) || !tenantAdminService.isEnabledTenant(repositoryId))
{
throw new CmisObjectNotFoundException("Unknown repository '" + repositoryId + "'!");
}
}
@Override
public void beforeCall()
{
// NOTE: Don't invoke super beforeCall to exclude authentication which is already supported by
// Web Script F/W
//super.beforeCall();
}
@Override
public void afterCall()
{
// NOTE: Don't invoke super afterCall to exclude authentication which is already supported by
// Web Script F/W
//super.afterCall();
}
@Override
public void close()
{
super.close();
}
}
package org.alfresco.opencmis;
import java.util.ArrayList;
import java.util.List;
import org.apache.chemistry.opencmis.commons.data.Acl;
import org.apache.chemistry.opencmis.commons.data.ContentStream;
import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
import org.apache.chemistry.opencmis.commons.data.Properties;
import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.RepositoryInfoImpl;
import org.apache.chemistry.opencmis.commons.spi.Holder;
import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.tenant.Network;
import org.alfresco.repo.tenant.NetworksService;
import org.alfresco.repo.tenant.TenantAdminService;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
import org.alfresco.util.FileFilterMode;
import org.alfresco.util.FileFilterMode.Client;
/**
* Override OpenCMIS service object - for public api
*
* @author sglover
* @since PublicApi1.0
*/
public class PublicApiAlfrescoCmisService extends AlfrescoCmisServiceImpl
{
protected CMISConnector connector;
protected TenantAdminService tenantAdminService;
protected NetworksService networksService;
public PublicApiAlfrescoCmisService(CMISConnector connector, TenantAdminService tenantAdminService, NetworksService networksService)
{
super(connector);
this.connector = connector;
this.networksService = networksService;
this.tenantAdminService = tenantAdminService;
}
@Override
public String create(String repositoryId, Properties properties, String folderId,
ContentStream contentStream, VersioningState versioningState,
List<String> policies, ExtensionsData extension)
{
FileFilterMode.setClient(Client.cmis);
try
{
return super.create(
repositoryId,
properties,
folderId,
contentStream,
versioningState,
policies,
extension);
}
finally
{
FileFilterMode.clearClient();
}
}
/**
* Overridden to capture content upload for publishing to analytics service.
*/
@Override
public String createDocument(String repositoryId, Properties properties, String folderId,
ContentStream contentStream, VersioningState versioningState,
List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension)
{
String newId = super.createDocument(
repositoryId,
properties,
folderId,
contentStream,
versioningState,
policies,
addAces,
removeAces,
extension);
return newId;
}
/**
* Overridden to capture content upload for publishing to analytics service.
*/
@Override
public void setContentStream(String repositoryId, Holder<String> objectId,
Boolean overwriteFlag, Holder<String> changeToken, ContentStream contentStream,
ExtensionsData extension)
{
FileFilterMode.setClient(Client.cmis);
try
{
super.setContentStream(repositoryId, objectId, overwriteFlag, changeToken, contentStream, extension);
}
finally
{
FileFilterMode.clearClient();
}
}
@Override
public List<RepositoryInfo> getRepositoryInfos(ExtensionsData extension)
{
// for currently authenticated user
PagingResults<Network> networks = networksService.getNetworks(new PagingRequest(0, Integer.MAX_VALUE));
List<Network> page = networks.getPage();
final List<RepositoryInfo> repoInfos = new ArrayList<RepositoryInfo>(page.size() + 1);
for (Network network : page)
{
repoInfos.add(getRepositoryInfo(network));
}
return repoInfos;
}
@Override
public RepositoryInfo getRepositoryInfo(String repositoryId, ExtensionsData extension)
{
Network network = null;
try
{
checkRepositoryId(repositoryId);
network = networksService.getNetwork(repositoryId);
}
catch (Exception e)
{
// ACE-2540: Avoid information leak. Same response if repository does not exist or if user is not a member
throw new CmisObjectNotFoundException("Unknown repository '" + repositoryId + "'!");
}
return getRepositoryInfo(network);
}
private RepositoryInfo getRepositoryInfo(final Network network)
{
final String networkId = network.getTenantDomain();
final String tenantDomain = (networkId.equals(TenantUtil.SYSTEM_TENANT) || networkId.equals(TenantUtil.DEFAULT_TENANT)) ? TenantService.DEFAULT_DOMAIN : networkId;
return TenantUtil.runAsSystemTenant(new TenantRunAsWork<RepositoryInfo>() {
public RepositoryInfo doWork()
{
RepositoryInfoImpl repoInfo = (RepositoryInfoImpl) connector.getRepositoryInfo(getContext().getCmisVersion());
repoInfo.setId(!networkId.equals("") ? networkId : TenantUtil.SYSTEM_TENANT);
repoInfo.setName(tenantDomain);
repoInfo.setDescription(tenantDomain);
return repoInfo;
}
}, tenantDomain);
}
@Override
public void checkRepositoryId(String repositoryId)
{
if (repositoryId.equals(TenantUtil.DEFAULT_TENANT) || repositoryId.equals(TenantUtil.SYSTEM_TENANT))
{
// TODO check for super admin
return;
}
if (!tenantAdminService.existsTenant(repositoryId) || !tenantAdminService.isEnabledTenant(repositoryId))
{
throw new CmisObjectNotFoundException("Unknown repository '" + repositoryId + "'!");
}
}
@Override
public void beforeCall()
{
// NOTE: Don't invoke super beforeCall to exclude authentication which is already supported by
// Web Script F/W
// super.beforeCall();
}
@Override
public void afterCall()
{
// NOTE: Don't invoke super afterCall to exclude authentication which is already supported by
// Web Script F/W
// super.afterCall();
}
@Override
public void close()
{
super.close();
}
}

View File

@@ -23,36 +23,36 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import org.alfresco.repo.tenant.NetworksService;
import org.alfresco.repo.tenant.TenantAdminService;
/**
* Override factory for OpenCMIS service objects - for public api
*
* @author steveglover
* @author janv
* @since PublicApi1.0
*/
public class PublicApiAlfrescoCmisServiceFactory extends AlfrescoCmisServiceFactory
{
private TenantAdminService tenantAdminService;
private NetworksService networksService;
public void setNetworksService(NetworksService networksService)
{
this.networksService = networksService;
}
public void setTenantAdminService(TenantAdminService tenantAdminService)
{
this.tenantAdminService = tenantAdminService;
}
@Override
protected AlfrescoCmisService getCmisServiceTarget(CMISConnector connector)
{
return new PublicApiAlfrescoCmisService(connector, tenantAdminService, networksService);
}
}
package org.alfresco.opencmis;
import org.alfresco.repo.tenant.NetworksService;
import org.alfresco.repo.tenant.TenantAdminService;
/**
* Override factory for OpenCMIS service objects - for public api
*
* @author steveglover
* @author janv
* @since PublicApi1.0
*/
public class PublicApiAlfrescoCmisServiceFactory extends AlfrescoCmisServiceFactory
{
private TenantAdminService tenantAdminService;
private NetworksService networksService;
public void setNetworksService(NetworksService networksService)
{
this.networksService = networksService;
}
public void setTenantAdminService(TenantAdminService tenantAdminService)
{
this.tenantAdminService = tenantAdminService;
}
@Override
protected AlfrescoCmisService getCmisServiceTarget(CMISConnector connector)
{
return new PublicApiAlfrescoCmisService(connector, tenantAdminService, networksService);
}
}

View File

@@ -23,24 +23,24 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Dispatches OpenCMIS requests to the OpenCMIS AtomPub servlet.
*
* @author steveglover
*
*/
public class PublicApiAtomPubCMISDispatcher extends AtomPubCMISDispatcher
{
@Override
protected CMISHttpServletRequest getHttpRequest(WebScriptRequest req)
{
String serviceName = getServiceName();
CMISHttpServletRequest httpReqWrapper = new PublicApiCMISHttpServletRequest(req, serviceName, baseUrlGenerator,
getBinding(), getCurrentDescriptor(), tenantAdminService);
return httpReqWrapper;
}
}
package org.alfresco.opencmis;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Dispatches OpenCMIS requests to the OpenCMIS AtomPub servlet.
*
* @author steveglover
*
*/
public class PublicApiAtomPubCMISDispatcher extends AtomPubCMISDispatcher
{
@Override
protected CMISHttpServletRequest getHttpRequest(WebScriptRequest req)
{
String serviceName = getServiceName();
CMISHttpServletRequest httpReqWrapper = new PublicApiCMISHttpServletRequest(req, serviceName, baseUrlGenerator,
getBinding(), getCurrentDescriptor(), tenantAdminService);
return httpReqWrapper;
}
}

View File

@@ -23,24 +23,24 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Cloud-specific browser binding OpenCMIS dispatcher.
*
* @author steveglover
*
*/
public class PublicApiBrowserCMISDispatcher extends BrowserCMISDispatcher
{
@Override
protected CMISHttpServletRequest getHttpRequest(WebScriptRequest req)
{
String serviceName = getServiceName();
CMISHttpServletRequest httpReqWrapper = new PublicApiCMISHttpServletRequest(req, serviceName,
baseUrlGenerator, getBinding(), getCurrentDescriptor(), tenantAdminService);
return httpReqWrapper;
}
}
package org.alfresco.opencmis;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Cloud-specific browser binding OpenCMIS dispatcher.
*
* @author steveglover
*
*/
public class PublicApiBrowserCMISDispatcher extends BrowserCMISDispatcher
{
@Override
protected CMISHttpServletRequest getHttpRequest(WebScriptRequest req)
{
String serviceName = getServiceName();
CMISHttpServletRequest httpReqWrapper = new PublicApiCMISHttpServletRequest(req, serviceName,
baseUrlGenerator, getBinding(), getCurrentDescriptor(), tenantAdminService);
return httpReqWrapper;
}
}

View File

@@ -1,67 +1,68 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import java.util.Map;
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
import org.alfresco.repo.tenant.TenantAdminService;
import org.alfresco.service.descriptor.Descriptor;
import org.springframework.extensions.webscripts.Match;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Wraps an OpenCMIS HttpServletRequest, mapping urls and adding servlet attributes specific to the Alfresco implementation of OpenCMIS.
*/
public class PublicApiCMISHttpServletRequest extends CMISHttpServletRequest
{
public PublicApiCMISHttpServletRequest(WebScriptRequest req, String serviceName, BaseUrlGenerator baseUrlGenerator,
Binding binding, Descriptor currentDescriptor, TenantAdminService tenantAdminService)
{
super(req, serviceName, baseUrlGenerator, binding, currentDescriptor, tenantAdminService);
}
protected void addAttributes()
{
super.addAttributes();
Match match = req.getServiceMatch();
Map<String, String> templateVars = match.getTemplateVars();
String apiScope = templateVars.get("apiScope");
String apiVersion = templateVars.get("apiVersion");
if(apiScope != null)
{
setAttribute("apiScope", apiScope);
}
if(apiVersion != null)
{
setAttribute("apiVersion", apiVersion);
}
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import java.util.Map;
import org.springframework.extensions.webscripts.Match;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
import org.alfresco.repo.tenant.TenantAdminService;
import org.alfresco.service.descriptor.Descriptor;
/**
* Wraps an OpenCMIS HttpServletRequest, mapping urls and adding servlet attributes specific to the Alfresco implementation of OpenCMIS.
*/
public class PublicApiCMISHttpServletRequest extends CMISHttpServletRequest
{
public PublicApiCMISHttpServletRequest(WebScriptRequest req, String serviceName, BaseUrlGenerator baseUrlGenerator,
Binding binding, Descriptor currentDescriptor, TenantAdminService tenantAdminService)
{
super(req, serviceName, baseUrlGenerator, binding, currentDescriptor, tenantAdminService);
}
protected void addAttributes()
{
super.addAttributes();
Match match = req.getServiceMatch();
Map<String, String> templateVars = match.getTemplateVars();
String apiScope = templateVars.get("apiScope");
String apiVersion = templateVars.get("apiVersion");
if (apiScope != null)
{
setAttribute("apiScope", apiScope);
}
if (apiVersion != null)
{
setAttribute("apiVersion", apiVersion);
}
}
}

View File

@@ -1,63 +1,63 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import jakarta.servlet.http.HttpServletRequest;
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
/**
* Cloud generator for OpenCMIS paths based on the repositoryId and binding.
*
* @author steveglover
*
*/
public class PublicApiPathGenerator implements PathGenerator
{
public void generatePath(HttpServletRequest req, StringBuilder url, String repositoryId, Binding binding)
{
url.append("{repositoryId}");
url.append("/");
String scope = (String)req.getAttribute("apiScope");
String serviceName = (String)req.getAttribute("serviceName");
String apiVersion = (String)req.getAttribute("apiVersion");
if(scope == null)
{
scope = "public";
}
url.append(scope);
url.append("/");
url.append(serviceName);
url.append("/");
url.append("versions");
url.append("/");
url.append(apiVersion);
url.append("/");
url.append(binding.toString());
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import jakarta.servlet.http.HttpServletRequest;
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
/**
* Cloud generator for OpenCMIS paths based on the repositoryId and binding.
*
* @author steveglover
*
*/
public class PublicApiPathGenerator implements PathGenerator
{
public void generatePath(HttpServletRequest req, StringBuilder url, String repositoryId, Binding binding)
{
url.append("{repositoryId}");
url.append("/");
String scope = (String) req.getAttribute("apiScope");
String serviceName = (String) req.getAttribute("serviceName");
String apiVersion = (String) req.getAttribute("apiVersion");
if (scope == null)
{
scope = "public";
}
url.append(scope);
url.append("/");
url.append(serviceName);
url.append("/");
url.append("versions");
url.append("/");
url.append(apiVersion);
url.append("/");
url.append(binding.toString());
}
}

View File

@@ -1,90 +1,89 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import jakarta.servlet.http.HttpServletRequest;
import org.alfresco.repo.admin.SysAdminParams;
/**
* Generates an OpenCMIS base url based on the request, repository id and binding. The url scheme, host and port
* are overridden by sys admin parameters.
*
* @author steveglover
*
*/
public class SysAdminParamsBaseUrlGenerator extends AbstractBaseUrlGenerator
{
private SysAdminParams sysAdminParams;
protected String getServerPath(HttpServletRequest request)
{
StringBuilder sb = new StringBuilder();
sb.append(getServerScheme(request));
sb.append("://");
sb.append(getServerName(request));
sb.append(":");
sb.append(getServerPort(request));
return sb.toString();
}
protected String getServerScheme(HttpServletRequest request)
{
String scheme = sysAdminParams.getAlfrescoProtocol();
if (scheme == null)
{
scheme = request.getScheme();
}
scheme = request.getScheme();
return scheme;
}
protected String getServerName(HttpServletRequest request)
{
String hostname = sysAdminParams.getAlfrescoHost();
if (hostname == null)
{
hostname = request.getScheme();
}
hostname = request.getServerName();
return hostname;
}
protected int getServerPort(HttpServletRequest request)
{
Integer port = sysAdminParams.getAlfrescoPort();
if (port == null)
{
port = request.getServerPort();
}
if (port == null)
{
port = request.getServerPort();
}
return port;
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.opencmis;
import jakarta.servlet.http.HttpServletRequest;
import org.alfresco.repo.admin.SysAdminParams;
/**
* Generates an OpenCMIS base url based on the request, repository id and binding. The url scheme, host and port are overridden by sys admin parameters.
*
* @author steveglover
*
*/
public class SysAdminParamsBaseUrlGenerator extends AbstractBaseUrlGenerator
{
private SysAdminParams sysAdminParams;
protected String getServerPath(HttpServletRequest request)
{
StringBuilder sb = new StringBuilder();
sb.append(getServerScheme(request));
sb.append("://");
sb.append(getServerName(request));
sb.append(":");
sb.append(getServerPort(request));
return sb.toString();
}
protected String getServerScheme(HttpServletRequest request)
{
String scheme = sysAdminParams.getAlfrescoProtocol();
if (scheme == null)
{
scheme = request.getScheme();
}
scheme = request.getScheme();
return scheme;
}
protected String getServerName(HttpServletRequest request)
{
String hostname = sysAdminParams.getAlfrescoHost();
if (hostname == null)
{
hostname = request.getScheme();
}
hostname = request.getServerName();
return hostname;
}
protected int getServerPort(HttpServletRequest request)
{
Integer port = sysAdminParams.getAlfrescoPort();
if (port == null)
{
port = request.getServerPort();
}
if (port == null)
{
port = request.getServerPort();
}
return port;
}
}

View File

@@ -23,29 +23,28 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo;
import java.io.Serializable;
/**
* Contract implemented by any object that represents an Alfresco "user" that
* can be persisted in an HTTP Session.
*
* @author Kevin Roast
*/
public interface SessionUser extends Serializable
{
/**
* Return the user name
*
* @return user name
*/
String getUserName();
/**
* Return the ticket
*
* @return ticket
*/
String getTicket();
}
package org.alfresco.repo;
import java.io.Serializable;
/**
* Contract implemented by any object that represents an Alfresco "user" that can be persisted in an HTTP Session.
*
* @author Kevin Roast
*/
public interface SessionUser extends Serializable
{
/**
* Return the user name
*
* @return user name
*/
String getUserName();
/**
* Return the ticket
*
* @return ticket
*/
String getTicket();
}

View File

@@ -23,49 +23,49 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.imap.scripts;
import java.io.IOException;
import org.alfresco.repo.imap.ImapService;
import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.extensions.webscripts.AbstractWebScript;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
/**
* Shows the availability of the IMAP server via web script request.
*/
public class ServerStatusWebScript extends AbstractWebScript implements ApplicationContextAware
{
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
this.applicationContext = applicationContext;
}
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
{
ChildApplicationContextFactory subsystem = (ChildApplicationContextFactory)applicationContext.getBean("imap");
// note: getting property (rather than getting imapService bean to check isEnabled) does not cause subsystem startup (if stopped)
// hence providing ability for subsystem to be disabled (whilst still supporting ability to check status and/or dynamically start via JMX)
String isEnabled = (String)subsystem.getProperty("imap.server.enabled");
if (Boolean.valueOf(isEnabled).booleanValue())
{
res.getWriter().write("enabled");
}
else
{
res.getWriter().write("disabled");
}
res.getWriter().flush();
res.getWriter().close();
}
}
package org.alfresco.repo.imap.scripts;
import java.io.IOException;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.extensions.webscripts.AbstractWebScript;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
/**
* Shows the availability of the IMAP server via web script request.
*/
public class ServerStatusWebScript extends AbstractWebScript implements ApplicationContextAware
{
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
this.applicationContext = applicationContext;
}
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
{
ChildApplicationContextFactory subsystem = (ChildApplicationContextFactory) applicationContext.getBean("imap");
// note: getting property (rather than getting imapService bean to check isEnabled) does not cause subsystem startup (if stopped)
// hence providing ability for subsystem to be disabled (whilst still supporting ability to check status and/or dynamically start via JMX)
String isEnabled = (String) subsystem.getProperty("imap.server.enabled");
if (Boolean.valueOf(isEnabled).booleanValue())
{
res.getWriter().write("enabled");
}
else
{
res.getWriter().write("disabled");
}
res.getWriter().flush();
res.getWriter().close();
}
}

View File

@@ -23,80 +23,80 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.surf.policy;
import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.web.scripts.bean.ADMRemoteStore;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* Delete Node Policy to remove surf-config files for a deleted user.
*
* @author Dmitry Velichkevich
* @author Kevin Roast
*/
public class SurfConfigCleaner extends ADMRemoteStore implements BeforeDeleteNodePolicy
{
private PolicyComponent policyComponent;
public void init()
{
this.policyComponent.bindClassBehaviour(
BeforeDeleteNodePolicy.QNAME,
ContentModel.TYPE_PERSON,
new JavaBehaviour(this, BeforeDeleteNodePolicy.QNAME.getLocalName()));
}
@Override
public void beforeDeleteNode(NodeRef nodeRef)
{
final String userName = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_USERNAME);
final NodeRef componentsRef = getGlobalComponentsNodeRef();
final NodeRef usersFolderRef = getGlobalUserFolderNodeRef();
// Remove the user Surf config folder, contains dynamic page definitions such as dashboard.xml
// For example, qname path to user folder:
// /app:company_home/st:sites/cm:surf-config/cm:pages/cm:user/cm:admin
// ^^^^^ encoded username
if (usersFolderRef != null)
{
NodeRef userFolderNodeRef = nodeService.getChildByName(usersFolderRef, ContentModel.ASSOC_CONTAINS, encodePath(userName));
if (userFolderNodeRef != null)
{
// CLOUD-2053: Need to set as temporary to delete node instead of archiving.
nodeService.addAspect(userFolderNodeRef, ContentModel.ASPECT_TEMPORARY, null);
nodeService.deleteNode(userFolderNodeRef);
}
}
// Remove each component Surf config file related to the user, such as the dashboard dashlet component references
// For example, qname path to user component file:
// /app:company_home/st:sites/cm:surf-config/cm:components/cm:page.component-1-1.user~admin~dashboard.xml
// ^^^^^ encoded username
if (componentsRef != null)
{
List<FileInfo> configNodes = getFileNodes(
fileFolderService.getFileInfo(componentsRef),
buildUserConfigSearchPattern(userName),
true).getPage();
for (FileInfo fileInfo : configNodes)
{
// CLOUD-2053: Need to set as temporary to delete node instead of archiving.
nodeService.addAspect(fileInfo.getNodeRef(), ContentModel.ASPECT_TEMPORARY, null);
nodeService.deleteNode(fileInfo.getNodeRef());
}
}
}
public void setPolicyComponent(PolicyComponent policyComponent)
{
this.policyComponent = policyComponent;
}
}
package org.alfresco.repo.surf.policy;
import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.web.scripts.bean.ADMRemoteStore;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* Delete Node Policy to remove surf-config files for a deleted user.
*
* @author Dmitry Velichkevich
* @author Kevin Roast
*/
public class SurfConfigCleaner extends ADMRemoteStore implements BeforeDeleteNodePolicy
{
private PolicyComponent policyComponent;
public void init()
{
this.policyComponent.bindClassBehaviour(
BeforeDeleteNodePolicy.QNAME,
ContentModel.TYPE_PERSON,
new JavaBehaviour(this, BeforeDeleteNodePolicy.QNAME.getLocalName()));
}
@Override
public void beforeDeleteNode(NodeRef nodeRef)
{
final String userName = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_USERNAME);
final NodeRef componentsRef = getGlobalComponentsNodeRef();
final NodeRef usersFolderRef = getGlobalUserFolderNodeRef();
// Remove the user Surf config folder, contains dynamic page definitions such as dashboard.xml
// For example, qname path to user folder:
// /app:company_home/st:sites/cm:surf-config/cm:pages/cm:user/cm:admin
// ^^^^^ encoded username
if (usersFolderRef != null)
{
NodeRef userFolderNodeRef = nodeService.getChildByName(usersFolderRef, ContentModel.ASSOC_CONTAINS, encodePath(userName));
if (userFolderNodeRef != null)
{
// CLOUD-2053: Need to set as temporary to delete node instead of archiving.
nodeService.addAspect(userFolderNodeRef, ContentModel.ASPECT_TEMPORARY, null);
nodeService.deleteNode(userFolderNodeRef);
}
}
// Remove each component Surf config file related to the user, such as the dashboard dashlet component references
// For example, qname path to user component file:
// /app:company_home/st:sites/cm:surf-config/cm:components/cm:page.component-1-1.user~admin~dashboard.xml
// ^^^^^ encoded username
if (componentsRef != null)
{
List<FileInfo> configNodes = getFileNodes(
fileFolderService.getFileInfo(componentsRef),
buildUserConfigSearchPattern(userName),
true).getPage();
for (FileInfo fileInfo : configNodes)
{
// CLOUD-2053: Need to set as temporary to delete node instead of archiving.
nodeService.addAspect(fileInfo.getNodeRef(), ContentModel.ASPECT_TEMPORARY, null);
nodeService.deleteNode(fileInfo.getNodeRef());
}
}
}
public void setPolicyComponent(PolicyComponent policyComponent)
{
this.policyComponent = policyComponent;
}
}

View File

@@ -26,8 +26,7 @@
package org.alfresco.repo.web.auth;
/**
* AuthenticationListener implementations can receive notifications of successful and unsuccessful
* authentication requests, made during web script, WebDav or Sharepoint requests.
* AuthenticationListener implementations can receive notifications of successful and unsuccessful authentication requests, made during web script, WebDav or Sharepoint requests.
*
* @author Alex Miller
*/
@@ -44,7 +43,7 @@ public interface AuthenticationListener
public void authenticationFailed(WebCredentials credentials, Exception ex);
/**
* An authentication attempt, using credentials, failed.
* An authentication attempt, using credentials, failed.
*/
public void authenticationFailed(WebCredentials credentials);

View File

@@ -38,9 +38,9 @@ public class BasicAuthCredentials implements WebCredentials
private String userName;
private String password;
/**
* Default constructor
* Default constructor
*/
public BasicAuthCredentials(String userName, String password)
{
@@ -61,20 +61,41 @@ public class BasicAuthCredentials implements WebCredentials
@Override
public boolean equals(Object obj)
{
if (this == obj) { return true; }
if (obj == null) { return false; }
if (getClass() != obj.getClass()) { return false; }
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
BasicAuthCredentials other = (BasicAuthCredentials) obj;
if (this.password == null)
{
if (other.password != null) { return false; }
if (other.password != null)
{
return false;
}
}
else if (!this.password.equals(other.password))
{
return false;
}
else if (!this.password.equals(other.password)) { return false; }
if (this.userName == null)
{
if (other.userName != null) { return false; }
if (other.userName != null)
{
return false;
}
}
else if (!this.userName.equals(other.userName))
{
return false;
}
else if (!this.userName.equals(other.userName)) { return false; }
return true;
}

View File

@@ -25,7 +25,6 @@
*/
package org.alfresco.repo.web.auth;
/**
* {@link WebCredentials} representing a guest user.
*
@@ -47,5 +46,4 @@ public class GuestCredentials implements WebCredentials
return getClass().hashCode();
}
}

View File

@@ -25,7 +25,6 @@
*/
package org.alfresco.repo.web.auth;
/**
* {@link AuthenticationListener} that does nothing.
*

View File

@@ -23,16 +23,18 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.auth;
public interface TenantAuthentication
{
/**
* Authenticate user against tenant
*
* @param username String
* @param tenant String
* @return true => authenticated, false => not authenticated
*/
boolean authenticateTenant(String username, String tenant);
}
package org.alfresco.repo.web.auth;
public interface TenantAuthentication
{
/**
* Authenticate user against tenant
*
* @param username
* String
* @param tenant
* String
* @return true => authenticated, false => not authenticated
*/
boolean authenticateTenant(String username, String tenant);
}

View File

@@ -25,7 +25,6 @@
*/
package org.alfresco.repo.web.auth;
/**
* {@link WebCredentials} class for holding Alfresco tickets.
*
@@ -54,15 +53,30 @@ public class TicketCredentials implements WebCredentials
@Override
public boolean equals(Object obj)
{
if (this == obj) { return true; }
if (obj == null) { return false; }
if (getClass() != obj.getClass()) { return false; }
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
TicketCredentials other = (TicketCredentials) obj;
if (this.ticket == null)
{
if (other.ticket != null) { return false; }
if (other.ticket != null)
{
return false;
}
}
else if (!this.ticket.equals(other.ticket))
{
return false;
}
else if (!this.ticket.equals(other.ticket)) { return false; }
return true;
}
}

View File

@@ -25,7 +25,6 @@
*/
package org.alfresco.repo.web.auth;
/**
* {@link WebCredentials} where credentials are undetermined.
*
@@ -47,5 +46,4 @@ public class UnknownCredentials implements WebCredentials
return getClass().hashCode();
}
}

View File

@@ -1,91 +1,87 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.filter.beans;
import java.io.IOException;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
/**
* An adapter from the servlet filter world into the Spring dependency injected world. Simply looks up a
* {@link DependencyInjectedFilter} with a configured bean name and delegates the
* {@link #doFilter(ServletRequest, ServletResponse, FilterChain)} call to that. This allows us to swap in and out
* different implementations for different 'hook points' in web.xml.
*
* @author dward
*/
public class BeanProxyFilter implements Filter
{
/**
* Name of the init parameter that carries the proxied bean name
*/
private static final String INIT_PARAM_BEAN_NAME = "beanName";
private DependencyInjectedFilter filter;
private ServletContext context;
/**
* Initialize the filter.
*
* @param args
* FilterConfig
* @throws ServletException
* the servlet exception
* @exception ServletException
*/
public void init(FilterConfig args) throws ServletException
{
WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(args.getServletContext());
this.filter = (DependencyInjectedFilter)ctx.getBean(args.getInitParameter(INIT_PARAM_BEAN_NAME));
this.context = args.getServletContext();
}
/* (non-Javadoc)
* @see jakarta.servlet.Filter#destroy()
*/
public void destroy()
{
this.filter = null;
}
/* (non-Javadoc)
* @see jakarta.servlet.Filter#doFilter(jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse, jakarta.servlet.FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException
{
this.filter.doFilter(this.context, request, response, chain);
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.filter.beans;
import java.io.IOException;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
/**
* An adapter from the servlet filter world into the Spring dependency injected world. Simply looks up a {@link DependencyInjectedFilter} with a configured bean name and delegates the {@link #doFilter(ServletRequest, ServletResponse, FilterChain)} call to that. This allows us to swap in and out different implementations for different 'hook points' in web.xml.
*
* @author dward
*/
public class BeanProxyFilter implements Filter
{
/**
* Name of the init parameter that carries the proxied bean name
*/
private static final String INIT_PARAM_BEAN_NAME = "beanName";
private DependencyInjectedFilter filter;
private ServletContext context;
/**
* Initialize the filter.
*
* @param args
* FilterConfig
* @throws ServletException
* the servlet exception
* @exception ServletException
*/
public void init(FilterConfig args) throws ServletException
{
WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(args.getServletContext());
this.filter = (DependencyInjectedFilter) ctx.getBean(args.getInitParameter(INIT_PARAM_BEAN_NAME));
this.context = args.getServletContext();
}
/* (non-Javadoc)
*
* @see jakarta.servlet.Filter#destroy() */
public void destroy()
{
this.filter = null;
}
/* (non-Javadoc)
*
* @see jakarta.servlet.Filter#doFilter(jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse, jakarta.servlet.FilterChain) */
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException
{
this.filter.doFilter(this.context, request, response, chain);
}
}

View File

@@ -1,63 +1,56 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.filter.beans;
import java.io.IOException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
/**
* A bean-like equivalent of a servlet filter, designed to be managed by a Spring container.
*
* @see BeanProxyFilter
* @author dward
*/
public interface DependencyInjectedFilter
{
/**
* The <code>doFilter</code> method of the Filter is called by the container each time a request/response pair is
* passed through the chain due to a client request for a resource at the end of the chain. The FilterChain passed
* in to this method allows the Filter to pass on the request and response to the next entity in the chain.
* <p>
* A typical implementation of this method would follow the following pattern:- <br>
* 1. Examine the request<br>
* 2. Optionally wrap the request object with a custom implementation to filter content or headers for input
* filtering <br>
* 3. Optionally wrap the response object with a custom implementation to filter content or headers for output
* filtering <br>
* 4. a) <strong>Either</strong> invoke the next entity in the chain using the FilterChain object (
* <code>chain.doFilter()</code>), <br>
* 4. b) <strong>or</strong> not pass on the request/response pair to the next entity in the filter chain to block
* the request processing<br>
* 5. Directly set headers on the response after invocation of the next entity in the filter chain.
**/
public void doFilter(ServletContext context, ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException;
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.filter.beans;
import java.io.IOException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
/**
* A bean-like equivalent of a servlet filter, designed to be managed by a Spring container.
*
* @see BeanProxyFilter
* @author dward
*/
public interface DependencyInjectedFilter
{
/**
* The <code>doFilter</code> method of the Filter is called by the container each time a request/response pair is passed through the chain due to a client request for a resource at the end of the chain. The FilterChain passed in to this method allows the Filter to pass on the request and response to the next entity in the chain.
* <p>
* A typical implementation of this method would follow the following pattern:- <br>
* 1. Examine the request<br>
* 2. Optionally wrap the request object with a custom implementation to filter content or headers for input filtering <br>
* 3. Optionally wrap the response object with a custom implementation to filter content or headers for output filtering <br>
* 4. a) <strong>Either</strong> invoke the next entity in the chain using the FilterChain object ( <code>chain.doFilter()</code>), <br>
* 4. b) <strong>or</strong> not pass on the request/response pair to the next entity in the filter chain to block the request processing<br>
* 5. Directly set headers on the response after invocation of the next entity in the filter chain.
**/
public void doFilter(ServletContext context, ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException;
}

View File

@@ -1,79 +1,74 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.filter.beans;
import java.io.IOException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import org.alfresco.repo.management.subsystems.ActivateableBean;
/**
* A Benign filter that does nothing more than invoke the filter chain. Allows strategic points of the filter chain to
* be configured in and out according to the authentication subsystem in use.
*
* @author dward
*/
public class NullFilter implements DependencyInjectedFilter, ActivateableBean
{
private boolean isActive = true;
/**
* Activates or deactivates the bean
*
* @param active
* <code>true</code> if the bean is active and initialization should complete
*/
public void setActive(boolean active)
{
this.isActive = active;
}
/* (non-Javadoc)
* @see org.alfresco.repo.management.subsystems.ActivateableBean#isActive()
*/
public boolean isActive()
{
return this.isActive;
}
/*
* (non-Javadoc)
* @see org.alfresco.repo.web.filter.beans.DependencyInjectedFilter#doFilter(jakarta.servlet.ServletContext,
* jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse, jakarta.servlet.FilterChain)
*/
public void doFilter(ServletContext context, ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
chain.doFilter(request, response);
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.filter.beans;
import java.io.IOException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import org.alfresco.repo.management.subsystems.ActivateableBean;
/**
* A Benign filter that does nothing more than invoke the filter chain. Allows strategic points of the filter chain to be configured in and out according to the authentication subsystem in use.
*
* @author dward
*/
public class NullFilter implements DependencyInjectedFilter, ActivateableBean
{
private boolean isActive = true;
/**
* Activates or deactivates the bean
*
* @param active
* <code>true</code> if the bean is active and initialization should complete
*/
public void setActive(boolean active)
{
this.isActive = active;
}
/* (non-Javadoc)
*
* @see org.alfresco.repo.management.subsystems.ActivateableBean#isActive() */
public boolean isActive()
{
return this.isActive;
}
/* (non-Javadoc)
*
* @see org.alfresco.repo.web.filter.beans.DependencyInjectedFilter#doFilter(jakarta.servlet.ServletContext, jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse, jakarta.servlet.FilterChain) */
public void doFilter(ServletContext context, ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
chain.doFilter(request, response);
}
}

View File

@@ -1,83 +1,77 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.filter.beans;
import java.io.IOException;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
/**
* A filter that will use the HttpSession (if it exists) as the monitor for a
* synchronized block so that only one request per session is processed at any
* time.
*
* Originally created to avoid having to make 200+ JSF session scoped beans thread
* safe.
*
* @author Alan Davis
* @deprecated 5.0 not exposed in web-client web.xml
*/
public class SessionSynchronizedFilter implements Filter
{
@Override
public void init(FilterConfig arg0) throws ServletException
{
}
@Override
public void destroy()
{
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
{
HttpSession session = null;
if (request instanceof HttpServletRequest)
{
session = ((HttpServletRequest)request).getSession(false);
}
if (session != null)
{
synchronized(session)
{
chain.doFilter(request, response);
}
}
else
{
chain.doFilter(request, response);
}
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.filter.beans;
import java.io.IOException;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
/**
* A filter that will use the HttpSession (if it exists) as the monitor for a synchronized block so that only one request per session is processed at any time.
*
* Originally created to avoid having to make 200+ JSF session scoped beans thread safe.
*
* @author Alan Davis
* @deprecated 5.0 not exposed in web-client web.xml
*/
public class SessionSynchronizedFilter implements Filter
{
@Override
public void init(FilterConfig arg0) throws ServletException
{}
@Override
public void destroy()
{}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
{
HttpSession session = null;
if (request instanceof HttpServletRequest)
{
session = ((HttpServletRequest) request).getSession(false);
}
if (session != null)
{
synchronized (session)
{
chain.doFilter(request, response);
}
}
else
{
chain.doFilter(request, response);
}
}
}

View File

@@ -25,8 +25,6 @@
*/
package org.alfresco.repo.web.scripts;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mozilla.javascript.ContextFactory;
@@ -34,6 +32,8 @@ import org.mozilla.javascript.tools.debugger.Dim;
import org.mozilla.javascript.tools.debugger.SwingGui;
import org.springframework.extensions.webscripts.ScriptDebugger;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
/**
* Alfresco implementation of Rhino JavaScript debugger
@@ -45,18 +45,17 @@ import org.springframework.extensions.webscripts.ScriptDebugger;
public class AlfrescoRhinoScriptDebugger extends ScriptDebugger
{
private static final Log logger = LogFactory.getLog(AlfrescoRhinoScriptDebugger.class);
// Logger
private ContextFactory factory = null;
private SwingGui gui = null;
@Override
protected void initDebugger()
{
dim = new AlfrescoDim();
}
@Override
public void start()
{
@@ -66,25 +65,23 @@ public class AlfrescoRhinoScriptDebugger extends ScriptDebugger
show();
}
}
@Override
protected String getTitle()
{
return "Alfresco Repository JavaScript Debugger";
}
public static class AlfrescoDim extends Dim
{
/* (non-Javadoc)
* @see org.mozilla.javascript.tools.debugger.Dim#objectToString(java.lang.Object)
*/
*
* @see org.mozilla.javascript.tools.debugger.Dim#objectToString(java.lang.Object) */
@Override
public String objectToString(final Object arg0)
{
// execute command in context of currently selected user
return AuthenticationUtil.runAs(new RunAsWork<String>()
{
return AuthenticationUtil.runAs(new RunAsWork<String>() {
@SuppressWarnings("synthetic-access")
public String doWork() throws Exception
{

View File

@@ -25,13 +25,14 @@
*/
package org.alfresco.repo.web.scripts;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.springframework.extensions.webscripts.servlet.WebScriptServlet;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.springframework.extensions.webscripts.servlet.WebScriptServlet;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
public class AlfrescoWebScriptServlet extends WebScriptServlet
{

View File

@@ -46,7 +46,7 @@ public class BufferedRequest implements WrappingWebScriptRequest, AutoCloseable
private TempOutputStream bufferStream;
private InputStream contentStream;
private BufferedReader contentReader;
public BufferedRequest(WebScriptRequest req, Supplier<TempOutputStream> streamFactory)
{
this.req = req;
@@ -97,8 +97,7 @@ public class BufferedRequest implements WrappingWebScriptRequest, AutoCloseable
contentStream.close();
}
catch (Exception ignore)
{
}
{}
contentStream = null;
}
if (contentReader != null)
@@ -108,8 +107,7 @@ public class BufferedRequest implements WrappingWebScriptRequest, AutoCloseable
contentReader.close();
}
catch (Exception ignore)
{
}
{}
contentReader = null;
}
}
@@ -125,15 +123,14 @@ public class BufferedRequest implements WrappingWebScriptRequest, AutoCloseable
bufferStream.destroy();
}
catch (Exception ignore)
{
}
{}
bufferStream = null;
}
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WrappingWebScriptRequest#getNext()
*/
*
* @see org.springframework.extensions.webscripts.WrappingWebScriptRequest#getNext() */
@Override
public WebScriptRequest getNext()
{
@@ -141,29 +138,31 @@ public class BufferedRequest implements WrappingWebScriptRequest, AutoCloseable
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#forceSuccessStatus()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#forceSuccessStatus() */
@Override
public boolean forceSuccessStatus()
{
return req.forceSuccessStatus();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getAgent()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getAgent() */
@Override
public String getAgent()
{
return req.getAgent();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getContent()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getContent() */
@Override
public Content getContent()
{
final Content wrapped = req.getContent();
return new Content(){
return new Content() {
@Override
public String getContent() throws IOException
@@ -183,13 +182,12 @@ public class BufferedRequest implements WrappingWebScriptRequest, AutoCloseable
return wrapped.getMimetype();
}
@Override
public long getSize()
{
return wrapped.getSize();
}
@Override
public InputStream getInputStream()
{
@@ -228,177 +226,199 @@ public class BufferedRequest implements WrappingWebScriptRequest, AutoCloseable
}
};
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getContentType()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getContentType() */
@Override
public String getContentType()
{
return req.getContentType();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getContextPath()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getContextPath() */
@Override
public String getContextPath()
{
return req.getContextPath();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getExtensionPath()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getExtensionPath() */
@Override
public String getExtensionPath()
{
return req.getExtensionPath();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getFormat()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getFormat() */
@Override
public String getFormat()
{
return req.getFormat();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getFormatStyle()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getFormatStyle() */
@Override
public FormatStyle getFormatStyle()
{
return req.getFormatStyle();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getHeader(java.lang.String)
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getHeader(java.lang.String) */
@Override
public String getHeader(String name)
{
return req.getHeader(name);
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getHeaderNames()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getHeaderNames() */
@Override
public String[] getHeaderNames()
{
return req.getHeaderNames();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getHeaderValues(java.lang.String)
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getHeaderValues(java.lang.String) */
@Override
public String[] getHeaderValues(String name)
{
return req.getHeaderValues(name);
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getJSONCallback()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getJSONCallback() */
@Override
public String getJSONCallback()
{
return req.getJSONCallback();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getParameter(java.lang.String)
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getParameter(java.lang.String) */
@Override
public String getParameter(String name)
{
return req.getParameter(name);
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getParameterNames()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getParameterNames() */
@Override
public String[] getParameterNames()
{
return req.getParameterNames();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getParameterValues(java.lang.String)
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getParameterValues(java.lang.String) */
@Override
public String[] getParameterValues(String name)
{
return req.getParameterValues(name);
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getPathInfo()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getPathInfo() */
@Override
public String getPathInfo()
{
return req.getPathInfo();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getQueryString()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getQueryString() */
@Override
public String getQueryString()
{
return req.getQueryString();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getRuntime()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getRuntime() */
@Override
public Runtime getRuntime()
{
return req.getRuntime();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getServerPath()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getServerPath() */
@Override
public String getServerPath()
{
return req.getServerPath();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getServiceContextPath()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getServiceContextPath() */
@Override
public String getServiceContextPath()
{
return req.getServiceContextPath();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getServiceMatch()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getServiceMatch() */
@Override
public Match getServiceMatch()
{
return req.getServiceMatch();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getServicePath()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getServicePath() */
@Override
public String getServicePath()
{
return req.getServicePath();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#getURL()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#getURL() */
@Override
public String getURL()
{
return req.getURL();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#isGuest()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#isGuest() */
@Override
public boolean isGuest()
{
return req.isGuest();
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptRequest#parseContent()
*/
*
* @see org.springframework.extensions.webscripts.WebScriptRequest#parseContent() */
@Override
public Object parseContent()
{

View File

@@ -30,7 +30,6 @@ import java.io.OutputStream;
import java.io.Writer;
import java.util.function.Supplier;
import org.alfresco.error.AlfrescoRuntimeException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.StringBuilderWriter;
@@ -40,6 +39,8 @@ import org.springframework.extensions.webscripts.WebScriptResponse;
import org.springframework.extensions.webscripts.WrappingWebScriptResponse;
import org.springframework.util.FileCopyUtils;
import org.alfresco.error.AlfrescoRuntimeException;
/**
* Transactional Buffered Response
*/
@@ -57,8 +58,10 @@ public class BufferedResponse implements WrappingWebScriptResponse, AutoCloseabl
/**
* Construct
*
* @param res WebScriptResponse
* @param bufferSize int
* @param res
* WebScriptResponse
* @param bufferSize
* int
*/
public BufferedResponse(WebScriptResponse res, int bufferSize, Supplier<TempOutputStream> streamFactory)
{
@@ -67,63 +70,58 @@ public class BufferedResponse implements WrappingWebScriptResponse, AutoCloseabl
this.streamFactory = streamFactory;
}
/*
* (non-Javadoc)
* @see org.alfresco.web.scripts.WrappingWebScriptResponse#getNext()
*/
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.WrappingWebScriptResponse#getNext() */
@Override
public WebScriptResponse getNext()
{
return res;
}
/*
* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#addHeader(java.lang.String, java.lang.String)
*/
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.WebScriptResponse#addHeader(java.lang.String, java.lang.String) */
public void addHeader(String name, String value)
{
res.addHeader(name, value);
}
/*
* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#encodeScriptUrl(java.lang.String)
*/
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.WebScriptResponse#encodeScriptUrl(java.lang.String) */
public String encodeScriptUrl(String url)
{
return res.encodeScriptUrl(url);
}
/*
* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#getEncodeScriptUrlFunction(java.lang.String)
*/
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.WebScriptResponse#getEncodeScriptUrlFunction(java.lang.String) */
public String getEncodeScriptUrlFunction(String name)
{
return res.getEncodeScriptUrlFunction(name);
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptResponse#encodeResourceUrl(java.lang.String)
*/
*
* @see org.springframework.extensions.webscripts.WebScriptResponse#encodeResourceUrl(java.lang.String) */
public String encodeResourceUrl(String url)
{
return res.encodeResourceUrl(url);
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.WebScriptResponse#getEncodeResourceUrlFunction(java.lang.String)
*/
*
* @see org.springframework.extensions.webscripts.WebScriptResponse#getEncodeResourceUrlFunction(java.lang.String) */
public String getEncodeResourceUrlFunction(String name)
{
return res.getEncodeResourceUrlFunction(name);
}
/*
* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#getOutputStream()
*/
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.WebScriptResponse#getOutputStream() */
@Override
public OutputStream getOutputStream() throws IOException
{
@@ -139,19 +137,17 @@ public class BufferedResponse implements WrappingWebScriptResponse, AutoCloseabl
return outputStream;
}
/*
* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#getRuntime()
*/
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.WebScriptResponse#getRuntime() */
public Runtime getRuntime()
{
return res.getRuntime();
}
/*
* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#getWriter()
*/
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.WebScriptResponse#getWriter() */
public Writer getWriter() throws IOException
{
if (outputWriter != null)
@@ -166,10 +162,9 @@ public class BufferedResponse implements WrappingWebScriptResponse, AutoCloseabl
return outputWriter;
}
/*
* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#reset()
*/
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.WebScriptResponse#reset() */
public void reset()
{
if (outputStream != null)
@@ -184,8 +179,8 @@ public class BufferedResponse implements WrappingWebScriptResponse, AutoCloseabl
}
/* (non-Javadoc)
* @see org./alfresco.web.scripts.WebScriptResponse#resetjava.lang.String)
*/
*
* @see org./alfresco.web.scripts.WebScriptResponse#resetjava.lang.String) */
public void reset(String preserveHeadersPattern)
{
if (outputStream != null)
@@ -199,46 +194,41 @@ public class BufferedResponse implements WrappingWebScriptResponse, AutoCloseabl
res.reset(preserveHeadersPattern);
}
/*
* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#setCache(org.alfresco.web.scripts.Cache)
*/
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.WebScriptResponse#setCache(org.alfresco.web.scripts.Cache) */
public void setCache(Cache cache)
{
res.setCache(cache);
}
/*
* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#setContentType(java.lang.String)
*/
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.WebScriptResponse#setContentType(java.lang.String) */
public void setContentType(String contentType)
{
res.setContentType(contentType);
}
/*
* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#setContentEncoding(java.lang.String)
*/
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.WebScriptResponse#setContentEncoding(java.lang.String) */
public void setContentEncoding(String contentEncoding)
{
res.setContentEncoding(contentEncoding);
}
/*
* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#setHeader(java.lang.String, java.lang.String)
*/
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.WebScriptResponse#setHeader(java.lang.String, java.lang.String) */
public void setHeader(String name, String value)
{
res.setHeader(name, value);
}
/*
* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptResponse#setStatus(int)
*/
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.WebScriptResponse#setStatus(int) */
public void setStatus(int status)
{
res.setStatus(status);
@@ -255,7 +245,7 @@ public class BufferedResponse implements WrappingWebScriptResponse, AutoCloseabl
{
logger.debug("Writing Transactional response: size=" + outputStream.getLength());
}
if (outputWriter != null)
{
outputWriter.flush();
@@ -285,8 +275,7 @@ public class BufferedResponse implements WrappingWebScriptResponse, AutoCloseabl
outputStream.destroy();
}
catch (Exception ignore)
{
}
{}
outputStream = null;
}
}

View File

@@ -35,13 +35,8 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
@@ -59,10 +54,14 @@ import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
/**
* Parent of Declarative Webscripts that generate Excel files,
* usually based on some sort of dictionary model.
* Parent of Declarative Webscripts that generate Excel files, usually based on some sort of dictionary model.
*
* @author Nick Burch
*/
@@ -71,63 +70,59 @@ public abstract class DeclarativeSpreadsheetWebScript extends DeclarativeWebScri
public static final String MODEL_CSV = "csv";
public static final String MODEL_EXCEL = "excel";
public static final String PARAM_REQ_DELIMITER = "delimiter";
private CSVFormat csvFormat;
protected DictionaryService dictionaryService;
protected String filenameBase;
/**
* @param dictionaryService the DictionaryService to set
* @param dictionaryService
* the DictionaryService to set
*/
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
/**
* Identifies the resource for the webscript.
*/
protected abstract Object identifyResource(String format, WebScriptRequest req);
/**
* If the format is requested as HTML, should an exception be raised,
* or should an HTML version be called?
* If the format is requested as HTML, should an exception be raised, or should an HTML version be called?
*/
protected abstract boolean allowHtmlFallback();
protected abstract boolean allowHtmlFallback();
/**
* Returns the QNames of the model properties to be output in
* the header, and if they're required or not
* Returns the QNames of the model properties to be output in the header, and if they're required or not
*/
protected abstract List<Pair<QName, Boolean>> buildPropertiesForHeader(Object resource, String format, WebScriptRequest req);
/**
* Populates the body of the Excel Workbook, once the header has been
* output.
* This is called if the format is .xls or .xlsx
* Populates the body of the Excel Workbook, once the header has been output. This is called if the format is .xls or .xlsx
*/
protected abstract void populateBody(Object resource, Workbook workbook, Sheet sheet, List<QName> properties)
throws IOException;
throws IOException;
/**
* Populates the body of the CSV file, once the header has been
* output.
* This is called if the format is .csv
* Populates the body of the CSV file, once the header has been output. This is called if the format is .csv
*/
protected abstract void populateBody(Object resource, CSVPrinter csv, List<QName> properties)
throws IOException;
throws IOException;
/**
* Set the CSVFormat
*
* @param csvFormat CSVFormat
* @param csvFormat
* CSVFormat
*/
public void setCsvFormat(CSVFormat csvFormat)
{
this.csvFormat = csvFormat;
}
/**
* Get the CSVFormat. Returns {@link CSVFormat#EXCEL} if none was set.
*
@@ -147,7 +142,7 @@ public abstract class DeclarativeSpreadsheetWebScript extends DeclarativeWebScri
return csvFormat;
}
}
/**
* @see org.springframework.extensions.webscripts.DeclarativeWebScript#executeImpl(org.springframework.extensions.webscripts.WebScriptRequest, org.springframework.extensions.webscripts.Status)
*/
@@ -156,46 +151,45 @@ public abstract class DeclarativeSpreadsheetWebScript extends DeclarativeWebScri
{
Map<String, Object> model = new HashMap<String, Object>();
model.put("success", Boolean.TRUE);
// What format are they after?
String format = req.getFormat();
if("csv".equals(format) || "xls".equals(format) ||
"xlsx".equals(format) || "excel".equals(format))
if ("csv".equals(format) || "xls".equals(format) ||
"xlsx".equals(format) || "excel".equals(format))
{
// Identify the thing to process
Object resource = identifyResource(format, req);
// Generate the spreadsheet
try
{
generateSpreadsheet(resource, format, req, status, model);
return model;
}
catch(IOException e)
catch (IOException e)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
"Unable to generate template file", e);
}
}
// If we get here, then it isn't a spreadsheet version
if(allowHtmlFallback())
if (allowHtmlFallback())
{
// There's some sort of help / upload form
return model;
// There's some sort of help / upload form
return model;
}
else
{
throw new WebScriptException("Web Script format '" + format + "' is not supported");
throw new WebScriptException("Web Script format '" + format + "' is not supported");
}
}
/**
* Generates the spreadsheet, based on the properties in the header
* and a callback for the body.
* Generates the spreadsheet, based on the properties in the header and a callback for the body.
*/
public void generateSpreadsheet(Object resource, String format, WebScriptRequest req,
Status status, Map<String, Object> model) throws IOException
public void generateSpreadsheet(Object resource, String format, WebScriptRequest req,
Status status, Map<String, Object> model) throws IOException
{
Pattern qnameMunger = Pattern.compile("([A-Z][a-z]+)([A-Z].*)");
String delimiterParam = req.getParameter(PARAM_REQ_DELIMITER);
@@ -204,10 +198,10 @@ public abstract class DeclarativeSpreadsheetWebScript extends DeclarativeWebScri
if (delimiterParam != null && !delimiterParam.isEmpty())
{
reqCSVFormat = CSVFormat.EXCEL
.withDelimiter(delimiterParam.charAt(0))
.withQuote('"')
.withRecordSeparator("\n")
.withFirstRecordAsHeader();
.withDelimiter(delimiterParam.charAt(0))
.withQuote('"')
.withRecordSeparator("\n")
.withFirstRecordAsHeader();
}
// Build up the details of the header
@@ -215,10 +209,10 @@ public abstract class DeclarativeSpreadsheetWebScript extends DeclarativeWebScri
String[] headings = new String[propertyDetails.size()];
String[] descriptions = new String[propertyDetails.size()];
boolean[] required = new boolean[propertyDetails.size()];
for(int i=0; i<headings.length; i++)
for (int i = 0; i < headings.length; i++)
{
Pair<QName, Boolean> property = propertyDetails.get(i);
if(property == null || property.getFirst() == null)
Pair<QName, Boolean> property = propertyDetails.get(i);
if (property == null || property.getFirst() == null)
{
headings[i] = "";
required[i] = false;
@@ -227,10 +221,10 @@ public abstract class DeclarativeSpreadsheetWebScript extends DeclarativeWebScri
{
QName column = property.getFirst();
required[i] = property.getSecond();
// Ask the dictionary service nicely for the details
PropertyDefinition pd = dictionaryService.getProperty(column);
if(pd != null && pd.getTitle(dictionaryService) != null)
if (pd != null && pd.getTitle(dictionaryService) != null)
{
// Use the friendly titles, which may even be localised!
headings[i] = pd.getTitle(dictionaryService);
@@ -239,12 +233,12 @@ public abstract class DeclarativeSpreadsheetWebScript extends DeclarativeWebScri
else
{
// Nothing friendly found, try to munge the raw qname into
// something we can show to a user...
// something we can show to a user...
String raw = column.getLocalName();
raw = raw.substring(0, 1).toUpperCase() + raw.substring(1);
Matcher m = qnameMunger.matcher(raw);
if(m.matches())
if (m.matches())
{
headings[i] = m.group(1) + " " + m.group(2);
}
@@ -255,34 +249,34 @@ public abstract class DeclarativeSpreadsheetWebScript extends DeclarativeWebScri
}
}
}
// Build a list of just the properties
List<QName> properties = new ArrayList<QName>(propertyDetails.size());
for(Pair<QName,Boolean> p : propertyDetails)
for (Pair<QName, Boolean> p : propertyDetails)
{
QName qn = null;
if(p != null)
{
qn = p.getFirst();
}
properties.add(qn);
QName qn = null;
if (p != null)
{
qn = p.getFirst();
}
properties.add(qn);
}
// Output
if("csv".equals(format))
if ("csv".equals(format))
{
StringWriter sw = new StringWriter();
CSVPrinter csv = new CSVPrinter(sw, reqCSVFormat != null ? reqCSVFormat : getCsvFormat());
csv.printRecord(headings);
populateBody(resource, csv, properties);
model.put(MODEL_CSV, sw.toString());
}
else
{
Workbook wb;
if("xlsx".equals(format))
if ("xlsx".equals(format))
{
wb = new XSSFWorkbook();
// TODO Properties
@@ -292,61 +286,61 @@ public abstract class DeclarativeSpreadsheetWebScript extends DeclarativeWebScri
wb = new HSSFWorkbook();
// TODO Properties
}
// Add our header row
Sheet sheet = wb.createSheet("Export");
Row hr = sheet.createRow(0);
sheet.createFreezePane(0, 1);
Font fb = wb.createFont();
fb.setBold(true);
Font fi = wb.createFont();
fi.setBold(true);
fi.setItalic(true);
CellStyle csReq = wb.createCellStyle();
csReq.setFont(fb);
CellStyle csOpt = wb.createCellStyle();
csOpt.setFont(fi);
// Populate the header
Drawing draw = null;
for(int i=0; i<headings.length; i++)
for (int i = 0; i < headings.length; i++)
{
Cell c = hr.createCell(i);
c.setCellValue(headings[i]);
if(required[i])
if (required[i])
{
c.setCellStyle(csReq);
c.setCellStyle(csReq);
}
else
{
c.setCellStyle(csOpt);
c.setCellStyle(csOpt);
}
if(headings[i].length() == 0)
if (headings[i].length() == 0)
{
sheet.setColumnWidth(i, 3*250);
sheet.setColumnWidth(i, 3 * 250);
}
else
{
sheet.setColumnWidth(i, 18*250);
sheet.setColumnWidth(i, 18 * 250);
}
if(descriptions[i] != null && descriptions[i].length() > 0)
if (descriptions[i] != null && descriptions[i].length() > 0)
{
// Add a description for it too
if(draw == null)
if (draw == null)
{
draw = sheet.createDrawingPatriarch();
}
ClientAnchor ca = wb.getCreationHelper().createClientAnchor();
ca.setCol1(c.getColumnIndex());
ca.setCol2(c.getColumnIndex()+1);
ca.setCol2(c.getColumnIndex() + 1);
ca.setRow1(hr.getRowNum());
ca.setRow2(hr.getRowNum()+2);
ca.setRow2(hr.getRowNum() + 2);
Comment cmt = draw.createCellComment(ca);
cmt.setAuthor("");
cmt.setString(wb.getCreationHelper().createRichTextString(descriptions[i]));
@@ -354,10 +348,10 @@ public abstract class DeclarativeSpreadsheetWebScript extends DeclarativeWebScri
c.setCellComment(cmt);
}
}
// Have the contents populated
populateBody(resource, wb, sheet, properties);
// Save it for the template
ByteArrayOutputStream baos = new ByteArrayOutputStream();
wb.write(baos);
@@ -370,19 +364,20 @@ public abstract class DeclarativeSpreadsheetWebScript extends DeclarativeWebScri
Map<String, Object> customParams)
{
Map<String, Object> model = super.createTemplateParameters(req, res, customParams);
// We sometimes need to monkey around to do the binary output...
// We sometimes need to monkey around to do the binary output...
model.put("req", req);
model.put("res", res);
model.put("writeExcel", new WriteExcel(res, model, req.getFormat(), filenameBase));
return model;
}
public static class WriteExcel
public static class WriteExcel
{
private String format;
private String filenameBase;
private WebScriptResponse res;
private Map<String, Object> model;
private WriteExcel(WebScriptResponse res, Map<String, Object> model, String format, String filenameBase)
{
this.res = res;
@@ -390,36 +385,39 @@ public abstract class DeclarativeSpreadsheetWebScript extends DeclarativeWebScri
this.format = format;
this.filenameBase = filenameBase;
}
public void write() throws IOException
{
String filename = filenameBase + "." + format;
// If it isn't a CSV, reset so we can send binary
if(! "csv".equals(format))
if (!"csv".equals(format))
{
res.reset();
}
// Tell the browser it's a file download
res.addHeader("Content-Disposition", "attachment; filename=" + filename);
// Now send that data
if("csv".equals(format))
if ("csv".equals(format))
{
res.getWriter().append((String)model.get(MODEL_CSV));
res.getWriter().append((String) model.get(MODEL_CSV));
}
else
{
// Set the mimetype, as we've reset
if("xlsx".equals(format))
if ("xlsx".equals(format))
{
res.setContentType(MimetypeMap.MIMETYPE_OPENXML_SPREADSHEET);
} else {
}
else
{
res.setContentType(MimetypeMap.MIMETYPE_EXCEL);
}
// Send the raw excel bytes
byte[] excel = (byte[])model.get(MODEL_EXCEL);
byte[] excel = (byte[]) model.get(MODEL_EXCEL);
res.getOutputStream().write(excel);
}
}

View File

@@ -25,82 +25,50 @@
*/
package org.alfresco.repo.web.scripts;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Element;
import org.springframework.extensions.config.ConfigImpl;
import org.springframework.extensions.config.ConfigSection;
import org.springframework.extensions.config.ConfigService;
import org.springframework.extensions.config.evaluator.Evaluator;
import org.springframework.extensions.config.xml.XMLConfigService;
import org.springframework.extensions.config.xml.elementreader.ConfigElementReader;
import org.springframework.extensions.surf.extensibility.BasicExtensionModule;
import org.springframework.extensions.surf.extensibility.ExtensibilityModel;
import org.springframework.extensions.surf.extensibility.HandlesExtensibility;
import org.springframework.extensions.surf.extensibility.WebScriptExtensibilityModuleHandler;
import org.springframework.extensions.surf.extensibility.impl.ExtensibilityModelImpl;
import org.springframework.extensions.surf.extensibility.impl.MarkupDirective;
import org.springframework.extensions.webscripts.Authenticator;
import org.springframework.extensions.webscripts.ExtendedScriptConfigModel;
import org.springframework.extensions.webscripts.ExtendedTemplateConfigModel;
import org.springframework.extensions.webscripts.ScriptConfigModel;
import org.springframework.extensions.webscripts.TemplateConfigModel;
import org.springframework.extensions.webscripts.WebScriptPropertyResourceBundle;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
/**
* <p>A simple extensibility {@link org.springframework.extensions.webscripts.Container} for processing WebScripts. This extends the {@link RepositoryContainer} and
* implements the {@link HandlesExtensibility} interface to provide extensibility capabilities.</p>
*
* <p>
* A simple extensibility {@link org.springframework.extensions.webscripts.Container} for processing WebScripts. This extends the {@link RepositoryContainer} and
*
* implements the {@link HandlesExtensibility} interface to provide extensibility capabilities.
* </p>
*
*
*
* @author David Draper
*
*/
public class ExtensibilityContainer extends RepositoryContainer implements HandlesExtensibility
@@ -109,33 +77,31 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
private static final Log logger = LogFactory.getLog(ExtensibilityContainer.class);
public boolean isExtensibilitySuppressed()
{
return false;
return false;
}
/**
* <p>Opens a new {@link ExtensibilityModel}, defers execution to the extended {@link RepositoryContainer} and
* then closes the {@link ExtensibilityModel}.</p>
*
* <p>
* Opens a new {@link ExtensibilityModel}, defers execution to the extended {@link RepositoryContainer} and
*
* then closes the {@link ExtensibilityModel}.
* </p>
*
*/
@Override
public void executeScript(WebScriptRequest scriptReq,
public void executeScript(WebScriptRequest scriptReq,
WebScriptResponse scriptRes,
WebScriptResponse scriptRes,
Authenticator auth) throws IOException
Authenticator auth) throws IOException
{
@@ -187,42 +153,43 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
}
/**
* <p>This keeps track of whether or not the {@link ExtensibilityModel} for the current thread has been used. The
*
* <p>
* This keeps track of whether or not the {@link ExtensibilityModel} for the current thread has been used. The
*
* thread local value will only be set to <code>true</code> if the <code>getCurrentExtensibilityModel</code> method
* is called.</p>
*
* is called.
* </p>
*
*/
private ThreadLocal<Boolean> modelUsed = new ThreadLocal<Boolean>();
/**
* <p>A {@link WebScriptExtensibilityModuleHandler} is required for retrieving information on what
* {@link BasicExtensionModule} instances have been configured and the extension files that need
* to be processed. This variable should be set thorugh the Spring application context configuration.</p>
*
* <p>
* A {@link WebScriptExtensibilityModuleHandler} is required for retrieving information on what
*
* {@link BasicExtensionModule} instances have been configured and the extension files that need
*
* to be processed. This variable should be set thorugh the Spring application context configuration.
* </p>
*
*/
private WebScriptExtensibilityModuleHandler extensibilityModuleHandler = null;
/**
* <p>Sets the {@link WebScriptExtensibilityModuleHandler} for this {@link org.springframework.extensions.webscripts.Container}.</p>
* @param extensibilityModuleHandler WebScriptExtensibilityModuleHandler
*
* <p>
* Sets the {@link WebScriptExtensibilityModuleHandler} for this {@link org.springframework.extensions.webscripts.Container}.
* </p>
*
* @param extensibilityModuleHandler
* WebScriptExtensibilityModuleHandler
*
*/
public void setExtensibilityModuleHandler(WebScriptExtensibilityModuleHandler extensibilityModuleHandler)
@@ -233,24 +200,24 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
}
/**
* <p>Maintains a list of all the {@link ExtensibilityModel} instances being used across all the
* available threads.</p>
*
* <p>
* Maintains a list of all the {@link ExtensibilityModel} instances being used across all the
*
* available threads.
* </p>
*
*/
private ThreadLocal<ExtensibilityModel> extensibilityModel = new ThreadLocal<ExtensibilityModel>();
/**
* <p>Creates a new {@link ExtensibilityModel} and sets it on the current thread</p>
*
* <p>
* Creates a new {@link ExtensibilityModel} and sets it on the current thread
* </p>
*
*/
public ExtensibilityModel openExtensibilityModel()
@@ -277,11 +244,9 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
this.sectionsByArea.set(null);
ExtensibilityModel model = new ExtensibilityModelImpl(null, this);
this.extensibilityModel.set(model);
this.extensibilityModel.set(model);
this.modelUsed.set(Boolean.FALSE);
@@ -289,14 +254,14 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
}
/**
* <p>Flushes the {@link ExtensibilityModel} provided and sets its parent as the current {@link ExtensibilityModel}
* for the current thread.</p>
*
* <p>
* Flushes the {@link ExtensibilityModel} provided and sets its parent as the current {@link ExtensibilityModel}
*
* for the current thread.
* </p>
*
*/
public void closeExtensibilityModel(ExtensibilityModel model, Writer out)
@@ -311,8 +276,6 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
}
model.flushModel(out);
this.modelUsed.set(Boolean.FALSE);
@@ -321,12 +284,12 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
}
/**
* <p>Returns the {@link ExtensibilityModel} for the current thread.</p>
*
* <p>
* Returns the {@link ExtensibilityModel} for the current thread.
* </p>
*
*/
public ExtensibilityModel getCurrentExtensibilityModel()
@@ -347,14 +310,14 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
}
/**
* <p>This method is implemented to perform no action as it is not necessary for a standalone WebScript
* container to add dependencies for processing.</p>
*
* <p>
* This method is implemented to perform no action as it is not necessary for a standalone WebScript
*
* container to add dependencies for processing.
* </p>
*
*/
public void updateExtendingModuleDependencies(String pathBeingProcessed, Map<String, Object> model)
@@ -365,32 +328,33 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
}
/**
* <p>A thread-safe cache of extended {@link ResourceBundle} instances for the current request.</p>
*
* <p>
* A thread-safe cache of extended {@link ResourceBundle} instances for the current request.
* </p>
*
*/
private ThreadLocal<Map<String, WebScriptPropertyResourceBundle>> extendedBundleCache = new ThreadLocal<Map<String, WebScriptPropertyResourceBundle>>();
private ThreadLocal<Map<String, WebScriptPropertyResourceBundle>> extendedBundleCache = new ThreadLocal<Map<String, WebScriptPropertyResourceBundle>>();
/**
* <p>Checks the cache to see if it has cached an extended bundle (that is a basic {@link ResourceBundle} that
* has had extension modules applied to it. Extended bundles can only be safely cached once per request as the modules
* applied can vary for each request.</p>
*
* @param webScriptId The id of the WebScript to retrieve the extended bundle for.
* <p>
* Checks the cache to see if it has cached an extended bundle (that is a basic {@link ResourceBundle} that
*
* has had extension modules applied to it. Extended bundles can only be safely cached once per request as the modules
*
* applied can vary for each request.
* </p>
*
*
*
* @param webScriptId
* The id of the WebScript to retrieve the extended bundle for.
*
* @return A cached bundle or <code>null</code> if the bundle has not previously been cached.
*
*/
public ResourceBundle getCachedExtendedBundle(String webScriptId)
@@ -413,22 +377,24 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
}
/**
* <p>Adds a new extended bundle to the cache. An extended bundle is a WebScript {@link ResourceBundle} that has had
* {@link ResourceBundle} instances merged into it from extension modules that have been applied. These can only be cached
* for the lifetime of the request as different modules may be applied to the same WebScript for different requests.</p>
*
* @param webScriptId The id of the WebScript to cache the extended bundle against.
* @param extensionBundle The extended bundle to cache.
* <p>
* Adds a new extended bundle to the cache. An extended bundle is a WebScript {@link ResourceBundle} that has had
*
* {@link ResourceBundle} instances merged into it from extension modules that have been applied. These can only be cached
*
* for the lifetime of the request as different modules may be applied to the same WebScript for different requests.
* </p>
*
*
*
* @param webScriptId
* The id of the WebScript to cache the extended bundle against.
*
* @param extensionBundle
* The extended bundle to cache.
*
*/
public void addExtensionBundleToCache(String webScriptId, WebScriptPropertyResourceBundle extensionBundle)
@@ -455,28 +421,28 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
}
/**
* <p>A {@link ThreadLocal} reference to the file currently being processed in the model.</p>
*
* <p>
* A {@link ThreadLocal} reference to the file currently being processed in the model.
* </p>
*
*/
private ThreadLocal<String> fileBeingProcessed = new ThreadLocal<String>();
/**
* <p>Returns the path of the file currently being processed in the model by the current thread.
* This information is primarily provided for the purposes of generating debug information.</p>
*
* <p>
* Returns the path of the file currently being processed in the model by the current thread.
*
* This information is primarily provided for the purposes of generating debug information.
* </p>
*
*
*
* @return The path of the file currently being processed.
*
*/
public String getFileBeingProcessed()
@@ -487,16 +453,17 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
}
/**
* <p>Sets the path of the file currently being processed in the model by the current thread.
* This information should be collected to assist with providing debug information.</p>
* @param file The path of the file currently being processed.
*
* <p>
* Sets the path of the file currently being processed in the model by the current thread.
*
* This information should be collected to assist with providing debug information.
* </p>
*
* @param file
* The path of the file currently being processed.
*
*/
public void setFileBeingProcessed(String file)
@@ -507,12 +474,12 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
}
/**
* <p>Retrieves an files for the evaluated modules that are extending the WebScript files being processed.</p>
*
* <p>
* Retrieves an files for the evaluated modules that are extending the WebScript files being processed.
* </p>
*
*/
public List<String> getExtendingModuleFiles(String pathBeingProcessed)
@@ -521,7 +488,7 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
List<String> extendingModuleFiles = new ArrayList<String>();
for (BasicExtensionModule module: this.getEvaluatedModules())
for (BasicExtensionModule module : this.getEvaluatedModules())
{
@@ -533,36 +500,36 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
}
/**
* <p>The list of {@link org.springframework.extensions.surf.types.ExtensionModule} instances that have been evaluated as applicable to
*
* <p>
* The list of {@link org.springframework.extensions.surf.types.ExtensionModule} instances that have been evaluated as applicable to
*
* this RequestContext. This is set to <code>null</code> when during instantiation and is only
*
* properly set the first time the <code>getEvaluatedModules</code> method is invoked. This ensures
* that module evaluation only occurs once per request.</p>
*
* that module evaluation only occurs once per request.
* </p>
*
*/
private ThreadLocal<List<BasicExtensionModule>> evaluatedModules = new ThreadLocal<List<BasicExtensionModule>>();
/**
* <p>Retrieve the list of {@link org.springframework.extensions.surf.types.ExtensionModule} instances that have been evaluated as applicable
* for the current request. If this list has not yet been populated then use the {@link org.springframework.extensions.surf.extensibility.ExtensibilityModuleHandler}
* configured in the Spring application context to evaluate them.</p>
*
* <p>
* Retrieve the list of {@link org.springframework.extensions.surf.types.ExtensionModule} instances that have been evaluated as applicable
*
* for the current request. If this list has not yet been populated then use the {@link org.springframework.extensions.surf.extensibility.ExtensibilityModuleHandler}
*
* configured in the Spring application context to evaluate them.
* </p>
*
*
*
* @return A list of {@link org.springframework.extensions.surf.types.ExtensionModule} instances that are applicable to the current request.
*
*/
public List<BasicExtensionModule> getEvaluatedModules()
@@ -609,70 +576,70 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
}
/**
* <p>This is a local {@link ConfigImpl} instance that will only be used when extension modules are employed. It will
*
* <p>
* This is a local {@link ConfigImpl} instance that will only be used when extension modules are employed. It will
*
* initially be populated with the default "static" global configuration taken from the {@link ConfigService} associated
*
* with this {@link org.springframework.extensions.surf.RequestContext} but then updated to include global configuration provided by extension modules that
* have been evaluated to be applied to the current request.</p>
*
* have been evaluated to be applied to the current request.
* </p>
*
*/
private ThreadLocal<ConfigImpl> globalConfig = new ThreadLocal<ConfigImpl>();
/**
* <p>This map represents {@link ConfigSection} instances mapped by area. It will only be used when extension modules are
*
* <p>
* This map represents {@link ConfigSection} instances mapped by area. It will only be used when extension modules are
*
* employed. It will initially be populated with the default "static" configuration taken from the {@link ConfigService} associated
*
* with this {@link org.springframework.extensions.surf.RequestContext} but then updated to include configuration provided by extension modules that have been evaluated
* to be applied to the current request.</p>
*
* to be applied to the current request.
* </p>
*
*/
private ThreadLocal<Map<String, List<ConfigSection>>> sectionsByArea = new ThreadLocal<Map<String,List<ConfigSection>>>();
private ThreadLocal<Map<String, List<ConfigSection>>> sectionsByArea = new ThreadLocal<Map<String, List<ConfigSection>>>();
/**
* <p>A list of {@link ConfigSection} instances that are only applicable to the current request. It will only be used when extension modules are
*
* <p>
* A list of {@link ConfigSection} instances that are only applicable to the current request. It will only be used when extension modules are
*
* employed. It will initially be populated with the default "static" configuration taken from the {@link ConfigService} associated
*
* with this {@link org.springframework.extensions.surf.RequestContext} but then updated to include configuration provided by extension modules that have been evaluated
* to be applied to the current request.</p>
*
* to be applied to the current request.
* </p>
*
*/
private ThreadLocal<List<ConfigSection>> sections = new ThreadLocal<List<ConfigSection>>();
/**
* <p>Creates a new {@link ExtendedScriptConfigModel} instance using the local configuration generated for this request.
*
* <p>
* Creates a new {@link ExtendedScriptConfigModel} instance using the local configuration generated for this request.
*
* If configuration for the request will be generated if it does not yet exist. It is likely that this method will be
*
* called multiple times within the context of a single request and although the configuration containers will always
*
* be the same a new {@link ExtendedScriptConfigModel} instance will always be created as the the supplied <code>xmlConfig</code>
*
* string could be different for each call (because each WebScript invoked in the request will supply different
* configuration.</p>
*
* configuration.
* </p>
*
*/
public ScriptConfigModel getExtendedScriptConfigModel(String xmlConfig)
@@ -691,22 +658,22 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
}
/**
* <p>Creates a new {@link TemplateConfigModel} instance using the local configuration generated for this request.
*
* <p>
* Creates a new {@link TemplateConfigModel} instance using the local configuration generated for this request.
*
* If configuration for the request will be generated if it does not yet exist. It is likely that this method will be
*
* called multiple times within the context of a single request and although the configuration containers will always
*
* be the same a new {@link TemplateConfigModel} instance will always be created as the the supplied <code>xmlConfig</code>
*
* string could be different for each call (because each WebScript invoked in the request will supply different
* configuration.</p>
*
* configuration.
* </p>
*
*/
public TemplateConfigModel getExtendedTemplateConfigModel(String xmlConfig)
@@ -725,16 +692,16 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
}
/**
* <p>Creates and populates the request specific configuration container objects (<code>globalConfig</code>, <code>sectionsByArea</code> &
*
* <p>
* Creates and populates the request specific configuration container objects (<code>globalConfig</code>, <code>sectionsByArea</code> &
*
* <code>sections</code> with a combination of the default static configuration (taken from files accessed by the {@link ConfigService}) and
* dynamic configuration taken from extension modules evaluated for the current request. </p>
*
* dynamic configuration taken from extension modules evaluated for the current request.
* </p>
*
*/
private void getConfigExtensions()
@@ -743,13 +710,13 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
// Extended configuration is only possible if config service is an XMLConfigService...
//
//
// ...also, it's only necessary to populate the configuration containers if they have not already been populated. This test should also
// be carried out by the two methods ("getExtendedTemplateConfigModel" & "getExtendedTemplateConfigModel") to prevent duplication
// of effort... but in case other methods attempt to access it we will make these additional tests.
// of effort... but in case other methods attempt to access it we will make these additional tests.
if (getConfigService() instanceof XMLConfigService && this.globalConfig == null && this.sectionsByArea == null && this.sections == null)
@@ -759,24 +726,18 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
XMLConfigService xmlConfigService = (XMLConfigService) getConfigService();
// Get the current configuration from the ConfigService - we don't want to permanently pollute
// the standard configuration with additions from the modules...
this.globalConfig.set(new ConfigImpl((ConfigImpl)xmlConfigService.getGlobalConfig())); // Make a copy of the current global config
this.globalConfig.set(new ConfigImpl((ConfigImpl) xmlConfigService.getGlobalConfig())); // Make a copy of the current global config
// Initialise these with the config service values...
this.sectionsByArea.set(new HashMap<String, List<ConfigSection>>(xmlConfigService.getSectionsByArea()));
this.sectionsByArea.set(new HashMap<String, List<ConfigSection>>(xmlConfigService.getSectionsByArea()));
this.sections.set(new ArrayList<ConfigSection>(xmlConfigService.getSections()));
// Check to see if there are any modules that we need to apply...
List<BasicExtensionModule> evaluatedModules = this.getEvaluatedModules();
@@ -785,11 +746,11 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
{
for (BasicExtensionModule currModule: evaluatedModules)
for (BasicExtensionModule currModule : evaluatedModules)
{
for (Element currentConfigElement: currModule.getConfigurations())
for (Element currentConfigElement : currModule.getConfigurations())
{
@@ -801,8 +762,6 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
List<ConfigSection> parsedConfigSections = new ArrayList<ConfigSection>();
// Parse and process the parses configuration...
String currentArea = xmlConfigService.parseFragment(currentConfigElement, parsedElementReaders, parsedEvaluators, parsedConfigSections);
@@ -847,12 +806,12 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
}
/**
* <p>Adds the <{@code}@markup> directive to the container which allows FreeMarker templates to be extended.</p>
*
* <p>
* Adds the <{@code}@markup> directive to the container which allows FreeMarker templates to be extended.
* </p>
*
*/
public void addExtensibilityDirectives(Map<String, Object> freeMarkerModel, ExtensibilityModel extModel)
@@ -866,4 +825,3 @@ public class ExtensibilityContainer extends RepositoryContainer implements Handl
}
}

View File

@@ -1,138 +1,146 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts;
import java.util.HashMap;
import java.util.Map;
import jakarta.servlet.ServletContext;
import org.alfresco.api.AlfrescoPublicApi;
import org.alfresco.service.cmr.repository.FileTypeImageSize;
/**
* Contains utility methods
*
* @author Roy Wetherall
*/
@AlfrescoPublicApi
public class FileTypeImageUtils
{
private static final String IMAGE_PREFIX16 = "/images/filetypes/";
private static final String IMAGE_PREFIX32 = "/images/filetypes32/";
private static final String IMAGE_PREFIX64 = "/images/filetypes64/";
private static final String IMAGE_POSTFIX_GIF = ".gif";
private static final String IMAGE_POSTFIX_PNG = ".png";
private static final String DEFAULT_FILE_IMAGE16 = IMAGE_PREFIX16 + "_default" + IMAGE_POSTFIX_GIF;
private static final String DEFAULT_FILE_IMAGE32 = IMAGE_PREFIX32 + "_default" + IMAGE_POSTFIX_GIF;
private static final String DEFAULT_FILE_IMAGE64 = IMAGE_PREFIX64 + "_default" + IMAGE_POSTFIX_PNG;
private static final Map<String, String> s_fileExtensionMap = new HashMap<String, String>(89, 1.0f);
/**
* Return the image path to the filetype icon for the specified file name string
*
* @param sc ServletContext
* @param name File name to build filetype icon path for
* @param small True for the small 16x16 icon or false for the large 32x32
*
* @return the image path for the specified node type or the default icon if not found
*/
public static String getFileTypeImage(ServletContext sc, String name, boolean small)
{
return getFileTypeImage(sc, name, (small ? FileTypeImageSize.Small : FileTypeImageSize.Medium));
}
/**
* Return the image path to the filetype icon for the specified file name string
*
* @param sc ServletContext
* @param name File name to build filetype icon path for
* @param size Size of the icon to return
*
* @return the image path for the specified node type or the default icon if not found
*/
public static String getFileTypeImage(ServletContext sc, String name, FileTypeImageSize size)
{
String image = null;
String defaultImage = null;
switch (size)
{
case Small:
defaultImage = DEFAULT_FILE_IMAGE16; break;
case Medium:
defaultImage = DEFAULT_FILE_IMAGE32; break;
case Large:
defaultImage = DEFAULT_FILE_IMAGE64; break;
}
int extIndex = name.lastIndexOf('.');
if (extIndex != -1 && name.length() > extIndex + 1)
{
String ext = name.substring(extIndex + 1).toLowerCase();
String key = ext + ' ' + size.toString();
// found file extension for appropriate size image
synchronized (s_fileExtensionMap)
{
image = s_fileExtensionMap.get(key);
if (image == null)
{
// not found create for first time
if (size != FileTypeImageSize.Large)
{
image = (size == FileTypeImageSize.Small ? IMAGE_PREFIX16 : IMAGE_PREFIX32) +
ext + IMAGE_POSTFIX_GIF;
}
else
{
image = IMAGE_PREFIX64 + ext + IMAGE_POSTFIX_PNG;
}
// does this image exist on the web-server?
if (sc != null && sc.getResourceAsStream(image) != null)
{
// found the image for this extension - save it for later
s_fileExtensionMap.put(key, image);
}
else if (sc == null)
{
// we have no ServerContext so return the default image but don't cache it
image = defaultImage;
}
else
{
// not found, save the default image for this extension instead
s_fileExtensionMap.put(key, defaultImage);
image = defaultImage;
}
}
}
}
return (image != null ? image : defaultImage);
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts;
import java.util.HashMap;
import java.util.Map;
import jakarta.servlet.ServletContext;
import org.alfresco.api.AlfrescoPublicApi;
import org.alfresco.service.cmr.repository.FileTypeImageSize;
/**
* Contains utility methods
*
* @author Roy Wetherall
*/
@AlfrescoPublicApi
public class FileTypeImageUtils
{
private static final String IMAGE_PREFIX16 = "/images/filetypes/";
private static final String IMAGE_PREFIX32 = "/images/filetypes32/";
private static final String IMAGE_PREFIX64 = "/images/filetypes64/";
private static final String IMAGE_POSTFIX_GIF = ".gif";
private static final String IMAGE_POSTFIX_PNG = ".png";
private static final String DEFAULT_FILE_IMAGE16 = IMAGE_PREFIX16 + "_default" + IMAGE_POSTFIX_GIF;
private static final String DEFAULT_FILE_IMAGE32 = IMAGE_PREFIX32 + "_default" + IMAGE_POSTFIX_GIF;
private static final String DEFAULT_FILE_IMAGE64 = IMAGE_PREFIX64 + "_default" + IMAGE_POSTFIX_PNG;
private static final Map<String, String> s_fileExtensionMap = new HashMap<String, String>(89, 1.0f);
/**
* Return the image path to the filetype icon for the specified file name string
*
* @param sc
* ServletContext
* @param name
* File name to build filetype icon path for
* @param small
* True for the small 16x16 icon or false for the large 32x32
*
* @return the image path for the specified node type or the default icon if not found
*/
public static String getFileTypeImage(ServletContext sc, String name, boolean small)
{
return getFileTypeImage(sc, name, (small ? FileTypeImageSize.Small : FileTypeImageSize.Medium));
}
/**
* Return the image path to the filetype icon for the specified file name string
*
* @param sc
* ServletContext
* @param name
* File name to build filetype icon path for
* @param size
* Size of the icon to return
*
* @return the image path for the specified node type or the default icon if not found
*/
public static String getFileTypeImage(ServletContext sc, String name, FileTypeImageSize size)
{
String image = null;
String defaultImage = null;
switch (size)
{
case Small:
defaultImage = DEFAULT_FILE_IMAGE16;
break;
case Medium:
defaultImage = DEFAULT_FILE_IMAGE32;
break;
case Large:
defaultImage = DEFAULT_FILE_IMAGE64;
break;
}
int extIndex = name.lastIndexOf('.');
if (extIndex != -1 && name.length() > extIndex + 1)
{
String ext = name.substring(extIndex + 1).toLowerCase();
String key = ext + ' ' + size.toString();
// found file extension for appropriate size image
synchronized (s_fileExtensionMap)
{
image = s_fileExtensionMap.get(key);
if (image == null)
{
// not found create for first time
if (size != FileTypeImageSize.Large)
{
image = (size == FileTypeImageSize.Small ? IMAGE_PREFIX16 : IMAGE_PREFIX32) +
ext + IMAGE_POSTFIX_GIF;
}
else
{
image = IMAGE_PREFIX64 + ext + IMAGE_POSTFIX_PNG;
}
// does this image exist on the web-server?
if (sc != null && sc.getResourceAsStream(image) != null)
{
// found the image for this extension - save it for later
s_fileExtensionMap.put(key, image);
}
else if (sc == null)
{
// we have no ServerContext so return the default image but don't cache it
image = defaultImage;
}
else
{
// not found, save the default image for this extension instead
s_fileExtensionMap.put(key, defaultImage);
image = defaultImage;
}
}
}
}
return (image != null ? image : defaultImage);
}
}

View File

@@ -25,24 +25,27 @@
*/
package org.alfresco.repo.web.scripts;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.springframework.extensions.webscripts.WebScriptRequest;
public class MimeTypeUtil
{
/**
* Get the file mimetype from the file ContentReader, and if its null then set the mimetype to binary by default
* and try to get the correct one from file extension
* Get the file mimetype from the file ContentReader, and if its null then set the mimetype to binary by default and try to get the correct one from file extension
*
*
* @param reader reader of the file in the request
* @param req request relating to the file
* @param mimetypeService MimetypeService
* @param reader
* reader of the file in the request
* @param req
* request relating to the file
* @param mimetypeService
* MimetypeService
*
* @return mimetype of the file as a string
* @return mimetype of the file as a string
*/
public static String determineMimetype(ContentReader reader, WebScriptRequest req, MimetypeService mimetypeService)
{

View File

@@ -23,80 +23,80 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts;
import org.alfresco.repo.cache.AbstractMTAsynchronouslyRefreshedCache;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.util.PropertyCheck;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.extensions.webscripts.Registry;
/**
* Asynchronously refreshed cache for repository webscripts.
* <p/>
* This does not stop gratuitous calls to <i>refresh</i> but will ensure that, once an instance has been created,
* a version of the registry is returned even if it is slighly out of date. This can be changed so that it waits
* for reset but is probably not required.
*
* @author Derek Hulley
* @since 4.2.0
*/
public class RegistryAsynchronouslyRefreshedCache extends AbstractMTAsynchronouslyRefreshedCache<Registry> implements InitializingBean
{
private static Log logger = LogFactory.getLog(RegistryAsynchronouslyRefreshedCache.class);
private ObjectFactory<Registry> registryFactory;
private RetryingTransactionHelper retryingTransactionHelper;
/**
* @param registryFactory factory for web script registries
*/
public void setRegistryFactory(ObjectFactory<Registry> registryFactory)
{
this.registryFactory = registryFactory;
}
/**
* @param retryingTransactionHelper the retryingTransactionHelper to set
*/
public void setRetryingTransactionHelper(RetryingTransactionHelper retryingTransactionHelper)
{
this.retryingTransactionHelper = retryingTransactionHelper;
}
@Override
protected Registry buildCache(final String tenantId)
{
return retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Registry>()
{
@Override
public Registry execute() throws Throwable
{
return doBuildCache(tenantId);
}
}, true, false);
}
/**
* This method is thread safe as per contract of {@link #buildCache(String)}.
*/
private Registry doBuildCache(String tenantId)
{
Registry registry = registryFactory.getObject();
registry.reset();
logger.info("Fetching web script registry for tenant " + tenantId);
return registry;
}
@Override
public void afterPropertiesSet() throws Exception
{
PropertyCheck.mandatory(this, "registryFactory", registryFactory);
PropertyCheck.mandatory(this, "retryingTransactionHelper", retryingTransactionHelper);
super.afterPropertiesSet();
}
}
package org.alfresco.repo.web.scripts;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.extensions.webscripts.Registry;
import org.alfresco.repo.cache.AbstractMTAsynchronouslyRefreshedCache;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.util.PropertyCheck;
/**
* Asynchronously refreshed cache for repository webscripts.
* <p/>
* This does not stop gratuitous calls to <i>refresh</i> but will ensure that, once an instance has been created, a version of the registry is returned even if it is slighly out of date. This can be changed so that it waits for reset but is probably not required.
*
* @author Derek Hulley
* @since 4.2.0
*/
public class RegistryAsynchronouslyRefreshedCache extends AbstractMTAsynchronouslyRefreshedCache<Registry> implements InitializingBean
{
private static Log logger = LogFactory.getLog(RegistryAsynchronouslyRefreshedCache.class);
private ObjectFactory<Registry> registryFactory;
private RetryingTransactionHelper retryingTransactionHelper;
/**
* @param registryFactory
* factory for web script registries
*/
public void setRegistryFactory(ObjectFactory<Registry> registryFactory)
{
this.registryFactory = registryFactory;
}
/**
* @param retryingTransactionHelper
* the retryingTransactionHelper to set
*/
public void setRetryingTransactionHelper(RetryingTransactionHelper retryingTransactionHelper)
{
this.retryingTransactionHelper = retryingTransactionHelper;
}
@Override
protected Registry buildCache(final String tenantId)
{
return retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<Registry>() {
@Override
public Registry execute() throws Throwable
{
return doBuildCache(tenantId);
}
}, true, false);
}
/**
* This method is thread safe as per contract of {@link #buildCache(String)}.
*/
private Registry doBuildCache(String tenantId)
{
Registry registry = registryFactory.getObject();
registry.reset();
logger.info("Fetching web script registry for tenant " + tenantId);
return registry;
}
@Override
public void afterPropertiesSet() throws Exception
{
PropertyCheck.mandatory(this, "registryFactory", registryFactory);
PropertyCheck.mandatory(this, "retryingTransactionHelper", retryingTransactionHelper);
super.afterPropertiesSet();
}
}

View File

@@ -23,60 +23,50 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts;
import java.io.IOException;
import org.springframework.extensions.webscripts.ClassPathStore;
import freemarker.cache.TemplateLoader;
/**
* Extension of the SpringSurf ClassPathStore to ensure that the examination of
* last modified dates on classpath bound resources does not cause a performance
* degredation in REST heavy client applications.
* <p>
* In the repository, due to the possibility of Repository bound resources, all
* WebScript search path lists have the "delay" set to either zero seconds (no delay)
* or something close to that. This means that the FreeMarker template cache is
* always or often requesting the last modified date of a classpath resource - and
* the resources do not change. Note that the /extension classpath store still uses
* the original ClassPathStore. Otherwise all stores can be refreshed as usual via
* the Refresh WebScripts command.
*
* @author Kevin Roast
*/
public class RepoClassPathStore extends ClassPathStore
{
@Override
public TemplateLoader getTemplateLoader()
{
return new ClassPathTemplateLoader();
}
@Override
public long lastModified(String documentPath)
throws IOException
{
return -1L;
}
/**
* Class Path Store implementation of a Template Loader
* <p>
* Retrieves templates either from classes in the class path or classes inside of JAR files
* within the class path
* <p>
* This implementation always returns a fixed last modified date of -1.
*/
private class ClassPathTemplateLoader extends ClassPathStore.ClassPathTemplateLoader
{
/**
* @see freemarker.cache.TemplateLoader#getLastModified(java.lang.Object)
*/
public long getLastModified(Object templateSource)
{
return -1L;
}
}
}
package org.alfresco.repo.web.scripts;
import java.io.IOException;
import freemarker.cache.TemplateLoader;
import org.springframework.extensions.webscripts.ClassPathStore;
/**
* Extension of the SpringSurf ClassPathStore to ensure that the examination of last modified dates on classpath bound resources does not cause a performance degredation in REST heavy client applications.
* <p>
* In the repository, due to the possibility of Repository bound resources, all WebScript search path lists have the "delay" set to either zero seconds (no delay) or something close to that. This means that the FreeMarker template cache is always or often requesting the last modified date of a classpath resource - and the resources do not change. Note that the /extension classpath store still uses the original ClassPathStore. Otherwise all stores can be refreshed as usual via the Refresh WebScripts command.
*
* @author Kevin Roast
*/
public class RepoClassPathStore extends ClassPathStore
{
@Override
public TemplateLoader getTemplateLoader()
{
return new ClassPathTemplateLoader();
}
@Override
public long lastModified(String documentPath)
throws IOException
{
return -1L;
}
/**
* Class Path Store implementation of a Template Loader
* <p>
* Retrieves templates either from classes in the class path or classes inside of JAR files within the class path
* <p>
* This implementation always returns a fixed last modified date of -1.
*/
private class ClassPathTemplateLoader extends ClassPathStore.ClassPathTemplateLoader
{
/**
* @see freemarker.cache.TemplateLoader#getLastModified(java.lang.Object)
*/
public long getLastModified(Object templateSource)
{
return -1L;
}
}
}

View File

@@ -32,28 +32,10 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.transaction.Status;
import jakarta.transaction.UserTransaction;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.error.ExceptionStackUtil;
import org.alfresco.repo.model.Repository;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.repo.transaction.TooBusyException;
import org.alfresco.repo.web.scripts.bean.LoginPost;
import org.alfresco.service.cmr.repository.ArchivedIOException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.TemplateService;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.descriptor.DescriptorService;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.TempFileProvider;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
@@ -72,6 +54,23 @@ import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.error.ExceptionStackUtil;
import org.alfresco.repo.model.Repository;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.repo.transaction.TooBusyException;
import org.alfresco.repo.web.scripts.bean.LoginPost;
import org.alfresco.service.cmr.repository.ArchivedIOException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.TemplateService;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.descriptor.DescriptorService;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.TempFileProvider;
/**
* Repository (server-tier) container for Web Scripts
@@ -99,55 +98,54 @@ public class RepositoryContainer extends AbstractRuntimeContainer
private Supplier<TempOutputStream> streamFactory = null;
private String preserveHeadersPattern = null;
private Class<?>[] notPublicExceptions = new Class<?>[] {};
private Class<?>[] publicExceptions = new Class<?>[] {};
private Class<?>[] notPublicExceptions = new Class<?>[]{};
private Class<?>[] publicExceptions = new Class<?>[]{};
/*
* Shame init is already used (by TenantRepositoryContainer).
*/
/* Shame init is already used (by TenantRepositoryContainer). */
public void setup()
{
streamFactory = TempOutputStream.factory(
TempFileProvider.getTempDir(tempDirectoryName),
memoryThreshold, maxContentSize, encryptTempFiles);
TempFileProvider.getTempDir(tempDirectoryName),
memoryThreshold, maxContentSize, encryptTempFiles);
}
public void setEncryptTempFiles(Boolean encryptTempFiles)
{
if(encryptTempFiles != null)
{
this.encryptTempFiles = encryptTempFiles;
}
}
if (encryptTempFiles != null)
{
this.encryptTempFiles = encryptTempFiles;
}
}
public void setTempDirectoryName(String tempDirectoryName)
{
this.tempDirectoryName = tempDirectoryName;
}
public void setTempDirectoryName(String tempDirectoryName)
{
this.tempDirectoryName = tempDirectoryName;
}
public void setMemoryThreshold(Integer memoryThreshold)
{
if(memoryThreshold != null)
{
this.memoryThreshold = memoryThreshold;
}
}
public void setMemoryThreshold(Integer memoryThreshold)
{
if (memoryThreshold != null)
{
this.memoryThreshold = memoryThreshold;
}
}
public void setMaxContentSize(Long maxContentSize)
{
if(maxContentSize != null)
{
this.maxContentSize = maxContentSize;
}
}
public void setMaxContentSize(Long maxContentSize)
{
if (maxContentSize != null)
{
this.maxContentSize = maxContentSize;
}
}
public void setPreserveHeadersPattern(String preserveHeadersPattern)
{
this.preserveHeadersPattern = preserveHeadersPattern;
}
/**
* @param repository Repository
/**
* @param repository
* Repository
*/
public void setRepository(Repository repository)
{
@@ -155,15 +153,17 @@ public class RepositoryContainer extends AbstractRuntimeContainer
}
/**
* @param imageResolver RepositoryImageResolver
* @param imageResolver
* RepositoryImageResolver
*/
public void setRepositoryImageResolver(RepositoryImageResolver imageResolver)
{
this.imageResolver = imageResolver;
}
/**
* @param transactionService TransactionService
* @param transactionService
* TransactionService
*/
public void setTransactionService(TransactionService transactionService)
{
@@ -171,7 +171,8 @@ public class RepositoryContainer extends AbstractRuntimeContainer
}
/**
* @param fallbackTransactionHelper an unlimited transaction helper used to generate error responses
* @param fallbackTransactionHelper
* an unlimited transaction helper used to generate error responses
*/
public void setFallbackTransactionHelper(RetryingTransactionHelper fallbackTransactionHelper)
{
@@ -179,7 +180,8 @@ public class RepositoryContainer extends AbstractRuntimeContainer
}
/**
* @param descriptorService DescriptorService
* @param descriptorService
* DescriptorService
*/
public void setDescriptorService(DescriptorService descriptorService)
{
@@ -187,7 +189,8 @@ public class RepositoryContainer extends AbstractRuntimeContainer
}
/**
* @param authorityService AuthorityService
* @param authorityService
* AuthorityService
*/
public void setAuthorityService(AuthorityService authorityService)
{
@@ -195,14 +198,15 @@ public class RepositoryContainer extends AbstractRuntimeContainer
}
/**
* Exceptions which may contain information that cannot be displayed in UI
* Exceptions which may contain information that cannot be displayed in UI
*
* @param notPublicExceptions - {@link Class}&lt;?&gt;[] instance which contains list of not public exceptions
* @param notPublicExceptions
* - {@link Class}&lt;?&gt;[] instance which contains list of not public exceptions
*/
public void setNotPublicExceptions(List<Class<?>> notPublicExceptions)
{
this.notPublicExceptions = new Class<?>[] {};
if((null != notPublicExceptions) && !notPublicExceptions.isEmpty())
this.notPublicExceptions = new Class<?>[]{};
if ((null != notPublicExceptions) && !notPublicExceptions.isEmpty())
{
this.notPublicExceptions = notPublicExceptions.toArray(this.notPublicExceptions);
}
@@ -216,12 +220,13 @@ public class RepositoryContainer extends AbstractRuntimeContainer
/**
* Exceptions which may contain information that need to display in UI
*
* @param publicExceptions - {@link Class}&lt;?&gt;[] instance which contains list of public exceptions
* @param publicExceptions
* - {@link Class}&lt;?&gt;[] instance which contains list of public exceptions
*/
public void setPublicExceptions(List<Class<?>> publicExceptions)
{
this.publicExceptions = new Class<?>[] {};
if((null != publicExceptions) && !publicExceptions.isEmpty())
this.publicExceptions = new Class<?>[]{};
if ((null != publicExceptions) && !publicExceptions.isEmpty())
{
this.publicExceptions = publicExceptions.toArray(this.publicExceptions);
}
@@ -233,16 +238,16 @@ public class RepositoryContainer extends AbstractRuntimeContainer
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.Container#getDescription()
*/
*
* @see org.alfresco.web.scripts.Container#getDescription() */
public ServerModel getDescription()
{
return new RepositoryServerModel(descriptorService.getCurrentRepositoryDescriptor(), descriptorService.getServerDescriptor());
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.AbstractRuntimeContainer#getScriptParameters()
*/
*
* @see org.alfresco.web.scripts.AbstractRuntimeContainer#getScriptParameters() */
public Map<String, Object> getScriptParameters()
{
Map<String, Object> params = new HashMap<>(super.getScriptParameters());
@@ -250,10 +255,9 @@ public class RepositoryContainer extends AbstractRuntimeContainer
return params;
}
/*
* (non-Javadoc)
* @see org.alfresco.web.scripts.AbstractRuntimeContainer#getTemplateParameters()
*/
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.AbstractRuntimeContainer#getTemplateParameters() */
public Map<String, Object> getTemplateParameters()
{
// Ensure we have a transaction - we might be generating the status template after the main transaction failed
@@ -268,12 +272,13 @@ public class RepositoryContainer extends AbstractRuntimeContainer
/**
* Add Repository specific parameters
*
* @param params Map<String, Object>
* @param params
* Map<String, Object>
*/
private void addRepoParameters(Map<String, Object> params)
{
if (AlfrescoTransactionSupport.getTransactionId() != null &&
AuthenticationUtil.getFullAuthentication() != null)
AuthenticationUtil.getFullAuthentication() != null)
{
NodeRef rootHome = repository.getRootHome();
if (rootHome != null)
@@ -299,10 +304,10 @@ public class RepositoryContainer extends AbstractRuntimeContainer
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.RuntimeContainer#executeScript(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse, org.alfresco.web.scripts.Authenticator)
*/
*
* @see org.alfresco.web.scripts.RuntimeContainer#executeScript(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse, org.alfresco.web.scripts.Authenticator) */
public void executeScript(WebScriptRequest scriptReq, WebScriptResponse scriptRes, final Authenticator auth)
throws IOException
throws IOException
{
try
{
@@ -334,9 +339,9 @@ public class RepositoryContainer extends AbstractRuntimeContainer
}
}
}
protected void executeScriptInternal(final WebScriptRequest scriptReq, final WebScriptResponse scriptRes, final Authenticator auth)
throws IOException
throws IOException
{
final WebScript script = scriptReq.getServiceMatch().getWebScript();
final Description desc = script.getDescription();
@@ -351,7 +356,7 @@ public class RepositoryContainer extends AbstractRuntimeContainer
if (required == RequiredAuthentication.none)
{
// TODO revisit - cleared here, in-lieu of WebClient clear
//AuthenticationUtil.clearCurrentSecurityContext();
// AuthenticationUtil.clearCurrentSecurityContext();
transactionedExecuteAs(script, scriptReq, scriptRes);
return;
@@ -453,17 +458,18 @@ public class RepositoryContainer extends AbstractRuntimeContainer
private void checkGuestAccess(RequiredAuthentication required, String scriptDescriptorId)
{
if (required == RequiredAuthentication.user || required == RequiredAuthentication.admin
|| required == RequiredAuthentication.sysadmin)
|| required == RequiredAuthentication.sysadmin)
{
final String authenticatedUser = AuthenticationUtil.getFullyAuthenticatedUser();
final String runAsUser = AuthenticationUtil.getRunAsUser();
if ((authenticatedUser == null) || (authenticatedUser.equals(runAsUser)
&& authorityService.hasGuestAuthority()) || (!authenticatedUser.equals(runAsUser)
&& authorityService.isGuestAuthority(authenticatedUser)))
&& authorityService.hasGuestAuthority())
|| (!authenticatedUser.equals(runAsUser)
&& authorityService.isGuestAuthority(authenticatedUser)))
{
throw new WebScriptException(HttpServletResponse.SC_UNAUTHORIZED, "Web Script " + scriptDescriptorId
+ " requires user authentication; however, a guest has attempted access.");
+ " requires user authentication; however, a guest has attempted access.");
}
}
}
@@ -477,25 +483,28 @@ public class RepositoryContainer extends AbstractRuntimeContainer
if (required == RequiredAuthentication.sysadmin && !(isSysAdminUser() || isAdminOrSystemUser()))
{
throw new WebScriptException(HttpServletResponse.SC_UNAUTHORIZED, "Web Script " + scriptDescriptorId
+ " requires system-admin authentication; however, a non-system-admin has attempted access.");
+ " requires system-admin authentication; however, a non-system-admin has attempted access.");
}
else if (required == RequiredAuthentication.admin && !isAdminOrSystemUser())
{
throw new WebScriptException(HttpServletResponse.SC_UNAUTHORIZED, "Web Script " + scriptDescriptorId
+ " requires admin authentication; however, a non-admin has attempted access.");
+ " requires admin authentication; however, a non-admin has attempted access.");
}
}
/**
* Execute script within required level of transaction
*
* @param script WebScript
* @param scriptReq WebScriptRequest
* @param scriptRes WebScriptResponse
* @param script
* WebScript
* @param scriptReq
* WebScriptRequest
* @param scriptRes
* WebScriptResponse
* @throws IOException
*/
protected void transactionedExecute(final WebScript script, final WebScriptRequest scriptReq, final WebScriptResponse scriptRes)
throws IOException
throws IOException
{
final Description description = script.getDescription();
@@ -519,7 +528,7 @@ public class RepositoryContainer extends AbstractRuntimeContainer
final RequiredTransactionParameters trxParams = description.getRequiredTransactionParameters();
try (final BufferedRequest bufferedReq = newBufferedRequest(trxParams, scriptReq, streamFactory);
final BufferedResponse bufferedRes = newBufferedResponse(trxParams, scriptRes, streamFactory))
final BufferedResponse bufferedRes = newBufferedResponse(trxParams, scriptRes, streamFactory))
{
boolean readonly = description.getRequiredTransactionParameters().getCapability() == TransactionCapability.readonly;
boolean requiresNew = description.getRequiredTransaction() == RequiredTransaction.requiresnew;
@@ -527,10 +536,10 @@ public class RepositoryContainer extends AbstractRuntimeContainer
// log a warning if we detect a GET webscript being run in a readwrite transaction, GET calls should
// NOT have any side effects so this scenario as a warning sign something maybe amiss, see ALF-10179.
if (logger.isDebugEnabled() && !readonly && "GET".equalsIgnoreCase(
description.getMethod()))
description.getMethod()))
{
logger.debug("Webscript with URL '" + scriptReq.getURL() +
"' is a GET request but it's descriptor has declared a readwrite transaction is required");
"' is a GET request but it's descriptor has declared a readwrite transaction is required");
}
try
@@ -538,7 +547,7 @@ public class RepositoryContainer extends AbstractRuntimeContainer
final RetryingTransactionHelper transactionHelper = transactionService.getRetryingTransactionHelper();
if (script instanceof LoginPost)
{
//login script requires read-write transaction because of authorization interceptor
// login script requires read-write transaction because of authorization interceptor
transactionHelper.setForceWritable(true);
}
transactionHelper.doInTransaction(() -> {
@@ -546,7 +555,7 @@ public class RepositoryContainer extends AbstractRuntimeContainer
{
if (logger.isDebugEnabled())
logger.debug("Begin retry transaction block: " + description.getRequiredTransaction() + ","
+ description.getRequiredTransactionParameters().getCapability());
+ description.getRequiredTransactionParameters().getCapability());
if (bufferedReq == null || bufferedRes == null)
{
@@ -600,7 +609,7 @@ public class RepositoryContainer extends AbstractRuntimeContainer
{
if (logger.isDebugEnabled())
logger.debug("End retry transaction block: " + description.getRequiredTransaction() + ","
+ description.getRequiredTransactionParameters().getCapability());
+ description.getRequiredTransactionParameters().getCapability());
}
return null;
@@ -651,7 +660,7 @@ public class RepositoryContainer extends AbstractRuntimeContainer
}
// Note: if you need to look for more exceptions in the stack, then create a static array and pass it in
if ((socketException != null && socketException.getMessage().contains("Broken pipe")) ||
(clientAbortException != null && ExceptionStackUtil.getCause(ioe, clientAbortException) != null))
(clientAbortException != null && ExceptionStackUtil.getCause(ioe, clientAbortException) != null))
{
if (logger.isDebugEnabled())
{
@@ -671,9 +680,12 @@ public class RepositoryContainer extends AbstractRuntimeContainer
/**
* Execute script within required level of transaction as required effective user.
*
* @param script WebScript
* @param scriptReq WebScriptRequest
* @param scriptRes WebScriptResponse
* @param script
* WebScript
* @param scriptReq
* WebScriptRequest
* @param scriptRes
* WebScriptResponse
* @throws IOException
*/
private void transactionedExecuteAs(final WebScript script, final WebScriptRequest scriptReq,
@@ -696,14 +708,18 @@ public class RepositoryContainer extends AbstractRuntimeContainer
/**
* Execute script within required level of transaction as required effective user.
*
* @param script WebScript
* @param scriptReq WebScriptRequest
* @param scriptRes WebScriptResponse
* @param requiredAuthentication Required authentication
* @param script
* WebScript
* @param scriptReq
* WebScriptRequest
* @param scriptRes
* WebScriptResponse
* @param requiredAuthentication
* Required authentication
* @throws IOException
*/
private void transactionedExecuteAs(final WebScript script, final WebScriptRequest scriptReq,
final WebScriptResponse scriptRes, RequiredAuthentication requiredAuthentication) throws IOException
final WebScriptResponse scriptRes, RequiredAuthentication requiredAuthentication) throws IOException
{
// Execute as System if and only if, the current user is a member of System-Admin group, and he is not a super admin.
// E.g. if 'jdoe' is a member of ALFRESCO_SYSTEM_ADMINISTRATORS group, then the work should be executed as System to satisfy the ACL checks.
@@ -721,16 +737,16 @@ public class RepositoryContainer extends AbstractRuntimeContainer
transactionedExecuteAs(script, scriptReq, scriptRes);
}
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.AbstractRuntimeContainer#onApplicationEvent(org.springframework.context.ApplicationEvent)
*/
*
* @see org.alfresco.web.scripts.AbstractRuntimeContainer#onApplicationEvent(org.springframework.context.ApplicationEvent) */
@Override
public void onApplicationEvent(ApplicationEvent event)
{
if (event instanceof ContextRefreshedEvent)
{
ContextRefreshedEvent refreshEvent = (ContextRefreshedEvent)event;
ContextRefreshedEvent refreshEvent = (ContextRefreshedEvent) event;
ApplicationContext refreshContext = refreshEvent.getApplicationContext();
if (refreshContext.equals(applicationContext))
{
@@ -741,10 +757,10 @@ public class RepositoryContainer extends AbstractRuntimeContainer
}
}
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.AbstractRuntimeContainer#getRequiredAuthentication()
*/
*
* @see org.alfresco.web.scripts.AbstractRuntimeContainer#getRequiredAuthentication() */
@Override
public RequiredAuthentication getRequiredAuthentication()
{
@@ -752,31 +768,31 @@ public class RepositoryContainer extends AbstractRuntimeContainer
{
return RequiredAuthentication.guest; // user or guest (ie. at least guest)
}
return RequiredAuthentication.none;
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.RuntimeContainer#authenticate(org.alfresco.web.scripts.Authenticator, org.alfresco.web.scripts.Description.RequiredAuthentication)
*/
*
* @see org.alfresco.web.scripts.RuntimeContainer#authenticate(org.alfresco.web.scripts.Authenticator, org.alfresco.web.scripts.Description.RequiredAuthentication) */
@Override
public boolean authenticate(Authenticator auth, RequiredAuthentication required)
{
if (auth != null)
{
AuthenticationUtil.clearCurrentSecurityContext();
return auth.authenticate(required, false);
}
return false;
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.AbstractRuntimeContainer#reset()
*/
*
* @see org.alfresco.web.scripts.AbstractRuntimeContainer#reset() */
@Override
public void reset()
public void reset()
{
transactionService.getRetryingTransactionHelper().doInTransaction(() -> {
internalReset();
@@ -790,9 +806,9 @@ public class RepositoryContainer extends AbstractRuntimeContainer
}
private static BufferedRequest newBufferedRequest(
final RequiredTransactionParameters trxParams,
final WebScriptRequest scriptReq,
final Supplier<TempOutputStream> streamFactory)
final RequiredTransactionParameters trxParams,
final WebScriptRequest scriptReq,
final Supplier<TempOutputStream> streamFactory)
{
if (trxParams.getCapability() != TransactionCapability.readwrite)
{
@@ -808,9 +824,9 @@ public class RepositoryContainer extends AbstractRuntimeContainer
}
private static BufferedResponse newBufferedResponse(
final RequiredTransactionParameters trxParams,
final WebScriptResponse scriptRes,
final Supplier<TempOutputStream> streamFactory)
final RequiredTransactionParameters trxParams,
final WebScriptResponse scriptRes,
final Supplier<TempOutputStream> streamFactory)
{
if (trxParams.getCapability() != TransactionCapability.readwrite)
{

View File

@@ -1,80 +1,78 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts;
import jakarta.servlet.ServletContext;
import org.alfresco.service.cmr.repository.FileTypeImageSize;
import org.alfresco.service.cmr.repository.TemplateImageResolver;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.context.ServletContextAware;
/**
* Web Scripts Image Resolver
*
* @author davidc
*/
public class RepositoryImageResolver
implements ServletContextAware, InitializingBean
{
private ServletContext servletContext;
private TemplateImageResolver imageResolver;
/* (non-Javadoc)
* @see org.springframework.web.context.ServletContextAware#setServletContext(jakarta.servlet.ServletContext)
*/
public void setServletContext(ServletContext context)
{
this.servletContext = context;
}
/* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@SuppressWarnings("serial")
public void afterPropertiesSet()
throws Exception
{
this.imageResolver = new TemplateImageResolver()
{
public String resolveImagePathForName(String filename, FileTypeImageSize size)
{
return FileTypeImageUtils.getFileTypeImage(servletContext, filename, size);
}
};
}
/**
* @return image resolver
*/
public TemplateImageResolver getImageResolver()
{
return this.imageResolver;
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts;
import jakarta.servlet.ServletContext;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.context.ServletContextAware;
import org.alfresco.service.cmr.repository.FileTypeImageSize;
import org.alfresco.service.cmr.repository.TemplateImageResolver;
/**
* Web Scripts Image Resolver
*
* @author davidc
*/
public class RepositoryImageResolver
implements ServletContextAware, InitializingBean
{
private ServletContext servletContext;
private TemplateImageResolver imageResolver;
/* (non-Javadoc)
*
* @see org.springframework.web.context.ServletContextAware#setServletContext(jakarta.servlet.ServletContext) */
public void setServletContext(ServletContext context)
{
this.servletContext = context;
}
/* (non-Javadoc)
*
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */
@SuppressWarnings("serial")
public void afterPropertiesSet()
throws Exception
{
this.imageResolver = new TemplateImageResolver() {
public String resolveImagePathForName(String filename, FileTypeImageSize size)
{
return FileTypeImageUtils.getFileTypeImage(servletContext, filename, size);
}
};
}
/**
* @return image resolver
*/
public TemplateImageResolver getImageResolver()
{
return this.imageResolver;
}
}

View File

@@ -23,184 +23,183 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts;
import java.io.InputStream;
import java.io.Reader;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.jscript.ValueConverter;
import org.alfresco.scripts.ScriptException;
import org.alfresco.service.cmr.repository.ScriptLocation;
import org.alfresco.service.cmr.repository.ScriptService;
import org.springframework.extensions.webscripts.MultiScriptLoader;
import org.springframework.extensions.webscripts.ScriptContent;
import org.springframework.extensions.webscripts.ScriptLoader;
import org.springframework.extensions.webscripts.ScriptProcessor;
import org.springframework.extensions.webscripts.SearchPath;
import org.springframework.extensions.webscripts.Store;
import org.springframework.extensions.webscripts.WebScriptException;
/**
* Repository (server-tier) Web Script Processor
*
* @author davidc
*/
public class RepositoryScriptProcessor implements ScriptProcessor
{
// dependencies
protected ScriptService scriptService;
protected ScriptLoader scriptLoader;
protected SearchPath searchPath;
// Javascript Converter
private final ValueConverter valueConverter = new ValueConverter();
/**
* @param scriptService ScriptService
*/
public void setScriptService(ScriptService scriptService)
{
this.scriptService = scriptService;
}
/**
* @param searchPath SearchPath
*/
public void setSearchPath(SearchPath searchPath)
{
this.searchPath = searchPath;
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.ScriptProcessor#findScript(java.lang.String)
*/
public ScriptContent findScript(String path)
{
return scriptLoader.getScript(path);
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.ScriptProcessor#executeScript(java.lang.String, java.util.Map)
*/
public Object executeScript(String path, Map<String, Object> model)
throws ScriptException
{
// locate script within web script stores
ScriptContent scriptContent = findScript(path);
if (scriptContent == null)
{
throw new WebScriptException("Unable to locate script " + path);
}
// execute script
return executeScript(scriptContent, model);
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.ScriptProcessor#executeScript(org.alfresco.web.scripts.ScriptContent, java.util.Map)
*/
public Object executeScript(ScriptContent content, Map<String, Object> model)
{
return scriptService.executeScript("javascript", new RepositoryScriptLocation(content), model);
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.ScriptProcessor#unwrapValue(java.lang.Object)
*/
public Object unwrapValue(Object value)
{
return valueConverter.convertValueForJava(value);
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.ScriptProcessor#reset()
*/
public void reset()
{
init();
this.scriptService.resetScriptProcessors();
}
/**
* Register script loader from each Web Script Store with Script Processor
*/
private void init()
{
List<ScriptLoader> loaders = new ArrayList<ScriptLoader>();
for (Store apiStore : searchPath.getStores())
{
ScriptLoader loader = apiStore.getScriptLoader();
if (loader == null)
{
throw new WebScriptException("Unable to retrieve script loader for Web Script store " + apiStore.getBasePath());
}
loaders.add(loader);
}
scriptLoader = new MultiScriptLoader(loaders.toArray(new ScriptLoader[loaders.size()]));
}
/**
* Script Location Facade
*/
private static class RepositoryScriptLocation implements ScriptLocation
{
private ScriptContent content;
private RepositoryScriptLocation(ScriptContent content)
{
this.content = content;
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.repository.ScriptLocation#getInputStream()
*/
public InputStream getInputStream()
{
return content.getInputStream();
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.repository.ScriptLocation#getReader()
*/
public Reader getReader()
{
return content.getReader();
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.repository.ScriptLocation#isCachable()
*/
public boolean isCachable()
{
return content.isCachable();
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.repository.ScriptLocation#isSecure()
*/
public boolean isSecure()
{
return content.isSecure();
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.repository.ScriptLocation#getPath()
*/
public String getPath()
{
return content.getPath();
}
@Override
public String toString()
{
return content.getPathDescription();
}
}
}
package org.alfresco.repo.web.scripts;
import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.extensions.webscripts.MultiScriptLoader;
import org.springframework.extensions.webscripts.ScriptContent;
import org.springframework.extensions.webscripts.ScriptLoader;
import org.springframework.extensions.webscripts.ScriptProcessor;
import org.springframework.extensions.webscripts.SearchPath;
import org.springframework.extensions.webscripts.Store;
import org.springframework.extensions.webscripts.WebScriptException;
import org.alfresco.repo.jscript.ValueConverter;
import org.alfresco.scripts.ScriptException;
import org.alfresco.service.cmr.repository.ScriptLocation;
import org.alfresco.service.cmr.repository.ScriptService;
/**
* Repository (server-tier) Web Script Processor
*
* @author davidc
*/
public class RepositoryScriptProcessor implements ScriptProcessor
{
// dependencies
protected ScriptService scriptService;
protected ScriptLoader scriptLoader;
protected SearchPath searchPath;
// Javascript Converter
private final ValueConverter valueConverter = new ValueConverter();
/**
* @param scriptService
* ScriptService
*/
public void setScriptService(ScriptService scriptService)
{
this.scriptService = scriptService;
}
/**
* @param searchPath
* SearchPath
*/
public void setSearchPath(SearchPath searchPath)
{
this.searchPath = searchPath;
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.ScriptProcessor#findScript(java.lang.String) */
public ScriptContent findScript(String path)
{
return scriptLoader.getScript(path);
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.ScriptProcessor#executeScript(java.lang.String, java.util.Map) */
public Object executeScript(String path, Map<String, Object> model)
throws ScriptException
{
// locate script within web script stores
ScriptContent scriptContent = findScript(path);
if (scriptContent == null)
{
throw new WebScriptException("Unable to locate script " + path);
}
// execute script
return executeScript(scriptContent, model);
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.ScriptProcessor#executeScript(org.alfresco.web.scripts.ScriptContent, java.util.Map) */
public Object executeScript(ScriptContent content, Map<String, Object> model)
{
return scriptService.executeScript("javascript", new RepositoryScriptLocation(content), model);
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.ScriptProcessor#unwrapValue(java.lang.Object) */
public Object unwrapValue(Object value)
{
return valueConverter.convertValueForJava(value);
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.ScriptProcessor#reset() */
public void reset()
{
init();
this.scriptService.resetScriptProcessors();
}
/**
* Register script loader from each Web Script Store with Script Processor
*/
private void init()
{
List<ScriptLoader> loaders = new ArrayList<ScriptLoader>();
for (Store apiStore : searchPath.getStores())
{
ScriptLoader loader = apiStore.getScriptLoader();
if (loader == null)
{
throw new WebScriptException("Unable to retrieve script loader for Web Script store " + apiStore.getBasePath());
}
loaders.add(loader);
}
scriptLoader = new MultiScriptLoader(loaders.toArray(new ScriptLoader[loaders.size()]));
}
/**
* Script Location Facade
*/
private static class RepositoryScriptLocation implements ScriptLocation
{
private ScriptContent content;
private RepositoryScriptLocation(ScriptContent content)
{
this.content = content;
}
/* (non-Javadoc)
*
* @see org.alfresco.service.cmr.repository.ScriptLocation#getInputStream() */
public InputStream getInputStream()
{
return content.getInputStream();
}
/* (non-Javadoc)
*
* @see org.alfresco.service.cmr.repository.ScriptLocation#getReader() */
public Reader getReader()
{
return content.getReader();
}
/* (non-Javadoc)
*
* @see org.alfresco.service.cmr.repository.ScriptLocation#isCachable() */
public boolean isCachable()
{
return content.isCachable();
}
/* (non-Javadoc)
*
* @see org.alfresco.service.cmr.repository.ScriptLocation#isSecure() */
public boolean isSecure()
{
return content.isSecure();
}
/* (non-Javadoc)
*
* @see org.alfresco.service.cmr.repository.ScriptLocation#getPath() */
public String getPath()
{
return content.getPath();
}
@Override
public String toString()
{
return content.getPathDescription();
}
}
}

View File

@@ -23,32 +23,32 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts;
import org.springframework.extensions.webscripts.ScriptProcessor;
import org.springframework.extensions.webscripts.ScriptProcessorFactory;
/**
* @author Kevin Roast
*/
public class RepositoryScriptProcessorFactory implements ScriptProcessorFactory
{
private ScriptProcessor scriptProcessor;
/**
* @param scriptProcessor the ScriptProcessor to set
*/
public void setScriptProcessor(ScriptProcessor scriptProcessor)
{
this.scriptProcessor = scriptProcessor;
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.ScriptProcessorFactory#newInstance()
*/
public ScriptProcessor newInstance()
{
return scriptProcessor;
}
}
package org.alfresco.repo.web.scripts;
import org.springframework.extensions.webscripts.ScriptProcessor;
import org.springframework.extensions.webscripts.ScriptProcessorFactory;
/**
* @author Kevin Roast
*/
public class RepositoryScriptProcessorFactory implements ScriptProcessorFactory
{
private ScriptProcessor scriptProcessor;
/**
* @param scriptProcessor
* the ScriptProcessor to set
*/
public void setScriptProcessor(ScriptProcessor scriptProcessor)
{
this.scriptProcessor = scriptProcessor;
}
/* (non-Javadoc)
*
* @see org.springframework.extensions.webscripts.ScriptProcessorFactory#newInstance() */
public ScriptProcessor newInstance()
{
return scriptProcessor;
}
}

View File

@@ -23,120 +23,122 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts;
import org.alfresco.service.descriptor.Descriptor;
import org.springframework.extensions.webscripts.ServerModel;
/**
* Script / Template Model representing Repository Server meta-data
*
* @author davidc
*/
public class RepositoryServerModel implements ServerModel
{
private Descriptor currentDescriptor;
private Descriptor serverDescriptor;
/**
* Construct
*
* @param currentDescriptor Descriptor
* @param serverDescriptor Descriptor
*/
/*package*/ RepositoryServerModel(Descriptor currentDescriptor, Descriptor serverDescriptor)
{
this.currentDescriptor = currentDescriptor;
this.serverDescriptor = serverDescriptor;
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.ServerModel#getContainerName()
*/
public String getContainerName()
{
return "Repository";
}
/*(non-Javadoc)
* @see org.alfresco.web.scripts.ServerModel#getId()
*/
public String getId()
{
return currentDescriptor.getId();
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.ServerModel#getName()
*/
public String getName()
{
return currentDescriptor.getName();
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.ServerModel#getVersionMajor()
*/
public String getVersionMajor()
{
return currentDescriptor.getVersionMajor();
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.ServerModel#getVersionMinor()
*/
public String getVersionMinor()
{
return currentDescriptor.getVersionMinor();
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.ServerModel#getVersionRevision()
*/
public String getVersionRevision()
{
return currentDescriptor.getVersionRevision();
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.ServerModel#getVersionLabel()
*/
public String getVersionLabel()
{
return currentDescriptor.getVersionLabel();
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.ServerModel#getVersionBuild()
*/
public String getVersionBuild()
{
return currentDescriptor.getVersionBuild();
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.ServerModel#getVersion()
*/
public String getVersion()
{
return currentDescriptor.getVersion();
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.ServerModel#getEdition()
*/
public String getEdition()
{
return serverDescriptor.getEdition();
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.ServerModel#getSchema()
*/
public int getSchema()
{
return currentDescriptor.getSchema();
}
}
package org.alfresco.repo.web.scripts;
import org.springframework.extensions.webscripts.ServerModel;
import org.alfresco.service.descriptor.Descriptor;
/**
* Script / Template Model representing Repository Server meta-data
*
* @author davidc
*/
public class RepositoryServerModel implements ServerModel
{
private Descriptor currentDescriptor;
private Descriptor serverDescriptor;
/**
* Construct
*
* @param currentDescriptor
* Descriptor
* @param serverDescriptor
* Descriptor
*/
/* package */ RepositoryServerModel(Descriptor currentDescriptor, Descriptor serverDescriptor)
{
this.currentDescriptor = currentDescriptor;
this.serverDescriptor = serverDescriptor;
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.ServerModel#getContainerName() */
public String getContainerName()
{
return "Repository";
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.ServerModel#getId() */
public String getId()
{
return currentDescriptor.getId();
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.ServerModel#getName() */
public String getName()
{
return currentDescriptor.getName();
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.ServerModel#getVersionMajor() */
public String getVersionMajor()
{
return currentDescriptor.getVersionMajor();
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.ServerModel#getVersionMinor() */
public String getVersionMinor()
{
return currentDescriptor.getVersionMinor();
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.ServerModel#getVersionRevision() */
public String getVersionRevision()
{
return currentDescriptor.getVersionRevision();
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.ServerModel#getVersionLabel() */
public String getVersionLabel()
{
return currentDescriptor.getVersionLabel();
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.ServerModel#getVersionBuild() */
public String getVersionBuild()
{
return currentDescriptor.getVersionBuild();
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.ServerModel#getVersion() */
public String getVersion()
{
return currentDescriptor.getVersion();
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.ServerModel#getEdition() */
public String getEdition()
{
return serverDescriptor.getEdition();
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.ServerModel#getSchema() */
public int getSchema()
{
return currentDescriptor.getSchema();
}
}

View File

@@ -23,239 +23,238 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.processor.ProcessorExtension;
import org.alfresco.repo.template.FreeMarkerProcessor;
import org.alfresco.repo.template.QNameAwareObjectWrapper;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
import org.springframework.extensions.webscripts.SearchPath;
import org.springframework.extensions.webscripts.Store;
import org.springframework.extensions.webscripts.TemplateProcessor;
import org.springframework.extensions.webscripts.WebScriptException;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.StrongCacheStorage;
import freemarker.cache.TemplateLoader;
import freemarker.core.TemplateClassResolver;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import freemarker.template.Version;
/**
* Repository (server-tier) Web Script Template Processor
*
* @author davidc
*/
public class RepositoryTemplateProcessor extends FreeMarkerProcessor
implements TemplateProcessor, ApplicationContextAware, ApplicationListener
{
private ProcessorLifecycle lifecycle = new ProcessorLifecycle();
protected SearchPath searchPath;
protected String defaultEncoding;
protected Configuration templateConfig;
protected FreeMarkerProcessor freeMarkerProcessor;
private int updateDelay = 1;
/* (non-Javadoc)
* @see org.alfresco.repo.template.FreeMarkerProcessor#setDefaultEncoding(java.lang.String)
*/
@Override
public void setDefaultEncoding(String defaultEncoding)
{
this.defaultEncoding = defaultEncoding;
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.TemplateProcessor#getDefaultEncoding()
*/
public String getDefaultEncoding()
{
return this.defaultEncoding;
}
/**
* @param updateDelay the time in seconds between checks on the modified date for cached templates
*/
public void setUpdateDelay(int updateDelay)
{
this.updateDelay = updateDelay;
}
/**
* @deprecated
* @param cacheSize not used anymore
*/
@Deprecated
public void setCacheSize(int cacheSize)
{
}
/**
* @param searchPath SearchPath
*/
public void setSearchPath(SearchPath searchPath)
{
this.searchPath = searchPath;
}
/**
* Set the freemarker processor
*
* @param freeMarkerProcessor the free marker processor
*/
public void setFreeMarkerProcessor(FreeMarkerProcessor freeMarkerProcessor)
{
this.freeMarkerProcessor = freeMarkerProcessor;
}
/* (non-Javadoc)
* @see org.alfresco.repo.template.FreeMarkerProcessor#getConfig()
*/
@Override
protected Configuration getConfig()
{
return templateConfig;
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.TemplateProcessor#reset()
*/
public void reset()
{
if (templateConfig != null)
{
templateConfig.clearTemplateCache();
}
initConfig();
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.TemplateProcessor#hasTemplate(java.lang.String)
*/
public boolean hasTemplate(String templatePath)
{
boolean hasTemplate = false;
try
{
Template template = templateConfig.getTemplate(templatePath);
hasTemplate = (template != null);
}
catch(FileNotFoundException e)
{
// NOTE: return false as template is not found
}
catch(IOException e)
{
throw new WebScriptException("Failed to retrieve template " + templatePath, e);
}
return hasTemplate;
}
/**
* Initialise FreeMarker Configuration
*/
protected void initConfig()
{
Configuration config = new Configuration();
// setup template cache
config.setCacheStorage(new StrongCacheStorage());
config.setTemplateUpdateDelay(updateDelay);
// setup template loaders
List<TemplateLoader> loaders = new ArrayList<TemplateLoader>();
for (Store apiStore : searchPath.getStores())
{
TemplateLoader loader = apiStore.getTemplateLoader();
if (loader == null)
{
throw new WebScriptException("Unable to retrieve template loader for Web Script store " + apiStore.getBasePath());
}
loaders.add(loader);
}
MultiTemplateLoader loader = new MultiTemplateLoader(loaders.toArray(new TemplateLoader[loaders.size()]));
config.setTemplateLoader(loader);
// use our custom object wrapper that can deal with QNameMap objects directly
config.setObjectWrapper(new QNameAwareObjectWrapper());
// rethrow any exception so we can deal with them
config.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
// turn off locale sensitive lookup - to save numerous wasted calls to nodeservice.exists()
config.setLocalizedLookup(false);
// set template encoding
if (defaultEncoding != null)
{
config.setDefaultEncoding(defaultEncoding);
}
// set output encoding
config.setOutputEncoding("UTF-8");
config.setIncompatibleImprovements(new Version(2, 3, 20));
config.setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER);
templateConfig = config;
}
/**
* Tempory fix to initialise this template processor with the freeMarker extensions expected by
* the templates.
*/
private void initProcessorExtensions()
{
for (ProcessorExtension processorExtension : this.freeMarkerProcessor.getProcessorExtensions())
{
this.registerProcessorExtension(processorExtension);
}
}
/* (non-Javadoc)
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
lifecycle.setApplicationContext(applicationContext);
}
/* (non-Javadoc)
* @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
*/
public void onApplicationEvent(ApplicationEvent event)
{
lifecycle.onApplicationEvent(event);
}
/**
* Hooks into Spring Application Lifecycle
*/
private class ProcessorLifecycle extends AbstractLifecycleBean
{
@Override
protected void onBootstrap(ApplicationEvent event)
{
initProcessorExtensions();
}
@Override
protected void onShutdown(ApplicationEvent event)
{
}
}
}
package org.alfresco.repo.web.scripts;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.StrongCacheStorage;
import freemarker.cache.TemplateLoader;
import freemarker.core.TemplateClassResolver;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import freemarker.template.Version;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
import org.springframework.extensions.webscripts.SearchPath;
import org.springframework.extensions.webscripts.Store;
import org.springframework.extensions.webscripts.TemplateProcessor;
import org.springframework.extensions.webscripts.WebScriptException;
import org.alfresco.processor.ProcessorExtension;
import org.alfresco.repo.template.FreeMarkerProcessor;
import org.alfresco.repo.template.QNameAwareObjectWrapper;
/**
* Repository (server-tier) Web Script Template Processor
*
* @author davidc
*/
public class RepositoryTemplateProcessor extends FreeMarkerProcessor
implements TemplateProcessor, ApplicationContextAware, ApplicationListener
{
private ProcessorLifecycle lifecycle = new ProcessorLifecycle();
protected SearchPath searchPath;
protected String defaultEncoding;
protected Configuration templateConfig;
protected FreeMarkerProcessor freeMarkerProcessor;
private int updateDelay = 1;
/* (non-Javadoc)
*
* @see org.alfresco.repo.template.FreeMarkerProcessor#setDefaultEncoding(java.lang.String) */
@Override
public void setDefaultEncoding(String defaultEncoding)
{
this.defaultEncoding = defaultEncoding;
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.TemplateProcessor#getDefaultEncoding() */
public String getDefaultEncoding()
{
return this.defaultEncoding;
}
/**
* @param updateDelay
* the time in seconds between checks on the modified date for cached templates
*/
public void setUpdateDelay(int updateDelay)
{
this.updateDelay = updateDelay;
}
/**
* @deprecated
* @param cacheSize
* not used anymore
*/
@Deprecated
public void setCacheSize(int cacheSize)
{}
/**
* @param searchPath
* SearchPath
*/
public void setSearchPath(SearchPath searchPath)
{
this.searchPath = searchPath;
}
/**
* Set the freemarker processor
*
* @param freeMarkerProcessor
* the free marker processor
*/
public void setFreeMarkerProcessor(FreeMarkerProcessor freeMarkerProcessor)
{
this.freeMarkerProcessor = freeMarkerProcessor;
}
/* (non-Javadoc)
*
* @see org.alfresco.repo.template.FreeMarkerProcessor#getConfig() */
@Override
protected Configuration getConfig()
{
return templateConfig;
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.TemplateProcessor#reset() */
public void reset()
{
if (templateConfig != null)
{
templateConfig.clearTemplateCache();
}
initConfig();
}
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.TemplateProcessor#hasTemplate(java.lang.String) */
public boolean hasTemplate(String templatePath)
{
boolean hasTemplate = false;
try
{
Template template = templateConfig.getTemplate(templatePath);
hasTemplate = (template != null);
}
catch (FileNotFoundException e)
{
// NOTE: return false as template is not found
}
catch (IOException e)
{
throw new WebScriptException("Failed to retrieve template " + templatePath, e);
}
return hasTemplate;
}
/**
* Initialise FreeMarker Configuration
*/
protected void initConfig()
{
Configuration config = new Configuration();
// setup template cache
config.setCacheStorage(new StrongCacheStorage());
config.setTemplateUpdateDelay(updateDelay);
// setup template loaders
List<TemplateLoader> loaders = new ArrayList<TemplateLoader>();
for (Store apiStore : searchPath.getStores())
{
TemplateLoader loader = apiStore.getTemplateLoader();
if (loader == null)
{
throw new WebScriptException("Unable to retrieve template loader for Web Script store " + apiStore.getBasePath());
}
loaders.add(loader);
}
MultiTemplateLoader loader = new MultiTemplateLoader(loaders.toArray(new TemplateLoader[loaders.size()]));
config.setTemplateLoader(loader);
// use our custom object wrapper that can deal with QNameMap objects directly
config.setObjectWrapper(new QNameAwareObjectWrapper());
// rethrow any exception so we can deal with them
config.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
// turn off locale sensitive lookup - to save numerous wasted calls to nodeservice.exists()
config.setLocalizedLookup(false);
// set template encoding
if (defaultEncoding != null)
{
config.setDefaultEncoding(defaultEncoding);
}
// set output encoding
config.setOutputEncoding("UTF-8");
config.setIncompatibleImprovements(new Version(2, 3, 20));
config.setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER);
templateConfig = config;
}
/**
* Tempory fix to initialise this template processor with the freeMarker extensions expected by the templates.
*/
private void initProcessorExtensions()
{
for (ProcessorExtension processorExtension : this.freeMarkerProcessor.getProcessorExtensions())
{
this.registerProcessorExtension(processorExtension);
}
}
/* (non-Javadoc)
*
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) */
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
lifecycle.setApplicationContext(applicationContext);
}
/* (non-Javadoc)
*
* @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent) */
public void onApplicationEvent(ApplicationEvent event)
{
lifecycle.onApplicationEvent(event);
}
/**
* Hooks into Spring Application Lifecycle
*/
private class ProcessorLifecycle extends AbstractLifecycleBean
{
@Override
protected void onBootstrap(ApplicationEvent event)
{
initProcessorExtensions();
}
@Override
protected void onShutdown(ApplicationEvent event)
{}
}
}

View File

@@ -23,32 +23,32 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts;
import org.springframework.extensions.webscripts.TemplateProcessor;
import org.springframework.extensions.webscripts.TemplateProcessorFactory;
/**
* @author Kevin Roast
*/
public class RepositoryTemplateProcessorFactory implements TemplateProcessorFactory
{
private TemplateProcessor templateProcessor;
/**
* @param templateProcessor the TemplateProcessor to set
*/
public void setTemplateProcessor(TemplateProcessor templateProcessor)
{
this.templateProcessor = templateProcessor;
}
/* (non-Javadoc)
* @see org.springframework.extensions.webscripts.TemplateProcessorFactory#newInstance()
*/
public TemplateProcessor newInstance()
{
return templateProcessor;
}
}
package org.alfresco.repo.web.scripts;
import org.springframework.extensions.webscripts.TemplateProcessor;
import org.springframework.extensions.webscripts.TemplateProcessorFactory;
/**
* @author Kevin Roast
*/
public class RepositoryTemplateProcessorFactory implements TemplateProcessorFactory
{
private TemplateProcessor templateProcessor;
/**
* @param templateProcessor
* the TemplateProcessor to set
*/
public void setTemplateProcessor(TemplateProcessor templateProcessor)
{
this.templateProcessor = templateProcessor;
}
/* (non-Javadoc)
*
* @see org.springframework.extensions.webscripts.TemplateProcessorFactory#newInstance() */
public TemplateProcessor newInstance()
{
return templateProcessor;
}
}

View File

@@ -37,29 +37,26 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.util.function.Supplier;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import org.alfresco.repo.content.ContentLimitViolationException;
import org.alfresco.util.TempFileProvider;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.alfresco.repo.content.ContentLimitViolationException;
import org.alfresco.util.TempFileProvider;
/**
* An output stream implementation that keeps the data in memory if is less then
* the specified <b>memoryThreshold</b> otherwise it writes it to a temp file.
* An output stream implementation that keeps the data in memory if is less then the specified <b>memoryThreshold</b> otherwise it writes it to a temp file.
* <p/>
*
* Close the stream before any call to
* {@link TempOutputStream}.getInputStream().
* Close the stream before any call to {@link TempOutputStream}.getInputStream().
* <p/>
*
* If <b>deleteTempFileOnClose</b> is false then use proper try-finally patterns
* to ensure that the temp file is destroyed after it is no longer needed.
* If <b>deleteTempFileOnClose</b> is false then use proper try-finally patterns to ensure that the temp file is destroyed after it is no longer needed.
*
* <pre>
* <code>try
@@ -102,9 +99,7 @@ public class TempOutputStream extends OutputStream
* Creates a TempOutputStream.
*
* @param tempDir
* the temporary directory, i.e. <code>isDir == true</code>, that
* will be used as * parent directory for creating temp file backed
* streams
* the temporary directory, i.e. <code>isDir == true</code>, that will be used as * parent directory for creating temp file backed streams
* @param memoryThreshold
* the memory threshold in B
* @param maxContentSize
@@ -187,8 +182,7 @@ public class TempOutputStream extends OutputStream
* Closes the stream and removes the backing file (if present).
* <p/>
*
* If <b>deleteTempFileOnClose</b> is false then use proper try-finally patterns
* to ensure that the temp file is destroyed after it is no longer needed.
* If <b>deleteTempFileOnClose</b> is false then use proper try-finally patterns to ensure that the temp file is destroyed after it is no longer needed.
*
* <pre>
* <code>try
@@ -350,9 +344,7 @@ public class TempOutputStream extends OutputStream
* Creates a {@link TempOutputStream} factory/supplier.
*
* @param tempDir
* the temporary directory, i.e. <code>isDir == true</code>, that
* will be used as * parent directory for creating temp file backed
* streams
* the temporary directory, i.e. <code>isDir == true</code>, that will be used as * parent directory for creating temp file backed streams
* @param memoryThreshold
* the memory threshold in B
* @param maxContentSize
@@ -361,7 +353,7 @@ public class TempOutputStream extends OutputStream
* true if temp files should be encrypted
*/
public static Supplier<TempOutputStream> factory(final File tempDir, final int memoryThreshold,
final long maxContentSize, final boolean encrypt)
final long maxContentSize, final boolean encrypt)
{
return () -> new TempOutputStream(tempDir, memoryThreshold, maxContentSize, encrypt);
}

View File

@@ -23,108 +23,111 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts;
import org.alfresco.repo.cache.AsynchronouslyRefreshedCache;
import org.alfresco.repo.tenant.TenantAdminService;
import org.alfresco.repo.tenant.TenantDeployer;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.transaction.TransactionService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.Registry;
/**
* Tenant-aware Repository (server-tier) container for Web Scripts
*
* @author davidc
*/
public class TenantRepositoryContainer extends RepositoryContainer implements TenantDeployer
{
// Logger
protected static final Log logger = LogFactory.getLog(TenantRepositoryContainer.class);
/* Component Dependencies */
protected TenantAdminService tenantAdminService;
protected TransactionService transactionService;
private AsynchronouslyRefreshedCache<Registry> registryCache;
/**
* @param registryCache asynchronously maintained cache for script registries
*/
public void setWebScriptsRegistryCache(AsynchronouslyRefreshedCache<Registry> registryCache)
{
this.registryCache = registryCache;
}
/**
* @param tenantAdminService service to sort out tenant context
*/
public void setTenantAdminService(TenantAdminService tenantAdminService)
{
this.tenantAdminService = tenantAdminService;
}
/**
* @param transactionService service to give transactions when reading from the container
*/
public void setTransactionService(TransactionService transactionService)
{
super.setTransactionService(transactionService);
this.transactionService = transactionService;
}
@Override
public Registry getRegistry()
{
Registry registry = registryCache.get();
boolean isUpToDate = registryCache.isUpToDate();
if (!isUpToDate && logger.isDebugEnabled())
{
logger.debug("Retrieved out of date web script registry for tenant " + tenantAdminService.getCurrentUserDomain());
}
return registry;
}
@Override
public void onEnableTenant()
{
init();
}
@Override
public void onDisableTenant()
{
destroy();
}
@Override
public void init()
{
tenantAdminService.register(this);
registryCache.refresh();
super.reset();
}
@Override
public void destroy()
{
registryCache.refresh();
}
@Override
public void reset()
{
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Object>()
{
public Object execute() throws Exception
{
destroy();
init();
return null;
}
}, true, false);
}
}
package org.alfresco.repo.web.scripts;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.Registry;
import org.alfresco.repo.cache.AsynchronouslyRefreshedCache;
import org.alfresco.repo.tenant.TenantAdminService;
import org.alfresco.repo.tenant.TenantDeployer;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.transaction.TransactionService;
/**
* Tenant-aware Repository (server-tier) container for Web Scripts
*
* @author davidc
*/
public class TenantRepositoryContainer extends RepositoryContainer implements TenantDeployer
{
// Logger
protected static final Log logger = LogFactory.getLog(TenantRepositoryContainer.class);
/* Component Dependencies */
protected TenantAdminService tenantAdminService;
protected TransactionService transactionService;
private AsynchronouslyRefreshedCache<Registry> registryCache;
/**
* @param registryCache
* asynchronously maintained cache for script registries
*/
public void setWebScriptsRegistryCache(AsynchronouslyRefreshedCache<Registry> registryCache)
{
this.registryCache = registryCache;
}
/**
* @param tenantAdminService
* service to sort out tenant context
*/
public void setTenantAdminService(TenantAdminService tenantAdminService)
{
this.tenantAdminService = tenantAdminService;
}
/**
* @param transactionService
* service to give transactions when reading from the container
*/
public void setTransactionService(TransactionService transactionService)
{
super.setTransactionService(transactionService);
this.transactionService = transactionService;
}
@Override
public Registry getRegistry()
{
Registry registry = registryCache.get();
boolean isUpToDate = registryCache.isUpToDate();
if (!isUpToDate && logger.isDebugEnabled())
{
logger.debug("Retrieved out of date web script registry for tenant " + tenantAdminService.getCurrentUserDomain());
}
return registry;
}
@Override
public void onEnableTenant()
{
init();
}
@Override
public void onDisableTenant()
{
destroy();
}
@Override
public void init()
{
tenantAdminService.register(this);
registryCache.refresh();
super.reset();
}
@Override
public void destroy()
{
registryCache.refresh();
}
@Override
public void reset()
{
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Object>() {
public Object execute() throws Exception
{
destroy();
init();
return null;
}
}, true, false);
}
}

View File

@@ -27,18 +27,17 @@
package org.alfresco.repo.web.scripts;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
import org.springframework.extensions.webscripts.servlet.WebScriptServlet;
import org.springframework.extensions.webscripts.servlet.WebScriptServletRuntime;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
/**
* Entry point for web scripts which can accept a tenant id in their servlet path
@@ -47,58 +46,58 @@ import org.springframework.extensions.webscripts.servlet.WebScriptServletRuntime
*/
public class TenantWebScriptServlet extends WebScriptServlet
{
// public static final String SYSTEM_TENANT = "-system-";
// public static final String DEFAULT_TENANT = "-default-";
// public static final String SYSTEM_TENANT = "-system-";
// public static final String DEFAULT_TENANT = "-default-";
private static final long serialVersionUID = 2954663814419046489L;
// Logger
private static final Log logger = LogFactory.getLog(TenantWebScriptServlet.class);
protected WebScriptServletRuntime getRuntime(HttpServletRequest req, HttpServletResponse res)
{
WebScriptServletRuntime runtime = new TenantWebScriptServletRuntime(container, authenticatorFactory, req, res, serverProperties);
return runtime;
}
/* (non-Javadoc)
* @see jakarta.servlet.http.HttpServlet#service(jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse)
*/
/* (non-Javadoc)
*
* @see jakarta.servlet.http.HttpServlet#service(jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse) */
protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
if (logger.isDebugEnabled())
logger.debug("Processing tenant request (" + req.getMethod() + ") " + req.getRequestURL() + (req.getQueryString() != null ? "?" + req.getQueryString() : ""));
logger.debug("Processing tenant request (" + req.getMethod() + ") " + req.getRequestURL() + (req.getQueryString() != null ? "?" + req.getQueryString() : ""));
if (req.getCharacterEncoding() == null)
{
req.setCharacterEncoding("UTF-8");
}
setLanguageFromRequestHeader(req);
try
{
WebScriptServletRuntime runtime = getRuntime(req, res);
WebScriptServletRuntime runtime = getRuntime(req, res);
runtime.executeScript();
}
catch (IllegalStateException e)
catch (IllegalStateException e)
{
if(e.getMessage().contains("getOutputStream() has already been called for this response"))
{
if(logger.isDebugEnabled())
{
logger.warn("Client has cut off communication", e);
}
else
{
logger.warn("Client has cut off communication");
}
}
else
{
throw e;
}
}
if (e.getMessage().contains("getOutputStream() has already been called for this response"))
{
if (logger.isDebugEnabled())
{
logger.warn("Client has cut off communication", e);
}
else
{
logger.warn("Client has cut off communication");
}
}
else
{
throw e;
}
}
finally
{
// clear threadlocal

View File

@@ -34,7 +34,6 @@ import org.springframework.extensions.webscripts.Match;
import org.springframework.extensions.webscripts.Runtime;
import org.springframework.extensions.webscripts.servlet.WebScriptServletRequest;
/**
* Web Script Request which can handle a tenant id in their servlet path
*
@@ -44,11 +43,11 @@ public class TenantWebScriptServletRequest extends WebScriptServletRequest
{
protected String tenant;
protected String pathInfo;
protected void parse()
{
String realPathInfo = getRealPathInfo();
// remove tenant
int idx = realPathInfo.indexOf('/', 1);
tenant = realPathInfo.substring(1, idx == -1 ? realPathInfo.length() : idx);
@@ -58,10 +57,14 @@ public class TenantWebScriptServletRequest extends WebScriptServletRequest
/**
* Construction
*
* @param container Runtime
* @param req HttpServletRequest
* @param serviceMatch Match
* @param serverProperties ServerProperties
* @param container
* Runtime
* @param req
* HttpServletRequest
* @param serviceMatch
* Match
* @param serverProperties
* ServerProperties
*/
public TenantWebScriptServletRequest(Runtime container, HttpServletRequest req, Match serviceMatch, ServerProperties serverProperties)
{
@@ -70,16 +73,16 @@ public class TenantWebScriptServletRequest extends WebScriptServletRequest
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptRequest#getServiceContextPath()
*/
*
* @see org.alfresco.web.scripts.WebScriptRequest#getServiceContextPath() */
public String getServiceContextPath()
{
return getHttpServletRequest().getContextPath() + getHttpServletRequest().getServletPath() + "/" + tenant;
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptRequest#getPathInfo()
*/
*
* @see org.alfresco.web.scripts.WebScriptRequest#getPathInfo() */
public String getPathInfo()
{
return pathInfo;
@@ -89,17 +92,17 @@ public class TenantWebScriptServletRequest extends WebScriptServletRequest
{
return tenant;
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptRequest#getPathInfo()
*/
*
* @see org.alfresco.web.scripts.WebScriptRequest#getPathInfo() */
protected String getRealPathInfo()
{
// NOTE: Don't use req.getPathInfo() - it truncates the path at first semi-colon in Tomcat
final String requestURI = getHttpServletRequest().getRequestURI();
final String serviceContextPath = getHttpServletRequest().getContextPath() + getHttpServletRequest().getServletPath();
String pathInfo;
if (serviceContextPath.length() > requestURI.length())
{
// NOTE: assume a redirect has taken place e.g. tomcat welcome-page
@@ -110,7 +113,7 @@ public class TenantWebScriptServletRequest extends WebScriptServletRequest
{
pathInfo = URLDecoder.decode(requestURI.substring(serviceContextPath.length()));
}
return pathInfo;
}

View File

@@ -38,7 +38,6 @@ import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.servlet.ServletAuthenticatorFactory;
import org.springframework.extensions.webscripts.servlet.WebScriptServletRuntime;
/**
* HTTP Servlet Web Script Runtime which can handle a tenant id in a web script path
*
@@ -52,8 +51,8 @@ public class TenantWebScriptServletRuntime extends WebScriptServletRuntime
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptRuntime#getScriptUrl()
*/
*
* @see org.alfresco.web.scripts.WebScriptRuntime#getScriptUrl() */
@Override
protected String getScriptUrl()
{
@@ -61,7 +60,7 @@ public class TenantWebScriptServletRuntime extends WebScriptServletRuntime
final String requestURI = req.getRequestURI();
final String serviceContextPath = req.getContextPath() + req.getServletPath();
String pathInfo;
if (serviceContextPath.length() > requestURI.length())
{
// NOTE: assume a redirect has taken place e.g. tomcat welcome-page
@@ -72,7 +71,7 @@ public class TenantWebScriptServletRuntime extends WebScriptServletRuntime
{
pathInfo = URLDecoder.decode(requestURI.substring(serviceContextPath.length()));
}
// ensure tenant is specified at beginning of path
// NOTE: must contain at least root / and single character for tenant name
if (pathInfo.length() < 2)
@@ -84,22 +83,22 @@ public class TenantWebScriptServletRuntime extends WebScriptServletRuntime
pathInfo = pathInfo.substring(idx == -1 ? pathInfo.length() : idx);
return pathInfo;
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptRuntime#createRequest(org.alfresco.web.scripts.WebScriptMatch)
*/
*
* @see org.alfresco.web.scripts.WebScriptRuntime#createRequest(org.alfresco.web.scripts.WebScriptMatch) */
@Override
protected WebScriptRequest createRequest(Match match)
{
// TODO: construct org.springframework.extensions.webscripts.servlet.WebScriptServletResponse when
// org.alfresco.web.scripts.WebScriptServletResponse (deprecated) is removed
// org.alfresco.web.scripts.WebScriptServletResponse (deprecated) is removed
servletReq = new TenantWebScriptServletRequest(this, req, match, serverProperties);
return servletReq;
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptContainer#getName()
*/
*
* @see org.alfresco.web.scripts.WebScriptContainer#getName() */
public String getName()
{
return "TenantServletRuntime";

View File

@@ -23,138 +23,137 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
package org.alfresco.repo.web.scripts;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import org.json.JSONObject;
import org.springframework.extensions.surf.util.Content;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.repo.nodelocator.CompanyHomeNodeLocator;
import org.alfresco.repo.nodelocator.NodeLocatorService;
import org.alfresco.repo.nodelocator.SharedHomeNodeLocator;
import org.alfresco.repo.nodelocator.SitesHomeNodeLocator;
import org.alfresco.repo.nodelocator.UserHomeNodeLocator;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.ISO8601DateFormat;
import org.json.JSONObject;
import org.springframework.extensions.surf.util.Content;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author Nick Smith
* @since 4.0
*
*/
public class WebScriptUtil
{
// General Keys
public static final String DATA_KEY = "data";
// NodeRef Keys
public static final String STORE_PROTOCOL = "store_protocol";
public static final String STORE_ID = "store_id";
public static final String NODE_ID = "node_id";
//Date/Calendar Keys
public static final String DATE_TIME= "dateTime";
public static final String FORMAT= "format";
public static final String TIME_ZONE= "timeZone";
public static final String ISO8601 = "ISO8601";
public static String getContent(WebScriptRequest request) throws IOException
{
Content content = request.getContent();
return content.getContent();
}
public static Map<String, Object> buildCalendarModel(Calendar calendar)
{
Map<String, Object> model = buildDateModel(calendar.getTime());
model.put(TIME_ZONE, calendar.getTimeZone().getID());
return model;
}
public static Map<String, Object> buildDateModel(Date dateTime)
{
String dateStr = ISO8601DateFormat.format(dateTime);
Map<String, Object> model = new HashMap<String, Object>();
model.put(DATE_TIME, dateStr);
model.put(FORMAT, ISO8601);
return model;
}
public static Calendar getCalendar(JSONObject json) throws ParseException
{
Date date = getDate(json);
if(date == null)
{
return null;
}
Calendar calendar = Calendar.getInstance();
String timeZone = json.optString(TIME_ZONE);
if(timeZone != null)
{
TimeZone zone = TimeZone.getTimeZone(timeZone);
calendar.setTimeZone(zone);
}
calendar.setTime(date);
return calendar;
}
public static Date getDate(JSONObject json) throws ParseException
{
if(json == null)
{
return null;
}
String dateTime = json.optString(DATE_TIME);
if(dateTime == null)
{
return null;
}
String format = json.optString(FORMAT);
if(format!= null && ISO8601.equals(format) == false)
{
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
return dateFormat.parse(dateTime);
}
return ISO8601DateFormat.parse(dateTime);
}
public static Map<String, Object> createBaseModel(Map<String, Object> result)
{
Map<String, Object> model = new HashMap<String, Object>();
model.put(DATA_KEY, result);
return model;
}
public static Map<String, Object> createBaseModel(List<Map<String, Object>> results)
{
Map<String, Object> model = new HashMap<String, Object>();
model.put(DATA_KEY, results);
return model;
}
public static NodeRef getNodeRef(Map<String, String> params)
{
String protocol = params.get(STORE_PROTOCOL);
String storeId= params.get(STORE_ID);
String nodeId= params.get(NODE_ID);
if(protocol == null || storeId == null || nodeId==null )
{
return null;
}
return new NodeRef(protocol, storeId, nodeId);
}
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.ISO8601DateFormat;
/**
* @author Nick Smith
* @since 4.0
*
*/
public class WebScriptUtil
{
// General Keys
public static final String DATA_KEY = "data";
// NodeRef Keys
public static final String STORE_PROTOCOL = "store_protocol";
public static final String STORE_ID = "store_id";
public static final String NODE_ID = "node_id";
// Date/Calendar Keys
public static final String DATE_TIME = "dateTime";
public static final String FORMAT = "format";
public static final String TIME_ZONE = "timeZone";
public static final String ISO8601 = "ISO8601";
public static String getContent(WebScriptRequest request) throws IOException
{
Content content = request.getContent();
return content.getContent();
}
public static Map<String, Object> buildCalendarModel(Calendar calendar)
{
Map<String, Object> model = buildDateModel(calendar.getTime());
model.put(TIME_ZONE, calendar.getTimeZone().getID());
return model;
}
public static Map<String, Object> buildDateModel(Date dateTime)
{
String dateStr = ISO8601DateFormat.format(dateTime);
Map<String, Object> model = new HashMap<String, Object>();
model.put(DATE_TIME, dateStr);
model.put(FORMAT, ISO8601);
return model;
}
public static Calendar getCalendar(JSONObject json) throws ParseException
{
Date date = getDate(json);
if (date == null)
{
return null;
}
Calendar calendar = Calendar.getInstance();
String timeZone = json.optString(TIME_ZONE);
if (timeZone != null)
{
TimeZone zone = TimeZone.getTimeZone(timeZone);
calendar.setTimeZone(zone);
}
calendar.setTime(date);
return calendar;
}
public static Date getDate(JSONObject json) throws ParseException
{
if (json == null)
{
return null;
}
String dateTime = json.optString(DATE_TIME);
if (dateTime == null)
{
return null;
}
String format = json.optString(FORMAT);
if (format != null && ISO8601.equals(format) == false)
{
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
return dateFormat.parse(dateTime);
}
return ISO8601DateFormat.parse(dateTime);
}
public static Map<String, Object> createBaseModel(Map<String, Object> result)
{
Map<String, Object> model = new HashMap<String, Object>();
model.put(DATA_KEY, result);
return model;
}
public static Map<String, Object> createBaseModel(List<Map<String, Object>> results)
{
Map<String, Object> model = new HashMap<String, Object>();
model.put(DATA_KEY, results);
return model;
}
public static NodeRef getNodeRef(Map<String, String> params)
{
String protocol = params.get(STORE_PROTOCOL);
String storeId = params.get(STORE_ID);
String nodeId = params.get(NODE_ID);
if (protocol == null || storeId == null || nodeId == null)
{
return null;
}
return new NodeRef(protocol, storeId, nodeId);
}
public static NodeRef resolveNodeReference(String reference, NodeLocatorService nodeLocatorService)
{
@@ -179,6 +178,6 @@ public class WebScriptUtil
}
return nodeRef;
}
}
}
}

View File

@@ -23,138 +23,133 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.action;
import java.util.Map;
import java.util.NoSuchElementException;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.repo.action.ActionTrackingServiceImpl;
import org.alfresco.repo.action.RuntimeActionService;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.action.ActionStatus;
import org.alfresco.service.cmr.action.ActionTrackingService;
import org.alfresco.service.cmr.action.ExecutionSummary;
import org.alfresco.service.cmr.repository.NodeService;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author Nick Burch
* @since 3.4
*/
public abstract class AbstractActionWebscript extends DeclarativeWebScript
{
protected NodeService nodeService;
protected ActionService actionService;
protected RuntimeActionService runtimeActionService;
protected ActionTrackingService actionTrackingService;
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setActionService(ActionService actionService)
{
this.actionService = actionService;
}
public void setRuntimeActionService(RuntimeActionService runtimeActionService)
{
this.runtimeActionService = runtimeActionService;
}
public void setActionTrackingService(ActionTrackingService actionTrackingService)
{
this.actionTrackingService = actionTrackingService;
}
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
RunningActionModelBuilder modelBuilder = new RunningActionModelBuilder(
nodeService, actionService, actionTrackingService
);
return buildModel(modelBuilder, req, status, cache);
}
protected abstract Map<String, Object> buildModel(
RunningActionModelBuilder modelBuilder,
WebScriptRequest req,
Status status, Cache cache
);
/**
* Takes a running action ID, and returns an
* ExecutionSummary object for it. Note - doesn't
* check to see if the object exists in the
* cache though!
*/
public static ExecutionSummary getSummaryFromKey(String key)
{
return WrappedActionTrackingService.getSummaryFromKey(key);
}
/**
* Returns the ExecutionSummary for the given action if it
* is currently executing, or null if it isn't
*/
public static ExecutionSummary getSummaryFromAction(Action action)
{
// Is it running?
if(action.getExecutionStatus() == ActionStatus.Running) {
return WrappedActionTrackingService.buildExecutionSummary(action);
}
// Has it been given a execution id?
// (eg has already finished, but this one was run)
if( ((ActionImpl)action).getExecutionInstance() != -1 ) {
return WrappedActionTrackingService.buildExecutionSummary(action);
}
// Not running, and hasn't run, we can't help
return null;
}
/**
* Returns the running action ID for the given
* ExecutionSummary
*/
public static String getRunningId(ExecutionSummary summary)
{
return WrappedActionTrackingService.getRunningId(summary);
}
/**
* So we can get at protected methods, which we need as
* we use the same naming scheme as the cache in the
* interests of simplicity.
*/
private static class WrappedActionTrackingService extends ActionTrackingServiceImpl
{
private static String getRunningId(ExecutionSummary summary)
{
return ActionTrackingServiceImpl.generateCacheKey(summary);
}
protected static ExecutionSummary buildExecutionSummary(Action action)
{
return ActionTrackingServiceImpl.buildExecutionSummary(action);
}
private static ExecutionSummary getSummaryFromKey(String key)
{
try {
// Try to have the key turned into a summary for us
return ActionTrackingServiceImpl.buildExecutionSummary(key);
} catch(NoSuchElementException e) {
// Wrong format
return null;
}
}
}
}
package org.alfresco.repo.web.scripts.action;
import java.util.Map;
import java.util.NoSuchElementException;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.repo.action.ActionTrackingServiceImpl;
import org.alfresco.repo.action.RuntimeActionService;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.action.ActionStatus;
import org.alfresco.service.cmr.action.ActionTrackingService;
import org.alfresco.service.cmr.action.ExecutionSummary;
import org.alfresco.service.cmr.repository.NodeService;
/**
* @author Nick Burch
* @since 3.4
*/
public abstract class AbstractActionWebscript extends DeclarativeWebScript
{
protected NodeService nodeService;
protected ActionService actionService;
protected RuntimeActionService runtimeActionService;
protected ActionTrackingService actionTrackingService;
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setActionService(ActionService actionService)
{
this.actionService = actionService;
}
public void setRuntimeActionService(RuntimeActionService runtimeActionService)
{
this.runtimeActionService = runtimeActionService;
}
public void setActionTrackingService(ActionTrackingService actionTrackingService)
{
this.actionTrackingService = actionTrackingService;
}
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
RunningActionModelBuilder modelBuilder = new RunningActionModelBuilder(
nodeService, actionService, actionTrackingService);
return buildModel(modelBuilder, req, status, cache);
}
protected abstract Map<String, Object> buildModel(
RunningActionModelBuilder modelBuilder,
WebScriptRequest req,
Status status, Cache cache);
/**
* Takes a running action ID, and returns an ExecutionSummary object for it. Note - doesn't check to see if the object exists in the cache though!
*/
public static ExecutionSummary getSummaryFromKey(String key)
{
return WrappedActionTrackingService.getSummaryFromKey(key);
}
/**
* Returns the ExecutionSummary for the given action if it is currently executing, or null if it isn't
*/
public static ExecutionSummary getSummaryFromAction(Action action)
{
// Is it running?
if (action.getExecutionStatus() == ActionStatus.Running)
{
return WrappedActionTrackingService.buildExecutionSummary(action);
}
// Has it been given a execution id?
// (eg has already finished, but this one was run)
if (((ActionImpl) action).getExecutionInstance() != -1)
{
return WrappedActionTrackingService.buildExecutionSummary(action);
}
// Not running, and hasn't run, we can't help
return null;
}
/**
* Returns the running action ID for the given ExecutionSummary
*/
public static String getRunningId(ExecutionSummary summary)
{
return WrappedActionTrackingService.getRunningId(summary);
}
/**
* So we can get at protected methods, which we need as we use the same naming scheme as the cache in the interests of simplicity.
*/
private static class WrappedActionTrackingService extends ActionTrackingServiceImpl
{
private static String getRunningId(ExecutionSummary summary)
{
return ActionTrackingServiceImpl.generateCacheKey(summary);
}
protected static ExecutionSummary buildExecutionSummary(Action action)
{
return ActionTrackingServiceImpl.buildExecutionSummary(action);
}
private static ExecutionSummary getSummaryFromKey(String key)
{
try
{
// Try to have the key turned into a summary for us
return ActionTrackingServiceImpl.buildExecutionSummary(key);
}
catch (NoSuchElementException e)
{
// Wrong format
return null;
}
}
}
}

View File

@@ -1,88 +1,89 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.action;
import java.util.Map;
import org.alfresco.repo.action.access.ActionAccessRestriction;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ExecutionSummary;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author Nick Burch
* @since 3.4
*/
public abstract class AbstractExecuteActionWebscript extends AbstractActionWebscript
{
protected Map<String, Object> buildModel(
RunningActionModelBuilder modelBuilder,
WebScriptRequest req,
Status status, Cache cache)
{
try {
// Have the action to run be identified
Action action = identifyAction(req, status, cache);
if(action == null) {
throw new WebScriptException(
Status.STATUS_NOT_FOUND,
"No Runnable Action found with the supplied details"
);
}
// Ask for it to be run in the background
// It will be available to execute once the webscript finishes
ActionAccessRestriction.setActionContext(action, ActionAccessRestriction.V0_ACTION_CONTEXT);
actionService.executeAction(
action, null,
false, true
);
// Return the details if we can
ExecutionSummary summary = getSummaryFromAction(action);
if(summary == null) {
throw new WebScriptException(
Status.STATUS_EXPECTATION_FAILED,
"Action failed to be added to the pending queue"
);
}
return modelBuilder.buildSimpleModel(summary);
} catch(Exception e) {
// Transaction broke
throw new RuntimeException(e);
}
}
protected abstract Action identifyAction(
WebScriptRequest req,
Status status, Cache cache
);
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.action;
import java.util.Map;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.repo.action.access.ActionAccessRestriction;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ExecutionSummary;
/**
* @author Nick Burch
* @since 3.4
*/
public abstract class AbstractExecuteActionWebscript extends AbstractActionWebscript
{
protected Map<String, Object> buildModel(
RunningActionModelBuilder modelBuilder,
WebScriptRequest req,
Status status, Cache cache)
{
try
{
// Have the action to run be identified
Action action = identifyAction(req, status, cache);
if (action == null)
{
throw new WebScriptException(
Status.STATUS_NOT_FOUND,
"No Runnable Action found with the supplied details");
}
// Ask for it to be run in the background
// It will be available to execute once the webscript finishes
ActionAccessRestriction.setActionContext(action, ActionAccessRestriction.V0_ACTION_CONTEXT);
actionService.executeAction(
action, null,
false, true);
// Return the details if we can
ExecutionSummary summary = getSummaryFromAction(action);
if (summary == null)
{
throw new WebScriptException(
Status.STATUS_EXPECTATION_FAILED,
"Action failed to be added to the pending queue");
}
return modelBuilder.buildSimpleModel(summary);
}
catch (Exception e)
{
// Transaction broke
throw new RuntimeException(e);
}
}
protected abstract Action identifyAction(
WebScriptRequest req,
Status status, Cache cache);
}

View File

@@ -23,57 +23,56 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.action;
import java.util.Map;
import org.alfresco.service.cmr.action.ExecutionDetails;
import org.alfresco.service.cmr.action.ExecutionSummary;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author Nick Burch
* @since 3.4
*/
public class RunningActionDelete extends AbstractActionWebscript
{
@Override
protected Map<String, Object> buildModel(
RunningActionModelBuilder modelBuilder, WebScriptRequest req,
Status status, Cache cache) {
// Which action did they ask for?
String actionTrackingId =
req.getServiceMatch().getTemplateVars().get("action_tracking_id");
// Check it exists
ExecutionSummary action =
getSummaryFromKey(actionTrackingId);
if(action == null) {
throw new WebScriptException(
Status.STATUS_NOT_FOUND,
"No Running Action found with that tracking id"
);
}
ExecutionDetails details =
actionTrackingService.getExecutionDetails(action);
if(details == null) {
throw new WebScriptException(
Status.STATUS_NOT_FOUND,
"No Running Action found with that tracking id"
);
}
// Request the cancel
actionTrackingService.requestActionCancellation(action);
// Report it as having been cancelled
status.setCode(Status.STATUS_NO_CONTENT);
status.setMessage("Action cancellation requested");
status.setRedirect(true);
return null;
}
}
package org.alfresco.repo.web.scripts.action;
import java.util.Map;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.service.cmr.action.ExecutionDetails;
import org.alfresco.service.cmr.action.ExecutionSummary;
/**
* @author Nick Burch
* @since 3.4
*/
public class RunningActionDelete extends AbstractActionWebscript
{
@Override
protected Map<String, Object> buildModel(
RunningActionModelBuilder modelBuilder, WebScriptRequest req,
Status status, Cache cache)
{
// Which action did they ask for?
String actionTrackingId = req.getServiceMatch().getTemplateVars().get("action_tracking_id");
// Check it exists
ExecutionSummary action = getSummaryFromKey(actionTrackingId);
if (action == null)
{
throw new WebScriptException(
Status.STATUS_NOT_FOUND,
"No Running Action found with that tracking id");
}
ExecutionDetails details = actionTrackingService.getExecutionDetails(action);
if (details == null)
{
throw new WebScriptException(
Status.STATUS_NOT_FOUND,
"No Running Action found with that tracking id");
}
// Request the cancel
actionTrackingService.requestActionCancellation(action);
// Report it as having been cancelled
status.setCode(Status.STATUS_NO_CONTENT);
status.setMessage("Action cancellation requested");
status.setRedirect(true);
return null;
}
}

View File

@@ -23,43 +23,43 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.action;
import java.util.Map;
import org.alfresco.service.cmr.action.ExecutionSummary;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author Nick Burch
* @since 3.4
*/
public class RunningActionGet extends AbstractActionWebscript
{
@Override
protected Map<String, Object> buildModel(
RunningActionModelBuilder modelBuilder, WebScriptRequest req,
Status status, Cache cache) {
// Which action did they ask for?
String actionTrackingId =
req.getServiceMatch().getTemplateVars().get("action_tracking_id");
ExecutionSummary action =
getSummaryFromKey(actionTrackingId);
// Get the details, if we can
Map<String,Object> model = modelBuilder.buildSimpleModel(action);
if(model == null) {
throw new WebScriptException(
Status.STATUS_NOT_FOUND,
"No Running Action found with that tracking id"
);
}
return model;
}
}
package org.alfresco.repo.web.scripts.action;
import java.util.Map;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.service.cmr.action.ExecutionSummary;
/**
* @author Nick Burch
* @since 3.4
*/
public class RunningActionGet extends AbstractActionWebscript
{
@Override
protected Map<String, Object> buildModel(
RunningActionModelBuilder modelBuilder, WebScriptRequest req,
Status status, Cache cache)
{
// Which action did they ask for?
String actionTrackingId = req.getServiceMatch().getTemplateVars().get("action_tracking_id");
ExecutionSummary action = getSummaryFromKey(actionTrackingId);
// Get the details, if we can
Map<String, Object> model = modelBuilder.buildSimpleModel(action);
if (model == null)
{
throw new WebScriptException(
Status.STATUS_NOT_FOUND,
"No Running Action found with that tracking id");
}
return model;
}
}

View File

@@ -23,123 +23,128 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.action;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.action.ActionTrackingService;
import org.alfresco.service.cmr.action.ExecutionDetails;
import org.alfresco.service.cmr.action.ExecutionSummary;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.util.ISO8601DateFormat;
/**
* Builds up models for running actions
*
* @author Nick Burch
* @since 3.4
*/
public class RunningActionModelBuilder
{
protected static final String MODEL_DATA_ITEM = "runningAction";
protected static final String MODEL_DATA_LIST = "runningActions";
protected static final String ACTION_ID = "id";
protected static final String ACTION_TYPE = "type";
protected static final String ACTION_INSTANCE = "instance";
protected static final String ACTION_NODE_REF = "nodeRef";
protected static final String ACTION_STARTED_AT = "startedAt";
protected static final String ACTION_RUNNING_ON = "runningOn";
protected static final String ACTION_CANCEL_REQUESTED = "cancelRequested";
protected static final String ACTION_KEY = "key";
protected NodeService nodeService;
protected ActionService actionService;
protected ActionTrackingService actionTrackingService;
public RunningActionModelBuilder(NodeService nodeService, ActionService actionService,
ActionTrackingService actionTrackingService)
{
this.nodeService = nodeService;
this.actionService = actionService;
this.actionTrackingService = actionTrackingService;
}
/**
* Build a model containing a single running action
*/
protected Map<String,Object> buildSimpleModel(ExecutionSummary summary)
{
Map<String, Object> ram = buildModel(summary);
if(ram != null) {
Map<String, Object> model = new HashMap<String,Object>();
model.put(MODEL_DATA_ITEM, ram);
return model;
}
return null;
}
/**
* Build a model containing a list of running actions for the given
* list of Running Actions
*/
protected Map<String,Object> buildSimpleList(List<ExecutionSummary> runningActions)
{
List<Map<String,Object>> models = new ArrayList<Map<String,Object>>();
for(ExecutionSummary summary : runningActions) {
Map<String, Object> ram = buildModel(summary);
if(ram != null) {
models.add(ram);
}
}
// Finish up
Map<String, Object> model = new HashMap<String,Object>();
model.put(MODEL_DATA_LIST, models);
return model;
}
/**
* Build a model for a single action
*/
private Map<String,Object> buildModel(ExecutionSummary summary)
{
if(summary == null) {
return null;
}
// Get the details, if we can
ExecutionDetails details = actionTrackingService.getExecutionDetails(summary);
// Only record if still running - may have finished
// between getting the list and now
if(details != null) {
Map<String, Object> ram = new HashMap<String,Object>();
ram.put(ACTION_ID, summary.getActionId());
ram.put(ACTION_TYPE, summary.getActionType());
ram.put(ACTION_INSTANCE, summary.getExecutionInstance());
ram.put(ACTION_KEY, AbstractActionWebscript.getRunningId(summary));
ram.put(ACTION_NODE_REF, details.getPersistedActionRef());
ram.put(ACTION_RUNNING_ON, details.getRunningOn());
ram.put(ACTION_CANCEL_REQUESTED, details.isCancelRequested());
if(details.getStartedAt() != null) {
ram.put(ACTION_STARTED_AT, ISO8601DateFormat.format(details.getStartedAt()));
} else {
ram.put(ACTION_STARTED_AT, null);
}
return ram;
}
return null;
}
}
package org.alfresco.repo.web.scripts.action;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.action.ActionTrackingService;
import org.alfresco.service.cmr.action.ExecutionDetails;
import org.alfresco.service.cmr.action.ExecutionSummary;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.util.ISO8601DateFormat;
/**
* Builds up models for running actions
*
* @author Nick Burch
* @since 3.4
*/
public class RunningActionModelBuilder
{
protected static final String MODEL_DATA_ITEM = "runningAction";
protected static final String MODEL_DATA_LIST = "runningActions";
protected static final String ACTION_ID = "id";
protected static final String ACTION_TYPE = "type";
protected static final String ACTION_INSTANCE = "instance";
protected static final String ACTION_NODE_REF = "nodeRef";
protected static final String ACTION_STARTED_AT = "startedAt";
protected static final String ACTION_RUNNING_ON = "runningOn";
protected static final String ACTION_CANCEL_REQUESTED = "cancelRequested";
protected static final String ACTION_KEY = "key";
protected NodeService nodeService;
protected ActionService actionService;
protected ActionTrackingService actionTrackingService;
public RunningActionModelBuilder(NodeService nodeService, ActionService actionService,
ActionTrackingService actionTrackingService)
{
this.nodeService = nodeService;
this.actionService = actionService;
this.actionTrackingService = actionTrackingService;
}
/**
* Build a model containing a single running action
*/
protected Map<String, Object> buildSimpleModel(ExecutionSummary summary)
{
Map<String, Object> ram = buildModel(summary);
if (ram != null)
{
Map<String, Object> model = new HashMap<String, Object>();
model.put(MODEL_DATA_ITEM, ram);
return model;
}
return null;
}
/**
* Build a model containing a list of running actions for the given list of Running Actions
*/
protected Map<String, Object> buildSimpleList(List<ExecutionSummary> runningActions)
{
List<Map<String, Object>> models = new ArrayList<Map<String, Object>>();
for (ExecutionSummary summary : runningActions)
{
Map<String, Object> ram = buildModel(summary);
if (ram != null)
{
models.add(ram);
}
}
// Finish up
Map<String, Object> model = new HashMap<String, Object>();
model.put(MODEL_DATA_LIST, models);
return model;
}
/**
* Build a model for a single action
*/
private Map<String, Object> buildModel(ExecutionSummary summary)
{
if (summary == null)
{
return null;
}
// Get the details, if we can
ExecutionDetails details = actionTrackingService.getExecutionDetails(summary);
// Only record if still running - may have finished
// between getting the list and now
if (details != null)
{
Map<String, Object> ram = new HashMap<String, Object>();
ram.put(ACTION_ID, summary.getActionId());
ram.put(ACTION_TYPE, summary.getActionType());
ram.put(ACTION_INSTANCE, summary.getExecutionInstance());
ram.put(ACTION_KEY, AbstractActionWebscript.getRunningId(summary));
ram.put(ACTION_NODE_REF, details.getPersistedActionRef());
ram.put(ACTION_RUNNING_ON, details.getRunningOn());
ram.put(ACTION_CANCEL_REQUESTED, details.isCancelRequested());
if (details.getStartedAt() != null)
{
ram.put(ACTION_STARTED_AT, ISO8601DateFormat.format(details.getStartedAt()));
}
else
{
ram.put(ACTION_STARTED_AT, null);
}
return ram;
}
return null;
}
}

View File

@@ -23,45 +23,52 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.action;
import java.util.List;
import java.util.Map;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ExecutionSummary;
import org.alfresco.service.cmr.repository.NodeRef;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author Nick Burch
* @since 3.4
*/
public class RunningActionsGet extends AbstractActionWebscript
{
@Override
protected Map<String, Object> buildModel(
RunningActionModelBuilder modelBuilder, WebScriptRequest req,
Status status, Cache cache) {
List<ExecutionSummary> actions = null;
// Do they want all actions, or only certain ones?
String type = req.getParameter("type");
String nodeRef = req.getParameter("nodeRef");
if(type != null) {
actions = actionTrackingService.getExecutingActions(type);
} else if(nodeRef != null) {
NodeRef actionNodeRef = new NodeRef(nodeRef);
Action action = runtimeActionService.createAction(actionNodeRef);
actions = actionTrackingService.getExecutingActions(action);
} else {
actions = actionTrackingService.getAllExecutingActions();
}
// Build the model list
return modelBuilder.buildSimpleList(actions);
}
}
package org.alfresco.repo.web.scripts.action;
import java.util.List;
import java.util.Map;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ExecutionSummary;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* @author Nick Burch
* @since 3.4
*/
public class RunningActionsGet extends AbstractActionWebscript
{
@Override
protected Map<String, Object> buildModel(
RunningActionModelBuilder modelBuilder, WebScriptRequest req,
Status status, Cache cache)
{
List<ExecutionSummary> actions = null;
// Do they want all actions, or only certain ones?
String type = req.getParameter("type");
String nodeRef = req.getParameter("nodeRef");
if (type != null)
{
actions = actionTrackingService.getExecutingActions(type);
}
else if (nodeRef != null)
{
NodeRef actionNodeRef = new NodeRef(nodeRef);
Action action = runtimeActionService.createAction(actionNodeRef);
actions = actionTrackingService.getExecutingActions(action);
}
else
{
actions = actionTrackingService.getAllExecutingActions();
}
// Build the model list
return modelBuilder.buildSimpleList(actions);
}
}

View File

@@ -23,57 +23,63 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.action;
import java.io.IOException;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author Nick Burch
* @since 3.4
*/
public class RunningActionsPost extends AbstractExecuteActionWebscript
{
@Override
protected Action identifyAction(WebScriptRequest req, Status status,
Cache cache) {
// Which action did they ask for?
String nodeRef = req.getParameter("nodeRef");
if(nodeRef == null) {
try {
JSONObject json = new JSONObject(new JSONTokener(req.getContent().getContent()));
if(! json.has("nodeRef")) {
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not find required 'nodeRef' parameter");
}
nodeRef = json.getString("nodeRef");
}
catch (IOException iox)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not read content from request.", iox);
}
catch (JSONException je)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not parse JSON from request.", je);
}
}
// Does it exist in the repo?
NodeRef actionNodeRef = new NodeRef(nodeRef);
if(! nodeService.exists(actionNodeRef)) {
return null;
}
// Load the specified action
Action action = runtimeActionService.createAction(actionNodeRef);
return action;
}
}
package org.alfresco.repo.web.scripts.action;
import java.io.IOException;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* @author Nick Burch
* @since 3.4
*/
public class RunningActionsPost extends AbstractExecuteActionWebscript
{
@Override
protected Action identifyAction(WebScriptRequest req, Status status,
Cache cache)
{
// Which action did they ask for?
String nodeRef = req.getParameter("nodeRef");
if (nodeRef == null)
{
try
{
JSONObject json = new JSONObject(new JSONTokener(req.getContent().getContent()));
if (!json.has("nodeRef"))
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not find required 'nodeRef' parameter");
}
nodeRef = json.getString("nodeRef");
}
catch (IOException iox)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not read content from request.", iox);
}
catch (JSONException je)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not parse JSON from request.", je);
}
}
// Does it exist in the repo?
NodeRef actionNodeRef = new NodeRef(nodeRef);
if (!nodeService.exists(actionNodeRef))
{
return null;
}
// Load the specified action
Action action = runtimeActionService.createAction(actionNodeRef);
return action;
}
}

View File

@@ -23,59 +23,62 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.action;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.replication.ReplicationDefinitionImpl;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ExecutionSummary;
import org.alfresco.service.cmr.replication.ReplicationDefinition;
import org.alfresco.service.cmr.replication.ReplicationService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author Nick Burch
* @since 3.4
*/
public class RunningReplicationActionsGet extends AbstractActionWebscript
{
private ReplicationService replicationService;
@Override
protected Map<String, Object> buildModel(
RunningActionModelBuilder modelBuilder, WebScriptRequest req,
Status status, Cache cache) {
List<ExecutionSummary> actions = null;
// Do they want all replication actions, or only certain ones?
String name = req.getParameter("name");
if(name != null) {
// Try to find a replication definition with this name
ReplicationDefinition rd = replicationService.loadReplicationDefinition(name);
// Look up what's running
if(rd != null) {
actions = actionTrackingService.getExecutingActions(rd);
}
} else {
// All replication actions
actions = actionTrackingService.getExecutingActions(
ReplicationDefinitionImpl.EXECUTOR_NAME
);
}
// Build the model list
return modelBuilder.buildSimpleList(actions);
}
public void setReplicationService(ReplicationService replicationService)
{
this.replicationService = replicationService;
}
}
package org.alfresco.repo.web.scripts.action;
import java.util.List;
import java.util.Map;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.repo.replication.ReplicationDefinitionImpl;
import org.alfresco.service.cmr.action.ExecutionSummary;
import org.alfresco.service.cmr.replication.ReplicationDefinition;
import org.alfresco.service.cmr.replication.ReplicationService;
/**
* @author Nick Burch
* @since 3.4
*/
public class RunningReplicationActionsGet extends AbstractActionWebscript
{
private ReplicationService replicationService;
@Override
protected Map<String, Object> buildModel(
RunningActionModelBuilder modelBuilder, WebScriptRequest req,
Status status, Cache cache)
{
List<ExecutionSummary> actions = null;
// Do they want all replication actions, or only certain ones?
String name = req.getParameter("name");
if (name != null)
{
// Try to find a replication definition with this name
ReplicationDefinition rd = replicationService.loadReplicationDefinition(name);
// Look up what's running
if (rd != null)
{
actions = actionTrackingService.getExecutingActions(rd);
}
}
else
{
// All replication actions
actions = actionTrackingService.getExecutingActions(
ReplicationDefinitionImpl.EXECUTOR_NAME);
}
// Build the model list
return modelBuilder.buildSimpleList(actions);
}
public void setReplicationService(ReplicationService replicationService)
{
this.replicationService = replicationService;
}
}

View File

@@ -23,60 +23,64 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.action;
import java.io.IOException;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.replication.ReplicationDefinition;
import org.alfresco.service.cmr.replication.ReplicationService;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author Nick Burch
* @since 3.4
*/
public class RunningReplicationActionsPost extends AbstractExecuteActionWebscript
{
private ReplicationService replicationService;
@Override
protected Action identifyAction(WebScriptRequest req, Status status,
Cache cache) {
// Which action did they ask for?
String name = req.getParameter("name");
if(name == null) {
try {
JSONObject json = new JSONObject(new JSONTokener(req.getContent().getContent()));
if(! json.has("name")) {
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not find required 'name' parameter");
}
name = json.getString("name");
}
catch (IOException iox)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not read content from request.", iox);
}
catch (JSONException je)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not parse JSON from request.", je);
}
}
// Load the specified replication definition
ReplicationDefinition replicationDefinition =
replicationService.loadReplicationDefinition(name);
return replicationDefinition;
}
public void setReplicationService(ReplicationService replicationService)
{
this.replicationService = replicationService;
}
}
package org.alfresco.repo.web.scripts.action;
import java.io.IOException;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.replication.ReplicationDefinition;
import org.alfresco.service.cmr.replication.ReplicationService;
/**
* @author Nick Burch
* @since 3.4
*/
public class RunningReplicationActionsPost extends AbstractExecuteActionWebscript
{
private ReplicationService replicationService;
@Override
protected Action identifyAction(WebScriptRequest req, Status status,
Cache cache)
{
// Which action did they ask for?
String name = req.getParameter("name");
if (name == null)
{
try
{
JSONObject json = new JSONObject(new JSONTokener(req.getContent().getContent()));
if (!json.has("name"))
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not find required 'name' parameter");
}
name = json.getString("name");
}
catch (IOException iox)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not read content from request.", iox);
}
catch (JSONException je)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not parse JSON from request.", je);
}
}
// Load the specified replication definition
ReplicationDefinition replicationDefinition = replicationService.loadReplicationDefinition(name);
return replicationDefinition;
}
public void setReplicationService(ReplicationService replicationService)
{
this.replicationService = replicationService;
}
}

View File

@@ -32,14 +32,15 @@ import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.SearchPath;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.alfresco.error.AlfrescoRuntimeException;
/**
* Java-backed WebScript to get a Template from a Template Store
*/
@@ -47,25 +48,25 @@ public class TemplateWebScript extends DeclarativeWebScript
{
// Logger
protected static final Log logger = LogFactory.getLog(TemplateWebScript.class);
private SearchPath searchPath;
public void setSearchPath(SearchPath searchPath)
{
this.searchPath = searchPath;
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
*/
*
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse) */
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
Map<String, Object> model = new HashMap<String, Object>();
// process extension
String path = req.getExtensionPath(); // required
if ((path == null) || (path.length() == 0))
{
String msg = "Failed to getTemplate: missing {path}";
@@ -73,30 +74,34 @@ public class TemplateWebScript extends DeclarativeWebScript
throw new AlfrescoRuntimeException(msg);
}
else
{
{
if (path.endsWith(".ftl"))
{
{
try
{
InputStream is = searchPath.getDocument(path);
if (is != null)
{
{
BufferedReader br = null;
try
{
br = new BufferedReader(new InputStreamReader(is));
String line = null;
StringBuffer sb = new StringBuffer();
while(((line = br.readLine()) !=null))
while (((line = br.readLine()) != null))
{
sb.append(line);
}
model.put("template", sb.toString());
}
finally
{
if (br != null) { br.close(); };
if (br != null)
{
br.close();
}
;
}
}
}
@@ -104,7 +109,7 @@ public class TemplateWebScript extends DeclarativeWebScript
{
logger.error("Failed to getTemplate: " + ioe);
}
}
}
}
return model;
}

View File

@@ -37,41 +37,41 @@ import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.Store;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Java-backed WebScript to get list of Activity Templates from a Template Store
*/
public class TemplatesWebScript extends DeclarativeWebScript
{
private SearchPath searchPath;
public void setSearchPath(SearchPath searchPath)
{
this.searchPath = searchPath;
}
/* (non-Javadoc)
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
*/
*
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse) */
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
String path = "/";
String templatePattern = "*.ftl";
// process extension
String p = req.getExtensionPath(); // optional
if ((p != null) && (p.length() > 0))
{
int idx = p.lastIndexOf("/");
if (idx != -1)
{
path = p.substring(0, idx);
templatePattern = p.substring(idx+1) + ".ftl";
templatePattern = p.substring(idx + 1) + ".ftl";
}
}
Set<String> templatePaths = new HashSet<String>();
for (Store apiStore : searchPath.getStores())
{

View File

@@ -23,116 +23,116 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.activities.feed;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.activities.feed.FeedTaskProcessor;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.service.cmr.activities.ActivityService;
import org.alfresco.util.JSONtoFmModel;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Java-backed WebScript to retrieve Activity Site Feed
*/
public class SiteFeedRetrieverWebScript extends DeclarativeWebScript
{
private static final Log logger = LogFactory.getLog(SiteFeedRetrieverWebScript.class);
private ActivityService activityService;
public void setActivityService(ActivityService activityService)
{
this.activityService = activityService;
}
/* (non-Javadoc)
* @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, Status status)
{
// retrieve requested format
String format = req.getFormat();
if (format == null || format.length() == 0)
{
format = getDescription().getDefaultFormat();
}
String extensionPath = req.getExtensionPath();
String[] extParts = extensionPath == null ? new String[1] : extensionPath.split("/");
String siteId = null;
if (extParts.length == 1)
{
siteId = extParts[0];
}
else
{
throw new AlfrescoRuntimeException("Unexpected extension: " + extensionPath);
}
// map feed collection format to feed entry format (if not the same), eg.
// atomfeed -> atomentry
// atom -> atomentry
if (format.equals("atomfeed") || format.equals("atom"))
{
format = "atomentry";
}
Map<String, Object> model = new HashMap<String, Object>();
try
{
List<String> feedEntries = activityService.getSiteFeedEntries(siteId);
if (format.equals(FeedTaskProcessor.FEED_FORMAT_JSON))
{
model.put("feedEntries", feedEntries);
model.put("siteId", siteId);
}
else
{
List<Map<String, Object>> activityFeedModels = new ArrayList<Map<String, Object>>();
try
{
for (String feedEntry : feedEntries)
{
activityFeedModels.add(JSONtoFmModel.convertJSONObjectToMap(feedEntry));
}
}
catch (JSONException je)
{
throw new AlfrescoRuntimeException("Unable to get user feed entries: " + je.getMessage());
}
model.put("feedEntries", activityFeedModels);
model.put("siteId", siteId);
}
}
catch (AccessDeniedException ade)
{
// implies that site either does not exist or is private (and current user is not admin or a member) - hence return 401 (unauthorised)
String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
status.setCode(Status.STATUS_UNAUTHORIZED);
logger.warn("Unable to get site feed entries for '" + siteId + "' (site does not exist or is private) - currently logged in as '" + currentUser +"'");
model.put("feedEntries", null);
model.put("siteId", "");
}
return model;
}
}
package org.alfresco.repo.web.scripts.activities.feed;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.activities.feed.FeedTaskProcessor;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.service.cmr.activities.ActivityService;
import org.alfresco.util.JSONtoFmModel;
/**
* Java-backed WebScript to retrieve Activity Site Feed
*/
public class SiteFeedRetrieverWebScript extends DeclarativeWebScript
{
private static final Log logger = LogFactory.getLog(SiteFeedRetrieverWebScript.class);
private ActivityService activityService;
public void setActivityService(ActivityService activityService)
{
this.activityService = activityService;
}
/* (non-Javadoc)
*
* @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, Status status)
{
// retrieve requested format
String format = req.getFormat();
if (format == null || format.length() == 0)
{
format = getDescription().getDefaultFormat();
}
String extensionPath = req.getExtensionPath();
String[] extParts = extensionPath == null ? new String[1] : extensionPath.split("/");
String siteId = null;
if (extParts.length == 1)
{
siteId = extParts[0];
}
else
{
throw new AlfrescoRuntimeException("Unexpected extension: " + extensionPath);
}
// map feed collection format to feed entry format (if not the same), eg.
// atomfeed -> atomentry
// atom -> atomentry
if (format.equals("atomfeed") || format.equals("atom"))
{
format = "atomentry";
}
Map<String, Object> model = new HashMap<String, Object>();
try
{
List<String> feedEntries = activityService.getSiteFeedEntries(siteId);
if (format.equals(FeedTaskProcessor.FEED_FORMAT_JSON))
{
model.put("feedEntries", feedEntries);
model.put("siteId", siteId);
}
else
{
List<Map<String, Object>> activityFeedModels = new ArrayList<Map<String, Object>>();
try
{
for (String feedEntry : feedEntries)
{
activityFeedModels.add(JSONtoFmModel.convertJSONObjectToMap(feedEntry));
}
}
catch (JSONException je)
{
throw new AlfrescoRuntimeException("Unable to get user feed entries: " + je.getMessage());
}
model.put("feedEntries", activityFeedModels);
model.put("siteId", siteId);
}
}
catch (AccessDeniedException ade)
{
// implies that site either does not exist or is private (and current user is not admin or a member) - hence return 401 (unauthorised)
String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
status.setCode(Status.STATUS_UNAUTHORIZED);
logger.warn("Unable to get site feed entries for '" + siteId + "' (site does not exist or is private) - currently logged in as '" + currentUser + "'");
model.put("feedEntries", null);
model.put("siteId", "");
}
return model;
}
}

View File

@@ -23,195 +23,197 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.activities.feed;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.query.PagingRequest;
import org.alfresco.repo.activities.feed.FeedTaskProcessor;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.service.cmr.activities.ActivityService;
import org.alfresco.service.cmr.subscriptions.PagingFollowingResults;
import org.alfresco.service.cmr.subscriptions.SubscriptionService;
import org.alfresco.util.JSONtoFmModel;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Java-backed WebScript to retrieve Activity User Feed
*/
public class UserFeedRetrieverWebScript extends DeclarativeWebScript
{
private static final Log logger = LogFactory.getLog(UserFeedRetrieverWebScript.class);
// URL request parameter names
public static final String PARAM_SITE_ID = "s";
public static final String PARAM_EXCLUDE_THIS_USER = "exclUser";
public static final String PARAM_EXCLUDE_OTHER_USERS = "exclOthers";
public static final String PARAM_ONLY_FOLLOWING = "following";
public static final String PARAM_ACTIVITY_FILTER = "activityFilter";
private ActivityService activityService;
private SubscriptionService subscriptionService;
private boolean userNamesAreCaseSensitive = false;
public void setActivityService(ActivityService activityService)
{
this.activityService = activityService;
}
public void setSubscriptionService(SubscriptionService subscriptionService)
{
this.subscriptionService = subscriptionService;
}
public void setUserNamesAreCaseSensitive(boolean userNamesAreCaseSensitive)
{
this.userNamesAreCaseSensitive = userNamesAreCaseSensitive;
}
/* (non-Javadoc)
* @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, Status status)
{
// retrieve requested format
String format = req.getFormat();
if (format == null || format.length() == 0)
{
format = getDescription().getDefaultFormat();
}
// process extension
String extensionPath = req.getExtensionPath();
String[] extParts = extensionPath == null ? new String[1] : extensionPath.split("/");
String feedUserId = null;
if (extParts.length == 1)
{
feedUserId = extParts[0];
}
else if (extParts.length > 1)
{
throw new AlfrescoRuntimeException("Unexpected extension: " + extensionPath);
}
// process arguments
String siteId = req.getParameter(PARAM_SITE_ID); // optional
String exclThisUserStr = req.getParameter(PARAM_EXCLUDE_THIS_USER); // optional
String exclOtherUsersStr = req.getParameter(PARAM_EXCLUDE_OTHER_USERS); // optional
String onlyFollowingStr = req.getParameter(PARAM_ONLY_FOLLOWING); // optional
String activityFilterStr = req.getParameter(PARAM_ACTIVITY_FILTER); // optional
boolean exclThisUser = false;
if ((exclThisUserStr != null) && (exclThisUserStr.equalsIgnoreCase("true") || exclThisUserStr.equalsIgnoreCase("t")))
{
exclThisUser = true;
}
boolean exclOtherUsers = false;
if ((exclOtherUsersStr != null) && (exclOtherUsersStr.equalsIgnoreCase("true") || exclOtherUsersStr.equalsIgnoreCase("t")))
{
exclOtherUsers = true;
}
Set<String> userFilter = null;
if ((onlyFollowingStr != null) && (onlyFollowingStr.equalsIgnoreCase("true") || onlyFollowingStr.equalsIgnoreCase("t")))
{
userFilter = new HashSet<String>();
if (subscriptionService.isActive()) {
PagingFollowingResults following = subscriptionService.getFollowing(AuthenticationUtil.getRunAsUser(), new PagingRequest(-1, null));
if (following.getPage() != null)
{
for (String userName : following.getPage())
{
userFilter.add(this.userNamesAreCaseSensitive ? userName : userName.toLowerCase());
}
}
}
}
Set<String> activityFilter = null;
if (activityFilterStr != null)
{
activityFilter = new HashSet<String>();
String[] activities = activityFilterStr.split(",");
for (String s : activities)
{
if (s.trim().length() > 0)
{
activityFilter.add(s.trim());
}
}
if (activityFilter.size() == 0)
{
activityFilter = null;
}
}
if ((feedUserId == null) || (feedUserId.length() == 0))
{
feedUserId = AuthenticationUtil.getFullyAuthenticatedUser();
}
// map feed collection format to feed entry format (if not the same), eg.
// atomfeed -> atomentry
// atom -> atomentry
if (format.equals("atomfeed") || format.equals("atom"))
{
format = "atomentry";
}
Map<String, Object> model = new HashMap<String, Object>();
try
{
List<String> feedEntries = activityService.getUserFeedEntries(feedUserId, siteId, exclThisUser, exclOtherUsers, userFilter, activityFilter);
if (format.equals(FeedTaskProcessor.FEED_FORMAT_JSON))
{
model.put("feedEntries", feedEntries);
model.put("siteId", siteId);
}
else
{
List<Map<String, Object>> activityFeedModels = new ArrayList<Map<String, Object>>();
try
{
for (String feedEntry : feedEntries)
{
activityFeedModels.add(JSONtoFmModel.convertJSONObjectToMap(feedEntry));
}
}
catch (JSONException je)
{
throw new AlfrescoRuntimeException("Unable to get user feed entries: " + je.getMessage());
}
model.put("feedEntries", activityFeedModels);
model.put("feedUserId", feedUserId);
}
}
catch (AccessDeniedException ade)
{
status.setCode(Status.STATUS_UNAUTHORIZED);
logger.warn("Unable to get user feed entries for '" + feedUserId + "' - currently logged in as '" + AuthenticationUtil.getFullyAuthenticatedUser() +"'");
return null;
}
return model;
}
}
package org.alfresco.repo.web.scripts.activities.feed;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.query.PagingRequest;
import org.alfresco.repo.activities.feed.FeedTaskProcessor;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.service.cmr.activities.ActivityService;
import org.alfresco.service.cmr.subscriptions.PagingFollowingResults;
import org.alfresco.service.cmr.subscriptions.SubscriptionService;
import org.alfresco.util.JSONtoFmModel;
/**
* Java-backed WebScript to retrieve Activity User Feed
*/
public class UserFeedRetrieverWebScript extends DeclarativeWebScript
{
private static final Log logger = LogFactory.getLog(UserFeedRetrieverWebScript.class);
// URL request parameter names
public static final String PARAM_SITE_ID = "s";
public static final String PARAM_EXCLUDE_THIS_USER = "exclUser";
public static final String PARAM_EXCLUDE_OTHER_USERS = "exclOthers";
public static final String PARAM_ONLY_FOLLOWING = "following";
public static final String PARAM_ACTIVITY_FILTER = "activityFilter";
private ActivityService activityService;
private SubscriptionService subscriptionService;
private boolean userNamesAreCaseSensitive = false;
public void setActivityService(ActivityService activityService)
{
this.activityService = activityService;
}
public void setSubscriptionService(SubscriptionService subscriptionService)
{
this.subscriptionService = subscriptionService;
}
public void setUserNamesAreCaseSensitive(boolean userNamesAreCaseSensitive)
{
this.userNamesAreCaseSensitive = userNamesAreCaseSensitive;
}
/* (non-Javadoc)
*
* @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, Status status)
{
// retrieve requested format
String format = req.getFormat();
if (format == null || format.length() == 0)
{
format = getDescription().getDefaultFormat();
}
// process extension
String extensionPath = req.getExtensionPath();
String[] extParts = extensionPath == null ? new String[1] : extensionPath.split("/");
String feedUserId = null;
if (extParts.length == 1)
{
feedUserId = extParts[0];
}
else if (extParts.length > 1)
{
throw new AlfrescoRuntimeException("Unexpected extension: " + extensionPath);
}
// process arguments
String siteId = req.getParameter(PARAM_SITE_ID); // optional
String exclThisUserStr = req.getParameter(PARAM_EXCLUDE_THIS_USER); // optional
String exclOtherUsersStr = req.getParameter(PARAM_EXCLUDE_OTHER_USERS); // optional
String onlyFollowingStr = req.getParameter(PARAM_ONLY_FOLLOWING); // optional
String activityFilterStr = req.getParameter(PARAM_ACTIVITY_FILTER); // optional
boolean exclThisUser = false;
if ((exclThisUserStr != null) && (exclThisUserStr.equalsIgnoreCase("true") || exclThisUserStr.equalsIgnoreCase("t")))
{
exclThisUser = true;
}
boolean exclOtherUsers = false;
if ((exclOtherUsersStr != null) && (exclOtherUsersStr.equalsIgnoreCase("true") || exclOtherUsersStr.equalsIgnoreCase("t")))
{
exclOtherUsers = true;
}
Set<String> userFilter = null;
if ((onlyFollowingStr != null) && (onlyFollowingStr.equalsIgnoreCase("true") || onlyFollowingStr.equalsIgnoreCase("t")))
{
userFilter = new HashSet<String>();
if (subscriptionService.isActive())
{
PagingFollowingResults following = subscriptionService.getFollowing(AuthenticationUtil.getRunAsUser(), new PagingRequest(-1, null));
if (following.getPage() != null)
{
for (String userName : following.getPage())
{
userFilter.add(this.userNamesAreCaseSensitive ? userName : userName.toLowerCase());
}
}
}
}
Set<String> activityFilter = null;
if (activityFilterStr != null)
{
activityFilter = new HashSet<String>();
String[] activities = activityFilterStr.split(",");
for (String s : activities)
{
if (s.trim().length() > 0)
{
activityFilter.add(s.trim());
}
}
if (activityFilter.size() == 0)
{
activityFilter = null;
}
}
if ((feedUserId == null) || (feedUserId.length() == 0))
{
feedUserId = AuthenticationUtil.getFullyAuthenticatedUser();
}
// map feed collection format to feed entry format (if not the same), eg.
// atomfeed -> atomentry
// atom -> atomentry
if (format.equals("atomfeed") || format.equals("atom"))
{
format = "atomentry";
}
Map<String, Object> model = new HashMap<String, Object>();
try
{
List<String> feedEntries = activityService.getUserFeedEntries(feedUserId, siteId, exclThisUser, exclOtherUsers, userFilter, activityFilter);
if (format.equals(FeedTaskProcessor.FEED_FORMAT_JSON))
{
model.put("feedEntries", feedEntries);
model.put("siteId", siteId);
}
else
{
List<Map<String, Object>> activityFeedModels = new ArrayList<Map<String, Object>>();
try
{
for (String feedEntry : feedEntries)
{
activityFeedModels.add(JSONtoFmModel.convertJSONObjectToMap(feedEntry));
}
}
catch (JSONException je)
{
throw new AlfrescoRuntimeException("Unable to get user feed entries: " + je.getMessage());
}
model.put("feedEntries", activityFeedModels);
model.put("feedUserId", feedUserId);
}
}
catch (AccessDeniedException ade)
{
status.setCode(Status.STATUS_UNAUTHORIZED);
logger.warn("Unable to get user feed entries for '" + feedUserId + "' - currently logged in as '" + AuthenticationUtil.getFullyAuthenticatedUser() + "'");
return null;
}
return model;
}
}

View File

@@ -23,100 +23,104 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.admin;
import java.util.Collections;
import java.util.Map;
import org.alfresco.service.cmr.admin.RepoAdminService;
import org.alfresco.service.cmr.admin.RepoUsage;
import org.alfresco.service.cmr.admin.RepoUsageStatus.RepoUsageLevel;
import org.alfresco.service.descriptor.DescriptorService;
import org.alfresco.service.license.LicenseDescriptor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
/**
* Abstract implementation for scripts that access the {@link RepoAdminService}.
*
* @author Derek Hulley
* @since 3.4
*/
public abstract class AbstractAdminWebScript extends DeclarativeWebScript
{
public static final String JSON_KEY_LAST_UPDATE = "lastUpdate";
public static final String JSON_KEY_USERS = "users";
public static final String JSON_KEY_DOCUMENTS = "documents";
public static final String JSON_KEY_LICENSE_MODE = "licenseMode";
public static final String JSON_KEY_READ_ONLY = "readOnly";
public static final String JSON_KEY_UPDATED = "updated";
public static final String JSON_KEY_LICENSE_VALID_UNTIL = "licenseValidUntil";
public static final String JSON_KEY_LICENSE_HOLDER = "licenseHolder";
public static final String JSON_KEY_LEVEL = "level";
public static final String JSON_KEY_WARNINGS = "warnings";
public static final String JSON_KEY_ERRORS = "errors";
/**
* Logger that can be used by subclasses.
*/
protected final Log logger = LogFactory.getLog(this.getClass());
protected RepoAdminService repoAdminService;
protected DescriptorService descriptorService;
/**
* @param repoAdminService the service that provides the functionality
*/
public void setRepoAdminService(RepoAdminService repoAdminService)
{
this.repoAdminService = repoAdminService;
}
/**
* @param descriptorService the service that provides the functionality
*/
public void setDescriptorService(DescriptorService descriptorService)
{
this.descriptorService = descriptorService;
}
/**
* Return an I18N'd message for the given key or the key itself if not present
*
* @param args arguments to replace the variables in the message
*/
protected String getI18NMessage(String key, Object ... args)
{
return I18NUtil.getMessage(key, args);
}
/**
* Helper to assign JSON return variables based on the repository usage data.
*/
protected void putUsageInModel(
Map<String, Object> model,
RepoUsage repoUsage,
boolean updated)
{
model.put(JSON_KEY_LAST_UPDATE, repoUsage.getLastUpdate());
model.put(JSON_KEY_USERS, repoUsage.getUsers());
model.put(JSON_KEY_DOCUMENTS, repoUsage.getDocuments());
model.put(JSON_KEY_LICENSE_MODE, repoUsage.getLicenseMode());
model.put(JSON_KEY_READ_ONLY, repoUsage.isReadOnly());
model.put(JSON_KEY_LICENSE_VALID_UNTIL, repoUsage.getLicenseExpiryDate());
model.put(JSON_KEY_UPDATED, updated);
// Add license holder
LicenseDescriptor license = descriptorService.getLicenseDescriptor();
if (license != null)
{
model.put(JSON_KEY_LICENSE_HOLDER, license.getHolderOrganisation());
}
model.put(JSON_KEY_LEVEL, RepoUsageLevel.OK.ordinal());
model.put(JSON_KEY_WARNINGS, Collections.emptyList());
model.put(JSON_KEY_ERRORS, Collections.emptyList());
}
}
package org.alfresco.repo.web.scripts.admin;
import java.util.Collections;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.alfresco.service.cmr.admin.RepoAdminService;
import org.alfresco.service.cmr.admin.RepoUsage;
import org.alfresco.service.cmr.admin.RepoUsageStatus.RepoUsageLevel;
import org.alfresco.service.descriptor.DescriptorService;
import org.alfresco.service.license.LicenseDescriptor;
/**
* Abstract implementation for scripts that access the {@link RepoAdminService}.
*
* @author Derek Hulley
* @since 3.4
*/
public abstract class AbstractAdminWebScript extends DeclarativeWebScript
{
public static final String JSON_KEY_LAST_UPDATE = "lastUpdate";
public static final String JSON_KEY_USERS = "users";
public static final String JSON_KEY_DOCUMENTS = "documents";
public static final String JSON_KEY_LICENSE_MODE = "licenseMode";
public static final String JSON_KEY_READ_ONLY = "readOnly";
public static final String JSON_KEY_UPDATED = "updated";
public static final String JSON_KEY_LICENSE_VALID_UNTIL = "licenseValidUntil";
public static final String JSON_KEY_LICENSE_HOLDER = "licenseHolder";
public static final String JSON_KEY_LEVEL = "level";
public static final String JSON_KEY_WARNINGS = "warnings";
public static final String JSON_KEY_ERRORS = "errors";
/**
* Logger that can be used by subclasses.
*/
protected final Log logger = LogFactory.getLog(this.getClass());
protected RepoAdminService repoAdminService;
protected DescriptorService descriptorService;
/**
* @param repoAdminService
* the service that provides the functionality
*/
public void setRepoAdminService(RepoAdminService repoAdminService)
{
this.repoAdminService = repoAdminService;
}
/**
* @param descriptorService
* the service that provides the functionality
*/
public void setDescriptorService(DescriptorService descriptorService)
{
this.descriptorService = descriptorService;
}
/**
* Return an I18N'd message for the given key or the key itself if not present
*
* @param args
* arguments to replace the variables in the message
*/
protected String getI18NMessage(String key, Object... args)
{
return I18NUtil.getMessage(key, args);
}
/**
* Helper to assign JSON return variables based on the repository usage data.
*/
protected void putUsageInModel(
Map<String, Object> model,
RepoUsage repoUsage,
boolean updated)
{
model.put(JSON_KEY_LAST_UPDATE, repoUsage.getLastUpdate());
model.put(JSON_KEY_USERS, repoUsage.getUsers());
model.put(JSON_KEY_DOCUMENTS, repoUsage.getDocuments());
model.put(JSON_KEY_LICENSE_MODE, repoUsage.getLicenseMode());
model.put(JSON_KEY_READ_ONLY, repoUsage.isReadOnly());
model.put(JSON_KEY_LICENSE_VALID_UNTIL, repoUsage.getLicenseExpiryDate());
model.put(JSON_KEY_UPDATED, updated);
// Add license holder
LicenseDescriptor license = descriptorService.getLicenseDescriptor();
if (license != null)
{
model.put(JSON_KEY_LICENSE_HOLDER, license.getHolderOrganisation());
}
model.put(JSON_KEY_LEVEL, RepoUsageLevel.OK.ordinal());
model.put(JSON_KEY_WARNINGS, Collections.emptyList());
model.put(JSON_KEY_ERRORS, Collections.emptyList());
}
}

View File

@@ -32,11 +32,9 @@ import org.alfresco.repo.admin.BaseInterpreter;
import org.alfresco.repo.processor.BaseProcessorExtension;
/**
* Console Interpeter script extension - dynamically binds to the configured BaseInterpreter instance.
* This avoids the need for a specific bean class per script interpreter.
* Console Interpeter script extension - dynamically binds to the configured BaseInterpreter instance. This avoids the need for a specific bean class per script interpreter.
*
* @see org.alfresco.repo.admin.BaseInterpreter
* See script beans configured in 'web-scripts-application-context.xml'.
* @see org.alfresco.repo.admin.BaseInterpreter See script beans configured in 'web-scripts-application-context.xml'.
*
* @author Kevin Roast
* @since 5.1
@@ -47,33 +45,35 @@ public class DynamicInterpreterExtension extends BaseProcessorExtension
private long duration;
private String result = "";
private String command = "";
/**
* Set the BaseInterpreter to use when executing commands and retrieving the command result.
*
* @param interpreter For example, repoAdminInterpreter
* @param interpreter
* For example, repoAdminInterpreter
*/
public void setInterpreter(BaseInterpreter interpreter)
{
this.interpreter = interpreter;
}
private BaseInterpreter getInterpreter()
{
return this.interpreter;
}
/**
* Script execute command gateway.
*
* @param command string to execute
* @param command
* string to execute
*/
public void executeCmd(String command)
{
this.command = command;
this.interpretCommand(command);
}
/**
* @return the command duration
*/
@@ -101,7 +101,8 @@ public class DynamicInterpreterExtension extends BaseProcessorExtension
/**
* Interpret console command using the configured Interpreter
*
* @param command command
* @param command
* command
*/
private void interpretCommand(String command)
{

View File

@@ -23,37 +23,38 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.admin;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.service.cmr.admin.RepoUsage;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* GET the repository {@link RepoUsage restrictions}.
*
* @author Derek Hulley
* @since 3.4
*/
public class RepoRestrictionsGet extends AbstractAdminWebScript
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>(7);
RepoUsage restrictions = repoAdminService.getRestrictions();
putUsageInModel(model, restrictions, false);
// Done
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}
package org.alfresco.repo.web.scripts.admin;
import java.util.HashMap;
import java.util.Map;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.service.cmr.admin.RepoUsage;
/**
* GET the repository {@link RepoUsage restrictions}.
*
* @author Derek Hulley
* @since 3.4
*/
public class RepoRestrictionsGet extends AbstractAdminWebScript
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>(7);
RepoUsage restrictions = repoAdminService.getRestrictions();
putUsageInModel(model, restrictions, false);
// Done
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}

View File

@@ -23,59 +23,59 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.admin;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.service.cmr.admin.RepoUsage;
import org.alfresco.service.cmr.admin.RepoUsageStatus;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* GET the repository {@link RepoUsage usage}.
*
* @author Derek Hulley
* @since 3.4
*/
public class RepoUsageGet extends AbstractAdminWebScript
{
@Override
protected Map<String, Object> executeImpl(final WebScriptRequest req, final Status status, final Cache cache)
{
// Runas system to obtain the info
RunAsWork<Map<String, Object>> runAs = new RunAsWork<Map<String,Object>>()
{
@Override
public Map<String, Object> doWork() throws Exception
{
Map<String, Object> model = new HashMap<String, Object>(7);
RepoUsageStatus usageStatus = repoAdminService.getUsageStatus();
RepoUsage usage = usageStatus.getUsage();
putUsageInModel(
model,
usage,
false);
// Add usage messages
model.put(JSON_KEY_LEVEL, usageStatus.getLevel().ordinal());
model.put(JSON_KEY_WARNINGS, usageStatus.getWarnings());
model.put(JSON_KEY_ERRORS, usageStatus.getErrors());
// Done
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
};
return AuthenticationUtil.runAs(runAs, AuthenticationUtil.getSystemUserName());
}
}
package org.alfresco.repo.web.scripts.admin;
import java.util.HashMap;
import java.util.Map;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.service.cmr.admin.RepoUsage;
import org.alfresco.service.cmr.admin.RepoUsageStatus;
/**
* GET the repository {@link RepoUsage usage}.
*
* @author Derek Hulley
* @since 3.4
*/
public class RepoUsageGet extends AbstractAdminWebScript
{
@Override
protected Map<String, Object> executeImpl(final WebScriptRequest req, final Status status, final Cache cache)
{
// Runas system to obtain the info
RunAsWork<Map<String, Object>> runAs = new RunAsWork<Map<String, Object>>() {
@Override
public Map<String, Object> doWork() throws Exception
{
Map<String, Object> model = new HashMap<String, Object>(7);
RepoUsageStatus usageStatus = repoAdminService.getUsageStatus();
RepoUsage usage = usageStatus.getUsage();
putUsageInModel(
model,
usage,
false);
// Add usage messages
model.put(JSON_KEY_LEVEL, usageStatus.getLevel().ordinal());
model.put(JSON_KEY_WARNINGS, usageStatus.getWarnings());
model.put(JSON_KEY_ERRORS, usageStatus.getErrors());
// Done
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
};
return AuthenticationUtil.runAs(runAs, AuthenticationUtil.getSystemUserName());
}
}

View File

@@ -23,40 +23,41 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.admin;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.service.cmr.admin.RepoUsage;
import org.alfresco.service.cmr.admin.RepoUsage.UsageType;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* GET the repository {@link RepoUsage usage}.
*
* @author Derek Hulley
* @since 3.4
*/
public class RepoUsagePost extends AbstractAdminWebScript
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>(7);
boolean updated = repoAdminService.updateUsage(UsageType.USAGE_ALL);
RepoUsage repoUsage = repoAdminService.getUsage();
putUsageInModel(model, repoUsage, updated);
// Done
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}
package org.alfresco.repo.web.scripts.admin;
import java.util.HashMap;
import java.util.Map;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.service.cmr.admin.RepoUsage;
import org.alfresco.service.cmr.admin.RepoUsage.UsageType;
/**
* GET the repository {@link RepoUsage usage}.
*
* @author Derek Hulley
* @since 3.4
*/
public class RepoUsagePost extends AbstractAdminWebScript
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>(7);
boolean updated = repoAdminService.updateUsage(UsageType.USAGE_ALL);
RepoUsage repoUsage = repoAdminService.getUsage();
putUsageInModel(model, repoUsage, updated);
// Done
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}

View File

@@ -1,201 +1,208 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.archive;
import java.util.Map;
import jakarta.servlet.http.HttpServletResponse;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.node.archive.ArchivedNodesCannedQueryBuilder;
import org.alfresco.repo.node.archive.NodeArchiveService;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.util.ScriptPagingDetails;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* This class is an abstract base class for the various webscript controllers in the
* NodeArchiveService.
*
* @author Neil McErlean, Jamal Kaabi-Mofrad
* @since 3.5
*/
public abstract class AbstractArchivedNodeWebScript extends DeclarativeWebScript
{
public static final String NAME = "name";
public static final String TITLE = "title";
public static final String DESCRIPTION = "description";
public static final String NODEREF = "nodeRef";
public static final String ARCHIVED_BY = "archivedBy";
public static final String ARCHIVED_DATE = "archivedDate";
public static final String DISPLAY_PATH = "displayPath";
public static final String USER_NAME = "userName";
public static final String FIRST_NAME = "firstName";
public static final String LAST_NAME = "lastName";
public static final String NODE_TYPE = "nodeType";
public static final String DELETED_NODES = "deletedNodes";
public static final int DEFAULT_MAX_ITEMS_PER_PAGE = 50;
// Injected services
protected ServiceRegistry serviceRegistry;
protected NodeArchiveService nodeArchiveService;
protected int maxSizeView = 1000;
/**
* Sets the serviceRegistry instance
*
* @param serviceRegistry the serviceRegistry to set
*/
public void setServiceRegistry(ServiceRegistry serviceRegistry)
{
this.serviceRegistry = serviceRegistry;
}
/**
* Sets the nodeArchiveService instance
*
* @param nodeArchiveService the nodeArchiveService to set
*/
public void setNodeArchiveService(NodeArchiveService nodeArchiveService)
{
this.nodeArchiveService = nodeArchiveService;
}
/**
* Sets the maxSizeView
*
* @param maxSizeView the maxSizeView
*/
public void setMaxSizeView(int maxSizeView)
{
this.maxSizeView = maxSizeView;
}
protected StoreRef parseRequestForStoreRef(WebScriptRequest req)
{
// get the parameters that represent the StoreRef, we know they are present
// otherwise this webscript would not have matched
Map<String, String> templateVars = req.getServiceMatch().getTemplateVars();
String storeType = templateVars.get("store_type");
String storeId = templateVars.get("store_id");
// create the StoreRef and ensure it is valid
StoreRef storeRef = new StoreRef(storeType, storeId);
return storeRef;
}
protected NodeRef parseRequestForNodeRef(WebScriptRequest req)
{
// get the parameters that represent the NodeRef. They may not all be there
// for all deletednodes webscripts.
Map<String, String> templateVars = req.getServiceMatch().getTemplateVars();
String storeType = templateVars.get("store_type");
String storeId = templateVars.get("store_id");
String id = templateVars.get("id");
if (id == null || id.trim().length() == 0)
{
return null;
}
else
{
return new NodeRef(storeType, storeId, id);
}
}
/**
* Retrieves the named parameter as an integer, if the parameter is not present the default value is returned
*
* @param req The WebScript request
* @param paramName The name of parameter to look for
* @param defaultValue The default value that should be returned if parameter is not present in request or if it is not positive
* @return The request parameter or default value
*/
protected int getIntParameter(WebScriptRequest req, String paramName, int defaultValue)
{
String paramString = req.getParameter(paramName);
if (paramString != null)
{
try
{
int param = Integer.valueOf(paramString);
if (param >= 0)
{
return param;
}
}
catch (NumberFormatException e)
{
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
}
}
return defaultValue;
}
/**
* * This method gets all nodes from the archive which were originally
* contained within the specified StoreRef.
*
* @param storeRef mandatory store ref
* @param paging mandatory paging
* @param filter optional filter
*/
protected PagingResults<NodeRef> getArchivedNodesFrom(StoreRef storeRef, ScriptPagingDetails paging, String filter)
{
NodeService nodeService = serviceRegistry.getNodeService();
NodeRef archiveStoreRootNodeRef = nodeService.getStoreArchiveNode(storeRef);
// Create canned query
ArchivedNodesCannedQueryBuilder queryBuilder = new ArchivedNodesCannedQueryBuilder.Builder(
archiveStoreRootNodeRef, paging).filter(filter)
.sortOrderAscending(false).build();
// Query the DB
PagingResults<NodeRef> result = nodeArchiveService.listArchivedNodes(queryBuilder);
return result;
}
protected void validatePermission(NodeRef nodeRef, String currentUser)
{
if (!nodeArchiveService.hasFullAccess(nodeRef))
{
throw new WebScriptException(Status.STATUS_FORBIDDEN, "You don't have permission to act on the node.");
}
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.archive;
import java.util.Map;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.node.archive.ArchivedNodesCannedQueryBuilder;
import org.alfresco.repo.node.archive.NodeArchiveService;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.util.ScriptPagingDetails;
/**
* This class is an abstract base class for the various webscript controllers in the NodeArchiveService.
*
* @author Neil McErlean, Jamal Kaabi-Mofrad
* @since 3.5
*/
public abstract class AbstractArchivedNodeWebScript extends DeclarativeWebScript
{
public static final String NAME = "name";
public static final String TITLE = "title";
public static final String DESCRIPTION = "description";
public static final String NODEREF = "nodeRef";
public static final String ARCHIVED_BY = "archivedBy";
public static final String ARCHIVED_DATE = "archivedDate";
public static final String DISPLAY_PATH = "displayPath";
public static final String USER_NAME = "userName";
public static final String FIRST_NAME = "firstName";
public static final String LAST_NAME = "lastName";
public static final String NODE_TYPE = "nodeType";
public static final String DELETED_NODES = "deletedNodes";
public static final int DEFAULT_MAX_ITEMS_PER_PAGE = 50;
// Injected services
protected ServiceRegistry serviceRegistry;
protected NodeArchiveService nodeArchiveService;
protected int maxSizeView = 1000;
/**
* Sets the serviceRegistry instance
*
* @param serviceRegistry
* the serviceRegistry to set
*/
public void setServiceRegistry(ServiceRegistry serviceRegistry)
{
this.serviceRegistry = serviceRegistry;
}
/**
* Sets the nodeArchiveService instance
*
* @param nodeArchiveService
* the nodeArchiveService to set
*/
public void setNodeArchiveService(NodeArchiveService nodeArchiveService)
{
this.nodeArchiveService = nodeArchiveService;
}
/**
* Sets the maxSizeView
*
* @param maxSizeView
* the maxSizeView
*/
public void setMaxSizeView(int maxSizeView)
{
this.maxSizeView = maxSizeView;
}
protected StoreRef parseRequestForStoreRef(WebScriptRequest req)
{
// get the parameters that represent the StoreRef, we know they are present
// otherwise this webscript would not have matched
Map<String, String> templateVars = req.getServiceMatch().getTemplateVars();
String storeType = templateVars.get("store_type");
String storeId = templateVars.get("store_id");
// create the StoreRef and ensure it is valid
StoreRef storeRef = new StoreRef(storeType, storeId);
return storeRef;
}
protected NodeRef parseRequestForNodeRef(WebScriptRequest req)
{
// get the parameters that represent the NodeRef. They may not all be there
// for all deletednodes webscripts.
Map<String, String> templateVars = req.getServiceMatch().getTemplateVars();
String storeType = templateVars.get("store_type");
String storeId = templateVars.get("store_id");
String id = templateVars.get("id");
if (id == null || id.trim().length() == 0)
{
return null;
}
else
{
return new NodeRef(storeType, storeId, id);
}
}
/**
* Retrieves the named parameter as an integer, if the parameter is not present the default value is returned
*
* @param req
* The WebScript request
* @param paramName
* The name of parameter to look for
* @param defaultValue
* The default value that should be returned if parameter is not present in request or if it is not positive
* @return The request parameter or default value
*/
protected int getIntParameter(WebScriptRequest req, String paramName, int defaultValue)
{
String paramString = req.getParameter(paramName);
if (paramString != null)
{
try
{
int param = Integer.valueOf(paramString);
if (param >= 0)
{
return param;
}
}
catch (NumberFormatException e)
{
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
}
}
return defaultValue;
}
/**
* * This method gets all nodes from the archive which were originally contained within the specified StoreRef.
*
* @param storeRef
* mandatory store ref
* @param paging
* mandatory paging
* @param filter
* optional filter
*/
protected PagingResults<NodeRef> getArchivedNodesFrom(StoreRef storeRef, ScriptPagingDetails paging, String filter)
{
NodeService nodeService = serviceRegistry.getNodeService();
NodeRef archiveStoreRootNodeRef = nodeService.getStoreArchiveNode(storeRef);
// Create canned query
ArchivedNodesCannedQueryBuilder queryBuilder = new ArchivedNodesCannedQueryBuilder.Builder(
archiveStoreRootNodeRef, paging).filter(filter)
.sortOrderAscending(false).build();
// Query the DB
PagingResults<NodeRef> result = nodeArchiveService.listArchivedNodes(queryBuilder);
return result;
}
protected void validatePermission(NodeRef nodeRef, String currentUser)
{
if (!nodeArchiveService.hasFullAccess(nodeRef))
{
throw new WebScriptException(Status.STATUS_FORBIDDEN, "You don't have permission to act on the node.");
}
}
}

View File

@@ -1,97 +1,97 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.archive;
import java.util.HashMap;
import java.util.Map;
import jakarta.servlet.http.HttpServletResponse;
import org.alfresco.repo.node.archive.RestoreNodeReport;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.repository.NodeRef;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* This class is the controller for the archivednode.put webscript.
*
* @author Neil Mc Erlean
* @since 3.5
*/
public class ArchivedNodePut extends AbstractArchivedNodeWebScript
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>();
// Current user
String userID = AuthenticationUtil.getFullyAuthenticatedUser();
if (userID == null)
{
throw new WebScriptException(HttpServletResponse.SC_UNAUTHORIZED, "Web Script ["
+ req.getServiceMatch().getWebScript().getDescription()
+ "] requires user authentication.");
}
NodeRef nodeRefToBeRestored = parseRequestForNodeRef(req);
if (nodeRefToBeRestored == null)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "nodeRef not recognised. Could not restore.");
}
// check if the current user has the permission to restore the node
validatePermission(nodeRefToBeRestored, userID);
RestoreNodeReport report = nodeArchiveService.restoreArchivedNode(nodeRefToBeRestored);
// Handling of some error scenarios
if (report.getStatus().equals(RestoreNodeReport.RestoreStatus.FAILURE_INVALID_ARCHIVE_NODE))
{
throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find archive node: " + nodeRefToBeRestored);
}
else if (report.getStatus().equals(RestoreNodeReport.RestoreStatus.FAILURE_PERMISSION))
{
throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "Unable to restore archive node: " + nodeRefToBeRestored);
}
else if (report.getStatus().equals(RestoreNodeReport.RestoreStatus.FAILURE_DUPLICATE_CHILD_NODE_NAME))
{
throw new WebScriptException(HttpServletResponse.SC_CONFLICT, "Unable to restore archive node: " + nodeRefToBeRestored +". Duplicate child node name");
}
else if (report.getStatus().equals(RestoreNodeReport.RestoreStatus.FAILURE_INVALID_PARENT) ||
report.getStatus().equals(RestoreNodeReport.RestoreStatus.FAILURE_INTEGRITY) ||
report.getStatus().equals(RestoreNodeReport.RestoreStatus.FAILURE_OTHER))
{
throw new WebScriptException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unable to restore archive node: " + nodeRefToBeRestored);
}
model.put("restoreNodeReport", report);
return model;
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.archive;
import java.util.HashMap;
import java.util.Map;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.repo.node.archive.RestoreNodeReport;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* This class is the controller for the archivednode.put webscript.
*
* @author Neil Mc Erlean
* @since 3.5
*/
public class ArchivedNodePut extends AbstractArchivedNodeWebScript
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>();
// Current user
String userID = AuthenticationUtil.getFullyAuthenticatedUser();
if (userID == null)
{
throw new WebScriptException(HttpServletResponse.SC_UNAUTHORIZED, "Web Script ["
+ req.getServiceMatch().getWebScript().getDescription()
+ "] requires user authentication.");
}
NodeRef nodeRefToBeRestored = parseRequestForNodeRef(req);
if (nodeRefToBeRestored == null)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "nodeRef not recognised. Could not restore.");
}
// check if the current user has the permission to restore the node
validatePermission(nodeRefToBeRestored, userID);
RestoreNodeReport report = nodeArchiveService.restoreArchivedNode(nodeRefToBeRestored);
// Handling of some error scenarios
if (report.getStatus().equals(RestoreNodeReport.RestoreStatus.FAILURE_INVALID_ARCHIVE_NODE))
{
throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find archive node: " + nodeRefToBeRestored);
}
else if (report.getStatus().equals(RestoreNodeReport.RestoreStatus.FAILURE_PERMISSION))
{
throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "Unable to restore archive node: " + nodeRefToBeRestored);
}
else if (report.getStatus().equals(RestoreNodeReport.RestoreStatus.FAILURE_DUPLICATE_CHILD_NODE_NAME))
{
throw new WebScriptException(HttpServletResponse.SC_CONFLICT, "Unable to restore archive node: " + nodeRefToBeRestored + ". Duplicate child node name");
}
else if (report.getStatus().equals(RestoreNodeReport.RestoreStatus.FAILURE_INVALID_PARENT) ||
report.getStatus().equals(RestoreNodeReport.RestoreStatus.FAILURE_INTEGRITY) ||
report.getStatus().equals(RestoreNodeReport.RestoreStatus.FAILURE_OTHER))
{
throw new WebScriptException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unable to restore archive node: " + nodeRefToBeRestored);
}
model.put("restoreNodeReport", report);
return model;
}
}

View File

@@ -23,142 +23,143 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.archive;
import java.io.Serializable;
import java.util.Date;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.PathUtil;
/**
* A simple POJO class for the state of an archived node. For easier passing to the FTL model.
*
* @author Neil McErlean
* @since 3.5
*/
public class ArchivedNodeState
{
private NodeRef archivedNodeRef;
private String archivedBy;
private Date archivedDate;
private String name;
private String title;
private String description;
private String displayPath;
private String firstName;
private String lastName;
private String nodeType;
private boolean isContentType;
/**
* To prevent unauthorised construction.
*/
private ArchivedNodeState() { /* Intentionally empty*/ }
public static ArchivedNodeState create(NodeRef archivedNode, ServiceRegistry serviceRegistry)
{
ArchivedNodeState result = new ArchivedNodeState();
NodeService nodeService = serviceRegistry.getNodeService();
Map<QName, Serializable> properties = nodeService.getProperties(archivedNode);
result.archivedNodeRef = archivedNode;
result.archivedBy = (String) properties.get(ContentModel.PROP_ARCHIVED_BY);
result.archivedDate = (Date) properties.get(ContentModel.PROP_ARCHIVED_DATE);
result.name = (String) properties.get(ContentModel.PROP_NAME);
result.title = (String) properties.get(ContentModel.PROP_TITLE);
result.description = (String) properties.get(ContentModel.PROP_DESCRIPTION);
QName type = nodeService.getType(archivedNode);
result.isContentType = (type.equals(ContentModel.TYPE_CONTENT) || serviceRegistry.getDictionaryService().isSubClass(type, ContentModel.TYPE_CONTENT));
result.nodeType = type.toPrefixString(serviceRegistry.getNamespaceService());
PersonService personService = serviceRegistry.getPersonService();
if (result.archivedBy != null && personService.personExists(result.archivedBy))
{
NodeRef personNodeRef = personService.getPerson(result.archivedBy, false);
Map<QName, Serializable> personProps = nodeService.getProperties(personNodeRef);
result.firstName = (String) personProps.get(ContentModel.PROP_FIRSTNAME);
result.lastName = (String) personProps.get(ContentModel.PROP_LASTNAME);
}
ChildAssociationRef originalParentAssoc = (ChildAssociationRef) properties.get(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC);
if (serviceRegistry.getPermissionService().hasPermission(originalParentAssoc.getParentRef(), PermissionService.READ).equals(AccessStatus.ALLOWED)
&& nodeService.exists(originalParentAssoc.getParentRef()))
{
result.displayPath = PathUtil.getDisplayPath(nodeService.getPath(originalParentAssoc.getParentRef()), true);
}
else
{
result.displayPath = "";
}
return result;
}
public NodeRef getNodeRef()
{
return this.archivedNodeRef;
}
public String getArchivedBy()
{
return this.archivedBy;
}
public Date getArchivedDate()
{
return this.archivedDate;
}
public String getName()
{
return this.name;
}
public String getTitle()
{
return this.title;
}
public String getDescription()
{
return this.description;
}
public String getDisplayPath()
{
return this.displayPath;
}
public String getFirstName()
{
return this.firstName;
}
public String getLastName()
{
return this.lastName;
}
public String getNodeType()
{
return this.nodeType;
}
public boolean getIsContentType()
{
return this.isContentType;
}
}
package org.alfresco.repo.web.scripts.archive;
import java.io.Serializable;
import java.util.Date;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.PathUtil;
/**
* A simple POJO class for the state of an archived node. For easier passing to the FTL model.
*
* @author Neil McErlean
* @since 3.5
*/
public class ArchivedNodeState
{
private NodeRef archivedNodeRef;
private String archivedBy;
private Date archivedDate;
private String name;
private String title;
private String description;
private String displayPath;
private String firstName;
private String lastName;
private String nodeType;
private boolean isContentType;
/**
* To prevent unauthorised construction.
*/
private ArchivedNodeState()
{ /* Intentionally empty */ }
public static ArchivedNodeState create(NodeRef archivedNode, ServiceRegistry serviceRegistry)
{
ArchivedNodeState result = new ArchivedNodeState();
NodeService nodeService = serviceRegistry.getNodeService();
Map<QName, Serializable> properties = nodeService.getProperties(archivedNode);
result.archivedNodeRef = archivedNode;
result.archivedBy = (String) properties.get(ContentModel.PROP_ARCHIVED_BY);
result.archivedDate = (Date) properties.get(ContentModel.PROP_ARCHIVED_DATE);
result.name = (String) properties.get(ContentModel.PROP_NAME);
result.title = (String) properties.get(ContentModel.PROP_TITLE);
result.description = (String) properties.get(ContentModel.PROP_DESCRIPTION);
QName type = nodeService.getType(archivedNode);
result.isContentType = (type.equals(ContentModel.TYPE_CONTENT) || serviceRegistry.getDictionaryService().isSubClass(type, ContentModel.TYPE_CONTENT));
result.nodeType = type.toPrefixString(serviceRegistry.getNamespaceService());
PersonService personService = serviceRegistry.getPersonService();
if (result.archivedBy != null && personService.personExists(result.archivedBy))
{
NodeRef personNodeRef = personService.getPerson(result.archivedBy, false);
Map<QName, Serializable> personProps = nodeService.getProperties(personNodeRef);
result.firstName = (String) personProps.get(ContentModel.PROP_FIRSTNAME);
result.lastName = (String) personProps.get(ContentModel.PROP_LASTNAME);
}
ChildAssociationRef originalParentAssoc = (ChildAssociationRef) properties.get(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC);
if (serviceRegistry.getPermissionService().hasPermission(originalParentAssoc.getParentRef(), PermissionService.READ).equals(AccessStatus.ALLOWED)
&& nodeService.exists(originalParentAssoc.getParentRef()))
{
result.displayPath = PathUtil.getDisplayPath(nodeService.getPath(originalParentAssoc.getParentRef()), true);
}
else
{
result.displayPath = "";
}
return result;
}
public NodeRef getNodeRef()
{
return this.archivedNodeRef;
}
public String getArchivedBy()
{
return this.archivedBy;
}
public Date getArchivedDate()
{
return this.archivedDate;
}
public String getName()
{
return this.name;
}
public String getTitle()
{
return this.title;
}
public String getDescription()
{
return this.description;
}
public String getDisplayPath()
{
return this.displayPath;
}
public String getFirstName()
{
return this.firstName;
}
public String getLastName()
{
return this.lastName;
}
public String getNodeType()
{
return this.nodeType;
}
public boolean getIsContentType()
{
return this.isContentType;
}
}

View File

@@ -1,110 +1,110 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.archive;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jakarta.servlet.http.HttpServletResponse;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.util.ScriptPagingDetails;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* This class is the controller for the deletednodes.delete web script.
*
* @author Neil McErlean
* @since 3.5
*/
public class ArchivedNodesDelete extends AbstractArchivedNodeWebScript
{
private static Log log = LogFactory.getLog(ArchivedNodesDelete.class);
public static final String PURGED_NODES = "purgedNodes";
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>();
// Current user
String userID = AuthenticationUtil.getFullyAuthenticatedUser();
if (userID == null)
{
throw new WebScriptException(HttpServletResponse.SC_UNAUTHORIZED, "Web Script ["
+ req.getServiceMatch().getWebScript().getDescription()
+ "] requires user authentication.");
}
StoreRef storeRef = parseRequestForStoreRef(req);
NodeRef nodeRef = parseRequestForNodeRef(req);
List<NodeRef> nodesToBePurged = new ArrayList<NodeRef>();
if (nodeRef != null)
{
// check if the current user has the permission to purge the node
validatePermission(nodeRef, userID);
// If there is a specific NodeRef, then that is the only Node that should be purged.
// In this case, the NodeRef points to the actual node to be purged i.e. the node in
// the archive store.
nodesToBePurged.add(nodeRef);
}
else
{
// But if there is no specific NodeRef and instead there is only a StoreRef, then
// all nodes which were originally in that StoreRef should be purged.
// Create paging
ScriptPagingDetails paging = new ScriptPagingDetails(maxSizeView, 0);
PagingResults<NodeRef> result = getArchivedNodesFrom(storeRef, paging, null);
nodesToBePurged.addAll(result.getPage());
}
if (log.isDebugEnabled())
{
log.debug("Purging " + nodesToBePurged.size() + " nodes");
}
// Now having identified the nodes to be purged, we simply have to do it.
nodeArchiveService.purgeArchivedNodes(nodesToBePurged);
model.put(PURGED_NODES, nodesToBePurged);
return model;
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.archive;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.util.ScriptPagingDetails;
/**
* This class is the controller for the deletednodes.delete web script.
*
* @author Neil McErlean
* @since 3.5
*/
public class ArchivedNodesDelete extends AbstractArchivedNodeWebScript
{
private static Log log = LogFactory.getLog(ArchivedNodesDelete.class);
public static final String PURGED_NODES = "purgedNodes";
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>();
// Current user
String userID = AuthenticationUtil.getFullyAuthenticatedUser();
if (userID == null)
{
throw new WebScriptException(HttpServletResponse.SC_UNAUTHORIZED, "Web Script ["
+ req.getServiceMatch().getWebScript().getDescription()
+ "] requires user authentication.");
}
StoreRef storeRef = parseRequestForStoreRef(req);
NodeRef nodeRef = parseRequestForNodeRef(req);
List<NodeRef> nodesToBePurged = new ArrayList<NodeRef>();
if (nodeRef != null)
{
// check if the current user has the permission to purge the node
validatePermission(nodeRef, userID);
// If there is a specific NodeRef, then that is the only Node that should be purged.
// In this case, the NodeRef points to the actual node to be purged i.e. the node in
// the archive store.
nodesToBePurged.add(nodeRef);
}
else
{
// But if there is no specific NodeRef and instead there is only a StoreRef, then
// all nodes which were originally in that StoreRef should be purged.
// Create paging
ScriptPagingDetails paging = new ScriptPagingDetails(maxSizeView, 0);
PagingResults<NodeRef> result = getArchivedNodesFrom(storeRef, paging, null);
nodesToBePurged.addAll(result.getPage());
}
if (log.isDebugEnabled())
{
log.debug("Purging " + nodesToBePurged.size() + " nodes");
}
// Now having identified the nodes to be purged, we simply have to do it.
nodeArchiveService.purgeArchivedNodes(nodesToBePurged);
model.put(PURGED_NODES, nodesToBePurged);
return model;
}
}

View File

@@ -23,24 +23,25 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.archive;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* This interface defines a filter for ArchivedNodes.
*
* @author Neil Mc Erlean
* @since 3.5
*/
public interface ArchivedNodesFilter
{
/**
* This method checks whether or not the specified {@link NodeRef} should be included,
* as defined by the concrete filter implementation.
* @param nodeRef the NodeRef to be checked for filtering.
* @return <code>true</code> if the {@link NodeRef} is acceptable, else <code>false</code>.
*/
boolean accept(NodeRef nodeRef);
}
package org.alfresco.repo.web.scripts.archive;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* This interface defines a filter for ArchivedNodes.
*
* @author Neil Mc Erlean
* @since 3.5
*/
public interface ArchivedNodesFilter
{
/**
* This method checks whether or not the specified {@link NodeRef} should be included, as defined by the concrete filter implementation.
*
* @param nodeRef
* the NodeRef to be checked for filtering.
* @return <code>true</code> if the {@link NodeRef} is acceptable, else <code>false</code>.
*/
boolean accept(NodeRef nodeRef);
}

View File

@@ -23,77 +23,78 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.archive;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.query.PagingResults;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.util.ModelUtil;
import org.alfresco.util.ScriptPagingDetails;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* This class is the controller for the archivednodes.get web script.
*
* @author Neil McErlean, Jamal Kaabi-Mofrad
* @since 3.5
*/
public class ArchivedNodesGet extends AbstractArchivedNodeWebScript
{
private static final String MAX_ITEMS = "maxItems";
private static final String SKIP_COUNT = "skipCount";
private static final String NAME_FILTER = "nf";
List<ArchivedNodesFilter> nodeFilters = new ArrayList<ArchivedNodesFilter>();
/**
* This method is used to inject {@link org.alfresco.repo.web.scripts.archive.ArchivedNodesFilter node filters} on this GET call.
*
*/
public void setArchivedNodeFilters(List<ArchivedNodesFilter> nodeFilters)
{
this.nodeFilters = nodeFilters;
}
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>();
// We want to get all nodes in the archive which were originally
// contained in the following StoreRef.
StoreRef storeRef = parseRequestForStoreRef(req);
// Create paging
ScriptPagingDetails paging = new ScriptPagingDetails(getIntParameter(req, MAX_ITEMS, DEFAULT_MAX_ITEMS_PER_PAGE),
getIntParameter(req, SKIP_COUNT, 0));
PagingResults<NodeRef> result = getArchivedNodesFrom(storeRef, paging, req.getParameter(NAME_FILTER));
List<NodeRef> nodeRefs = result.getPage();
List<ArchivedNodeState> deletedNodes = new ArrayList<ArchivedNodeState>(nodeRefs.size());
for (NodeRef archivedNode : nodeRefs)
{
ArchivedNodeState state = ArchivedNodeState.create(archivedNode, serviceRegistry);
deletedNodes.add(state);
}
// Now do the paging
// ALF-19111. Note: Archived nodes CQ, supports Paging,
// so no need to use the ModelUtil.page method to build the page again.
model.put(DELETED_NODES, deletedNodes);
// Because we haven't used ModelUtil.page method, we need to set the total items manually.
paging.setTotalItems(deletedNodes.size());
model.put("paging", ModelUtil.buildPaging(paging));
return model;
}
}
package org.alfresco.repo.web.scripts.archive;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.util.ModelUtil;
import org.alfresco.util.ScriptPagingDetails;
/**
* This class is the controller for the archivednodes.get web script.
*
* @author Neil McErlean, Jamal Kaabi-Mofrad
* @since 3.5
*/
public class ArchivedNodesGet extends AbstractArchivedNodeWebScript
{
private static final String MAX_ITEMS = "maxItems";
private static final String SKIP_COUNT = "skipCount";
private static final String NAME_FILTER = "nf";
List<ArchivedNodesFilter> nodeFilters = new ArrayList<ArchivedNodesFilter>();
/**
* This method is used to inject {@link org.alfresco.repo.web.scripts.archive.ArchivedNodesFilter node filters} on this GET call.
*
*/
public void setArchivedNodeFilters(List<ArchivedNodesFilter> nodeFilters)
{
this.nodeFilters = nodeFilters;
}
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>();
// We want to get all nodes in the archive which were originally
// contained in the following StoreRef.
StoreRef storeRef = parseRequestForStoreRef(req);
// Create paging
ScriptPagingDetails paging = new ScriptPagingDetails(getIntParameter(req, MAX_ITEMS, DEFAULT_MAX_ITEMS_PER_PAGE),
getIntParameter(req, SKIP_COUNT, 0));
PagingResults<NodeRef> result = getArchivedNodesFrom(storeRef, paging, req.getParameter(NAME_FILTER));
List<NodeRef> nodeRefs = result.getPage();
List<ArchivedNodeState> deletedNodes = new ArrayList<ArchivedNodeState>(nodeRefs.size());
for (NodeRef archivedNode : nodeRefs)
{
ArchivedNodeState state = ArchivedNodeState.create(archivedNode, serviceRegistry);
deletedNodes.add(state);
}
// Now do the paging
// ALF-19111. Note: Archived nodes CQ, supports Paging,
// so no need to use the ModelUtil.page method to build the page again.
model.put(DELETED_NODES, deletedNodes);
// Because we haven't used ModelUtil.page method, we need to set the total items manually.
paging.setTotalItems(deletedNodes.size());
model.put("paging", ModelUtil.buildPaging(paging));
return model;
}
}

View File

@@ -23,71 +23,73 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.archive;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
/**
* This class is used to filter nodes based on node type.
*
* @author Neil McErlean
* @since 3.5
*/
public class NodeTypeFilter implements ArchivedNodesFilter
{
private NodeService nodeService;
private NamespaceService namespaceService;
private List<QName> excludedTypes;
/**
* This method sets the NamespaceService object.
* @param namespaceService the namespaceService.
*/
public void setNamespaceService(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
/**
* This method sets the NodeService object.
* @param nodeService the node service.
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* Sets the List of node types to exclude. These node types should be in the
* short form e.g. cm:myType.
*
* @param excludedTypesStg a List of node types which are to be excluded.
*/
public void setExcludedTypes(List<String> excludedTypesStg)
{
// Convert the Strings to QNames.
this.excludedTypes = new ArrayList<QName>(excludedTypesStg.size());
for (String s : excludedTypesStg)
{
QName typeQName = QName.createQName(s, namespaceService);
this.excludedTypes.add(typeQName);
}
}
/*
* (non-Javadoc)
* @see org.alfresco.repo.web.scripts.archive.ArchivedNodesFilter#accept(org.alfresco.service.cmr.repository.NodeRef)
*/
public boolean accept(NodeRef nodeRef)
{
boolean typeIsExcluded = this.excludedTypes.contains(nodeService.getType(nodeRef));
return !typeIsExcluded;
}
}
package org.alfresco.repo.web.scripts.archive;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
/**
* This class is used to filter nodes based on node type.
*
* @author Neil McErlean
* @since 3.5
*/
public class NodeTypeFilter implements ArchivedNodesFilter
{
private NodeService nodeService;
private NamespaceService namespaceService;
private List<QName> excludedTypes;
/**
* This method sets the NamespaceService object.
*
* @param namespaceService
* the namespaceService.
*/
public void setNamespaceService(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
/**
* This method sets the NodeService object.
*
* @param nodeService
* the node service.
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* Sets the List of node types to exclude. These node types should be in the short form e.g. cm:myType.
*
* @param excludedTypesStg
* a List of node types which are to be excluded.
*/
public void setExcludedTypes(List<String> excludedTypesStg)
{
// Convert the Strings to QNames.
this.excludedTypes = new ArrayList<QName>(excludedTypesStg.size());
for (String s : excludedTypesStg)
{
QName typeQName = QName.createQName(s, namespaceService);
this.excludedTypes.add(typeQName);
}
}
/* (non-Javadoc)
*
* @see org.alfresco.repo.web.scripts.archive.ArchivedNodesFilter#accept(org.alfresco.service.cmr.repository.NodeRef) */
public boolean accept(NodeRef nodeRef)
{
boolean typeIsExcluded = this.excludedTypes.contains(nodeService.getType(nodeRef));
return !typeIsExcluded;
}
}

View File

@@ -1,299 +1,302 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.audit;
import java.util.Map;
import org.alfresco.service.cmr.audit.AuditService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Abstract implementation for scripts that access the {@link AuditService}.
*
* @author Derek Hulley
* @since 3.4
*/
public abstract class AbstractAuditWebScript extends DeclarativeWebScript
{
public static final String PARAM_APPLICATION = "application";
public static final String PARAM_PATH="path";
public static final String PARAM_ENABLE = "enable";
public static final String PARAM_VALUE = "value";
public static final String PARAM_VALUE_TYPE = "valueType";
public static final String PARAM_FROM_TIME = "fromTime";
public static final String PARAM_TO_TIME = "toTime";
public static final String PARAM_FROM_ID = "fromId";
public static final String PARAM_TO_ID = "toId";
public static final String PARAM_USER = "user";
public static final String PARAM_FORWARD = "forward";
public static final String PARAM_LIMIT = "limit";
public static final String PARAM_VERBOSE = "verbose";
public static final Long DEFAULT_FROM_TIME = null;
public static final Long DEFAULT_TO_TIME = null;
public static final Long DEFAULT_FROM_ID = null;
public static final Long DEFAULT_TO_ID = null;
public static final String DEFAULT_USER = null;
public static final boolean DEFAULT_FORWARD = true;
public static final int DEFAULT_LIMIT = 100;
public static final boolean DEFAULT_VERBOSE = false;
public static final boolean DEFAULT_ENABLE = false;
public static final String JSON_KEY_ENABLED = "enabled";
public static final String JSON_KEY_APPLICATIONS = "applications";
public static final String JSON_KEY_NAME = "name";
public static final String JSON_KEY_PATH = "path";
public static final String JSON_KEY_CLEARED = "cleared";
public static final String JSON_KEY_DELETED = "deleted";
public static final String JSON_KEY_ENTRY_COUNT = "count";
public static final String JSON_KEY_ENTRIES = "entries";
public static final String JSON_KEY_ENTRY_ID = "id";
public static final String JSON_KEY_ENTRY_APPLICATION = "application";
public static final String JSON_KEY_ENTRY_USER = "user";
public static final String JSON_KEY_ENTRY_TIME = "time";
public static final String JSON_KEY_ENTRY_VALUES = "values";
/**
* Logger that can be used by subclasses.
*/
protected final Log logger = LogFactory.getLog(this.getClass());
protected AuditService auditService;
/**
* @param auditService the service that provides the actual data
*/
public void setAuditService(AuditService auditService)
{
this.auditService = auditService;
}
/**
* Return an I18N'd message for the given key or the key itself if not present
*
* @param args arguments to replace the variables in the message
*/
protected String getI18NMessage(String key, Object ... args)
{
return I18NUtil.getMessage(key, args);
}
/**
* Get the application name from the request.
*
* @return Returns the application name or <tt>null</tt> if not present
*/
protected final String getParamAppName(WebScriptRequest req)
{
Map<String, String> templateVars = req.getServiceMatch().getTemplateVars();
String app = templateVars.get(PARAM_APPLICATION);
if (app == null || app.length() == 0)
{
return null;
}
else
{
return app;
}
}
/**
* Get the entry id from the request.
*
* @return Returns the id or <tt>null</tt> if not present
*/
protected Long getId(WebScriptRequest req)
{
Map<String, String> templateVars = req.getServiceMatch().getTemplateVars();
String id = templateVars.get("id");
if (id == null || id.length() == 0)
{
return null;
}
else
{
try
{
return Long.parseLong(id);
}
catch (NumberFormatException e)
{
return null;
}
}
}
/**
* Get the path from the request.
*
* @return Returns the path or <tt>null</tt> if not present
*/
protected String getParamPath(WebScriptRequest req)
{
Map<String, String> templateVars = req.getServiceMatch().getTemplateVars();
String paramPath = templateVars.get(PARAM_PATH);
if (paramPath == null || paramPath.length() == 0)
{
paramPath = null;
}
else if (!paramPath.startsWith("/"))
{
// It won't ever, so we can expect to be here all the time
paramPath = "/" + paramPath;
}
return paramPath;
}
protected boolean getParamEnableDisable(WebScriptRequest req)
{
return getBooleanParam(req.getParameter(PARAM_ENABLE), DEFAULT_ENABLE);
}
protected String getParamValue(WebScriptRequest req)
{
return req.getParameter(PARAM_VALUE);
}
protected String getParamValueType(WebScriptRequest req)
{
return req.getParameter(PARAM_VALUE_TYPE);
}
/**
* @see #DEFAULT_FROM_TIME
*/
protected Long getParamFromTime(WebScriptRequest req)
{
return getLongParam(req.getParameter(PARAM_FROM_TIME), DEFAULT_FROM_TIME);
}
/**
* @see #DEFAULT_TO_TIME
*/
protected Long getParamToTime(WebScriptRequest req)
{
return getLongParam(req.getParameter(PARAM_TO_TIME), DEFAULT_TO_TIME);
}
/**
* @see #DEFAULT_FROM_ID
*/
protected Long getParamFromId(WebScriptRequest req)
{
return getLongParam(req.getParameter(PARAM_FROM_ID), DEFAULT_FROM_ID);
}
/**
* @see #DEFAULT_TO_ID
*/
protected Long getParamToId(WebScriptRequest req)
{
return getLongParam(req.getParameter(PARAM_TO_ID), DEFAULT_TO_ID);
}
/**
* @see #DEFAULT_USER
*/
protected String getParamUser(WebScriptRequest req)
{
return req.getParameter(PARAM_USER);
}
/**
* @see #DEFAULT_FORWARD
*/
protected boolean getParamForward(WebScriptRequest req)
{
return getBooleanParam(req.getParameter(PARAM_FORWARD), DEFAULT_FORWARD);
}
/**
* @see #DEFAULT_LIMIT
*/
protected int getParamLimit(WebScriptRequest req)
{
return getIntParam(req.getParameter(PARAM_LIMIT), DEFAULT_LIMIT);
}
/**
* @see #DEFAULT_VERBOSE
*/
protected boolean getParamVerbose(WebScriptRequest req)
{
return getBooleanParam(req.getParameter(PARAM_VERBOSE), DEFAULT_VERBOSE);
}
private Long getLongParam(String paramStr, Long defaultVal)
{
if (paramStr == null)
{
// note: defaultVal can be null
return defaultVal;
}
try
{
return Long.parseLong(paramStr);
}
catch (NumberFormatException e)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, e.getMessage());
}
}
private boolean getBooleanParam(String paramStr, boolean defaultVal)
{
if (paramStr == null)
{
return defaultVal;
}
// note: will return false if paramStr does not equals "true" (ignoring case)
return Boolean.parseBoolean(paramStr);
}
private int getIntParam(String paramStr, int defaultVal)
{
if (paramStr == null)
{
return defaultVal;
}
try
{
return Integer.parseInt(paramStr);
}
catch (NumberFormatException e)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, e.getMessage());
}
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.audit;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.service.cmr.audit.AuditService;
/**
* Abstract implementation for scripts that access the {@link AuditService}.
*
* @author Derek Hulley
* @since 3.4
*/
public abstract class AbstractAuditWebScript extends DeclarativeWebScript
{
public static final String PARAM_APPLICATION = "application";
public static final String PARAM_PATH = "path";
public static final String PARAM_ENABLE = "enable";
public static final String PARAM_VALUE = "value";
public static final String PARAM_VALUE_TYPE = "valueType";
public static final String PARAM_FROM_TIME = "fromTime";
public static final String PARAM_TO_TIME = "toTime";
public static final String PARAM_FROM_ID = "fromId";
public static final String PARAM_TO_ID = "toId";
public static final String PARAM_USER = "user";
public static final String PARAM_FORWARD = "forward";
public static final String PARAM_LIMIT = "limit";
public static final String PARAM_VERBOSE = "verbose";
public static final Long DEFAULT_FROM_TIME = null;
public static final Long DEFAULT_TO_TIME = null;
public static final Long DEFAULT_FROM_ID = null;
public static final Long DEFAULT_TO_ID = null;
public static final String DEFAULT_USER = null;
public static final boolean DEFAULT_FORWARD = true;
public static final int DEFAULT_LIMIT = 100;
public static final boolean DEFAULT_VERBOSE = false;
public static final boolean DEFAULT_ENABLE = false;
public static final String JSON_KEY_ENABLED = "enabled";
public static final String JSON_KEY_APPLICATIONS = "applications";
public static final String JSON_KEY_NAME = "name";
public static final String JSON_KEY_PATH = "path";
public static final String JSON_KEY_CLEARED = "cleared";
public static final String JSON_KEY_DELETED = "deleted";
public static final String JSON_KEY_ENTRY_COUNT = "count";
public static final String JSON_KEY_ENTRIES = "entries";
public static final String JSON_KEY_ENTRY_ID = "id";
public static final String JSON_KEY_ENTRY_APPLICATION = "application";
public static final String JSON_KEY_ENTRY_USER = "user";
public static final String JSON_KEY_ENTRY_TIME = "time";
public static final String JSON_KEY_ENTRY_VALUES = "values";
/**
* Logger that can be used by subclasses.
*/
protected final Log logger = LogFactory.getLog(this.getClass());
protected AuditService auditService;
/**
* @param auditService
* the service that provides the actual data
*/
public void setAuditService(AuditService auditService)
{
this.auditService = auditService;
}
/**
* Return an I18N'd message for the given key or the key itself if not present
*
* @param args
* arguments to replace the variables in the message
*/
protected String getI18NMessage(String key, Object... args)
{
return I18NUtil.getMessage(key, args);
}
/**
* Get the application name from the request.
*
* @return Returns the application name or <tt>null</tt> if not present
*/
protected final String getParamAppName(WebScriptRequest req)
{
Map<String, String> templateVars = req.getServiceMatch().getTemplateVars();
String app = templateVars.get(PARAM_APPLICATION);
if (app == null || app.length() == 0)
{
return null;
}
else
{
return app;
}
}
/**
* Get the entry id from the request.
*
* @return Returns the id or <tt>null</tt> if not present
*/
protected Long getId(WebScriptRequest req)
{
Map<String, String> templateVars = req.getServiceMatch().getTemplateVars();
String id = templateVars.get("id");
if (id == null || id.length() == 0)
{
return null;
}
else
{
try
{
return Long.parseLong(id);
}
catch (NumberFormatException e)
{
return null;
}
}
}
/**
* Get the path from the request.
*
* @return Returns the path or <tt>null</tt> if not present
*/
protected String getParamPath(WebScriptRequest req)
{
Map<String, String> templateVars = req.getServiceMatch().getTemplateVars();
String paramPath = templateVars.get(PARAM_PATH);
if (paramPath == null || paramPath.length() == 0)
{
paramPath = null;
}
else if (!paramPath.startsWith("/"))
{
// It won't ever, so we can expect to be here all the time
paramPath = "/" + paramPath;
}
return paramPath;
}
protected boolean getParamEnableDisable(WebScriptRequest req)
{
return getBooleanParam(req.getParameter(PARAM_ENABLE), DEFAULT_ENABLE);
}
protected String getParamValue(WebScriptRequest req)
{
return req.getParameter(PARAM_VALUE);
}
protected String getParamValueType(WebScriptRequest req)
{
return req.getParameter(PARAM_VALUE_TYPE);
}
/**
* @see #DEFAULT_FROM_TIME
*/
protected Long getParamFromTime(WebScriptRequest req)
{
return getLongParam(req.getParameter(PARAM_FROM_TIME), DEFAULT_FROM_TIME);
}
/**
* @see #DEFAULT_TO_TIME
*/
protected Long getParamToTime(WebScriptRequest req)
{
return getLongParam(req.getParameter(PARAM_TO_TIME), DEFAULT_TO_TIME);
}
/**
* @see #DEFAULT_FROM_ID
*/
protected Long getParamFromId(WebScriptRequest req)
{
return getLongParam(req.getParameter(PARAM_FROM_ID), DEFAULT_FROM_ID);
}
/**
* @see #DEFAULT_TO_ID
*/
protected Long getParamToId(WebScriptRequest req)
{
return getLongParam(req.getParameter(PARAM_TO_ID), DEFAULT_TO_ID);
}
/**
* @see #DEFAULT_USER
*/
protected String getParamUser(WebScriptRequest req)
{
return req.getParameter(PARAM_USER);
}
/**
* @see #DEFAULT_FORWARD
*/
protected boolean getParamForward(WebScriptRequest req)
{
return getBooleanParam(req.getParameter(PARAM_FORWARD), DEFAULT_FORWARD);
}
/**
* @see #DEFAULT_LIMIT
*/
protected int getParamLimit(WebScriptRequest req)
{
return getIntParam(req.getParameter(PARAM_LIMIT), DEFAULT_LIMIT);
}
/**
* @see #DEFAULT_VERBOSE
*/
protected boolean getParamVerbose(WebScriptRequest req)
{
return getBooleanParam(req.getParameter(PARAM_VERBOSE), DEFAULT_VERBOSE);
}
private Long getLongParam(String paramStr, Long defaultVal)
{
if (paramStr == null)
{
// note: defaultVal can be null
return defaultVal;
}
try
{
return Long.parseLong(paramStr);
}
catch (NumberFormatException e)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, e.getMessage());
}
}
private boolean getBooleanParam(String paramStr, boolean defaultVal)
{
if (paramStr == null)
{
return defaultVal;
}
// note: will return false if paramStr does not equals "true" (ignoring case)
return Boolean.parseBoolean(paramStr);
}
private int getIntParam(String paramStr, int defaultVal)
{
if (paramStr == null)
{
return defaultVal;
}
try
{
return Integer.parseInt(paramStr);
}
catch (NumberFormatException e)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, e.getMessage());
}
}
}

View File

@@ -23,52 +23,53 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.audit;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.service.cmr.audit.AuditService.AuditApplication;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author Derek Hulley
* @since 3.4
*/
public class AuditClearPost extends AbstractAuditWebScript
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>(7);
String appName = getParamAppName(req);
if (appName == null)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "audit.err.app.notProvided");
}
AuditApplication app = auditService.getAuditApplications().get(appName);
if (app == null)
{
throw new WebScriptException(Status.STATUS_NOT_FOUND, "audit.err.app.notFound", appName);
}
// Get from/to times
Long fromTime = getParamFromTime(req); // might be null
Long toTime = getParamToTime(req); // might be null
// Clear
int cleared = auditService.clearAudit(appName, fromTime, toTime);
model.put(JSON_KEY_CLEARED, cleared);
// Done
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}
package org.alfresco.repo.web.scripts.audit;
import java.util.HashMap;
import java.util.Map;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.service.cmr.audit.AuditService.AuditApplication;
/**
* @author Derek Hulley
* @since 3.4
*/
public class AuditClearPost extends AbstractAuditWebScript
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>(7);
String appName = getParamAppName(req);
if (appName == null)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "audit.err.app.notProvided");
}
AuditApplication app = auditService.getAuditApplications().get(appName);
if (app == null)
{
throw new WebScriptException(Status.STATUS_NOT_FOUND, "audit.err.app.notFound", appName);
}
// Get from/to times
Long fromTime = getParamFromTime(req); // might be null
Long toTime = getParamToTime(req); // might be null
// Clear
int cleared = auditService.clearAudit(appName, fromTime, toTime);
model.put(JSON_KEY_CLEARED, cleared);
// Done
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}

View File

@@ -23,59 +23,60 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.audit;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.service.cmr.audit.AuditService.AuditApplication;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author Derek Hulley
* @since 3.4
*/
public class AuditControlGet extends AbstractAuditWebScript
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>(7);
String appName = getParamAppName(req);
String path = getParamPath(req);
boolean enabledGlobal = auditService.isAuditEnabled();
Map<String, AuditApplication> appsByName = auditService.getAuditApplications();
// Check that the application exists
if (appName != null)
{
if (path == null)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "audit.err.path.notProvided");
}
AuditApplication app = appsByName.get(appName);
if (app == null)
{
throw new WebScriptException(Status.STATUS_NOT_FOUND, "audit.err.app.notFound", appName);
}
// Discard all the other applications
appsByName = Collections.singletonMap(appName, app);
}
model.put(JSON_KEY_ENABLED, enabledGlobal);
model.put(JSON_KEY_APPLICATIONS, appsByName.values());
// Done
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}
package org.alfresco.repo.web.scripts.audit;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.service.cmr.audit.AuditService.AuditApplication;
/**
* @author Derek Hulley
* @since 3.4
*/
public class AuditControlGet extends AbstractAuditWebScript
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>(7);
String appName = getParamAppName(req);
String path = getParamPath(req);
boolean enabledGlobal = auditService.isAuditEnabled();
Map<String, AuditApplication> appsByName = auditService.getAuditApplications();
// Check that the application exists
if (appName != null)
{
if (path == null)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "audit.err.path.notProvided");
}
AuditApplication app = appsByName.get(appName);
if (app == null)
{
throw new WebScriptException(Status.STATUS_NOT_FOUND, "audit.err.app.notFound", appName);
}
// Discard all the other applications
appsByName = Collections.singletonMap(appName, app);
}
model.put(JSON_KEY_ENABLED, enabledGlobal);
model.put(JSON_KEY_APPLICATIONS, appsByName.values());
// Done
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}

View File

@@ -23,55 +23,55 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.audit;
import java.util.HashMap;
import java.util.Map;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author Derek Hulley
* @since 3.4
*/
public class AuditControlPost extends AbstractAuditWebScript
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>(7);
String appName = getParamAppName(req);
String path = getParamPath(req);
boolean enable = getParamEnableDisable(req);
if (appName == null)
{
// Global operation
auditService.setAuditEnabled(enable);
}
else
{
// Apply to a specific application
if (enable)
{
auditService.enableAudit(appName, path);
}
else
{
auditService.disableAudit(appName, path);
}
}
model.put(JSON_KEY_ENABLED, enable);
// Done
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}
package org.alfresco.repo.web.scripts.audit;
import java.util.HashMap;
import java.util.Map;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author Derek Hulley
* @since 3.4
*/
public class AuditControlPost extends AbstractAuditWebScript
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>(7);
String appName = getParamAppName(req);
String path = getParamPath(req);
boolean enable = getParamEnableDisable(req);
if (appName == null)
{
// Global operation
auditService.setAuditEnabled(enable);
}
else
{
// Apply to a specific application
if (enable)
{
auditService.enableAudit(appName, path);
}
else
{
auditService.disableAudit(appName, path);
}
}
model.put(JSON_KEY_ENABLED, enable);
// Done
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}

View File

@@ -23,89 +23,91 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.audit;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.service.cmr.audit.AuditQueryParameters;
import org.alfresco.service.cmr.audit.AuditService.AuditApplication;
import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author Mark Rogers
* @since 4.2
*/
public class AuditEntryDelete extends AbstractAuditWebScript
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>(7);
Long id = getId(req);
if (id == null)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "audit.err.entry.id.notProvided");
}
final List<Long> auditEntryIds = new ArrayList<Long>();
// Need to check that the audit entry actually exists - otherwise we get into a concurrency retry loop
AuditQueryParameters params = new AuditQueryParameters();
AuditQueryCallback callback = new AuditQueryCallback(){
@Override
public boolean valuesRequired() {
return false;
}
@Override
public boolean handleAuditEntry(Long entryId,
String applicationName,
String user, long time,
Map<String, Serializable> values) {
auditEntryIds.add(entryId);
return false;
}
@Override
public boolean handleAuditEntryError(Long entryId, String errorMsg,
Throwable error)
{
return true;
}
};
params.setToId(id);
params.setFromId(id);
auditService.auditQuery(callback, params, 1);
if(auditEntryIds.size() > 0)
{
//
int deleted = auditService.clearAudit(auditEntryIds);
model.put(JSON_KEY_DELETED, deleted);
// Done
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
else
{
// Not found
throw new WebScriptException(Status.STATUS_NOT_FOUND, "audit.err.entry.id.notfound", id);
}
}
}
package org.alfresco.repo.web.scripts.audit;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.service.cmr.audit.AuditQueryParameters;
import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback;
/**
* @author Mark Rogers
* @since 4.2
*/
public class AuditEntryDelete extends AbstractAuditWebScript
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, Object> model = new HashMap<String, Object>(7);
Long id = getId(req);
if (id == null)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "audit.err.entry.id.notProvided");
}
final List<Long> auditEntryIds = new ArrayList<Long>();
// Need to check that the audit entry actually exists - otherwise we get into a concurrency retry loop
AuditQueryParameters params = new AuditQueryParameters();
AuditQueryCallback callback = new AuditQueryCallback() {
@Override
public boolean valuesRequired()
{
return false;
}
@Override
public boolean handleAuditEntry(Long entryId,
String applicationName,
String user, long time,
Map<String, Serializable> values)
{
auditEntryIds.add(entryId);
return false;
}
@Override
public boolean handleAuditEntryError(Long entryId, String errorMsg,
Throwable error)
{
return true;
}
};
params.setToId(id);
params.setFromId(id);
auditService.auditQuery(callback, params, 1);
if (auditEntryIds.size() > 0)
{
//
int deleted = auditService.clearAudit(auditEntryIds);
model.put(JSON_KEY_DELETED, deleted);
// Done
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
else
{
// Not found
throw new WebScriptException(Status.STATUS_NOT_FOUND, "audit.err.entry.id.notfound", id);
}
}
}

View File

@@ -1,197 +1,197 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.audit;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.service.cmr.audit.AuditQueryParameters;
import org.alfresco.service.cmr.audit.AuditService.AuditApplication;
import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback;
import org.alfresco.service.cmr.repository.MLText;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.repository.datatype.TypeConversionException;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author Derek Hulley
* @since 3.4
*/
public class AuditQueryGet extends AbstractAuditWebScript
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
final Map<String, Object> model = new HashMap<String, Object>(7);
String appName = getParamAppName(req);
String path = getParamPath(req);
Serializable value = getParamValue(req);
String valueType = getParamValueType(req);
Long fromTime = getParamFromTime(req);
Long toTime = getParamToTime(req);
Long fromId = getParamFromId(req);
Long toId = getParamToId(req);
String user = getParamUser(req);
boolean forward = getParamForward(req);
int limit = getParamLimit(req);
final boolean verbose = getParamVerbose(req);
if (appName == null)
{
Map<String, AuditApplication> appsByName = auditService.getAuditApplications();
AuditApplication app = appsByName.get(appName);
if (app == null)
{
throw new WebScriptException(Status.STATUS_NOT_FOUND, "audit.err.app.notFound", appName);
}
}
// Transform the value to the correct type
if (value != null && valueType != null)
{
try
{
@SuppressWarnings("unchecked")
Class<? extends Serializable> clazz = (Class<? extends Serializable>) Class.forName(valueType);
value = DefaultTypeConverter.INSTANCE.convert(clazz, value);
}
catch (ClassNotFoundException e)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "audit.err.value.classNotFound", valueType);
}
catch (Throwable e)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "audit.err.value.convertFailed", value, valueType);
}
}
// Execute the query
AuditQueryParameters params = new AuditQueryParameters();
params.setApplicationName(appName);
params.setFromTime(fromTime);
params.setToTime(toTime);
params.setFromId(fromId);
params.setToId(toId);
params.setUser(user);
params.setForward(forward);
if (path != null || value != null)
{
params.addSearchKey(path, value);
}
final List<Map<String, Object>> entries = new ArrayList<Map<String,Object>>(limit);
AuditQueryCallback callback = new AuditQueryCallback()
{
@Override
public boolean valuesRequired()
{
return verbose;
}
@Override
public boolean handleAuditEntryError(Long entryId, String errorMsg, Throwable error)
{
return true;
}
@Override
public boolean handleAuditEntry(
Long entryId,
String applicationName,
String user,
long time,
Map<String, Serializable> values)
{
Map<String, Object> entry = new HashMap<String, Object>(11);
entry.put(JSON_KEY_ENTRY_ID, entryId);
entry.put(JSON_KEY_ENTRY_APPLICATION, applicationName);
if (user != null)
{
entry.put(JSON_KEY_ENTRY_USER, user);
}
entry.put(JSON_KEY_ENTRY_TIME, new Date(time));
if (values != null)
{
// Convert values to Strings
Map<String, String> valueStrings = new HashMap<String, String>(values.size() * 2);
for (Map.Entry<String, Serializable> mapEntry : values.entrySet())
{
String key = mapEntry.getKey();
Serializable value = mapEntry.getValue();
try
{
String valueString = DefaultTypeConverter.INSTANCE.convert(String.class, value);
valueStrings.put(key, valueString);
}
catch (ClassCastException e)
{
// Fix for symptoms of MNT-20992. It is possible to have MLText values whose underlying
// map's keys are not Locale, as MLText map keys should be. In this case we can expect
// a ClassCastException.
if (!(value instanceof MLText))
{
// Rethrow if the exception was not caused by the expected MLText conversion.
throw e;
}
valueStrings.put(key, value.toString());
}
catch (TypeConversionException e)
{
// Use the toString()
valueStrings.put(key, value.toString());
}
}
entry.put(JSON_KEY_ENTRY_VALUES, valueStrings);
}
entries.add(entry);
return true;
}
};
auditService.auditQuery(callback, params, limit);
model.put(JSON_KEY_ENTRY_COUNT, entries.size());
model.put(JSON_KEY_ENTRIES, entries);
// Done
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.audit;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.service.cmr.audit.AuditQueryParameters;
import org.alfresco.service.cmr.audit.AuditService.AuditApplication;
import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback;
import org.alfresco.service.cmr.repository.MLText;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.repository.datatype.TypeConversionException;
/**
* @author Derek Hulley
* @since 3.4
*/
public class AuditQueryGet extends AbstractAuditWebScript
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
final Map<String, Object> model = new HashMap<String, Object>(7);
String appName = getParamAppName(req);
String path = getParamPath(req);
Serializable value = getParamValue(req);
String valueType = getParamValueType(req);
Long fromTime = getParamFromTime(req);
Long toTime = getParamToTime(req);
Long fromId = getParamFromId(req);
Long toId = getParamToId(req);
String user = getParamUser(req);
boolean forward = getParamForward(req);
int limit = getParamLimit(req);
final boolean verbose = getParamVerbose(req);
if (appName == null)
{
Map<String, AuditApplication> appsByName = auditService.getAuditApplications();
AuditApplication app = appsByName.get(appName);
if (app == null)
{
throw new WebScriptException(Status.STATUS_NOT_FOUND, "audit.err.app.notFound", appName);
}
}
// Transform the value to the correct type
if (value != null && valueType != null)
{
try
{
@SuppressWarnings("unchecked")
Class<? extends Serializable> clazz = (Class<? extends Serializable>) Class.forName(valueType);
value = DefaultTypeConverter.INSTANCE.convert(clazz, value);
}
catch (ClassNotFoundException e)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "audit.err.value.classNotFound", valueType);
}
catch (Throwable e)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "audit.err.value.convertFailed", value, valueType);
}
}
// Execute the query
AuditQueryParameters params = new AuditQueryParameters();
params.setApplicationName(appName);
params.setFromTime(fromTime);
params.setToTime(toTime);
params.setFromId(fromId);
params.setToId(toId);
params.setUser(user);
params.setForward(forward);
if (path != null || value != null)
{
params.addSearchKey(path, value);
}
final List<Map<String, Object>> entries = new ArrayList<Map<String, Object>>(limit);
AuditQueryCallback callback = new AuditQueryCallback() {
@Override
public boolean valuesRequired()
{
return verbose;
}
@Override
public boolean handleAuditEntryError(Long entryId, String errorMsg, Throwable error)
{
return true;
}
@Override
public boolean handleAuditEntry(
Long entryId,
String applicationName,
String user,
long time,
Map<String, Serializable> values)
{
Map<String, Object> entry = new HashMap<String, Object>(11);
entry.put(JSON_KEY_ENTRY_ID, entryId);
entry.put(JSON_KEY_ENTRY_APPLICATION, applicationName);
if (user != null)
{
entry.put(JSON_KEY_ENTRY_USER, user);
}
entry.put(JSON_KEY_ENTRY_TIME, new Date(time));
if (values != null)
{
// Convert values to Strings
Map<String, String> valueStrings = new HashMap<String, String>(values.size() * 2);
for (Map.Entry<String, Serializable> mapEntry : values.entrySet())
{
String key = mapEntry.getKey();
Serializable value = mapEntry.getValue();
try
{
String valueString = DefaultTypeConverter.INSTANCE.convert(String.class, value);
valueStrings.put(key, valueString);
}
catch (ClassCastException e)
{
// Fix for symptoms of MNT-20992. It is possible to have MLText values whose underlying
// map's keys are not Locale, as MLText map keys should be. In this case we can expect
// a ClassCastException.
if (!(value instanceof MLText))
{
// Rethrow if the exception was not caused by the expected MLText conversion.
throw e;
}
valueStrings.put(key, value.toString());
}
catch (TypeConversionException e)
{
// Use the toString()
valueStrings.put(key, value.toString());
}
}
entry.put(JSON_KEY_ENTRY_VALUES, valueStrings);
}
entries.add(entry);
return true;
}
};
auditService.auditQuery(callback, params, limit);
model.put(JSON_KEY_ENTRY_COUNT, entries.size());
model.put(JSON_KEY_ENTRIES, entries);
// Done
if (logger.isDebugEnabled())
{
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
}
return model;
}
}

View File

@@ -1,116 +1,116 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.bean;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import jakarta.servlet.http.HttpServletResponse;
import org.alfresco.sync.events.types.Event;
import org.alfresco.sync.events.types.RepositoryEventImpl;
import org.alfresco.sync.repo.events.EventPreparator;
import org.alfresco.sync.repo.events.EventPublisher;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Common code between Get based login and POST based login
*/
/* package scope */ abstract class AbstractLoginBean extends DeclarativeWebScript
{
// dependencies
private AuthenticationService authenticationService;
protected EventPublisher eventPublisher;
/**
* @param authenticationService AuthenticationService
*/
public void setAuthenticationService(AuthenticationService authenticationService)
{
this.authenticationService = authenticationService;
}
/**
* @param eventPublisher EventPublisher
*/
public void setEventPublisher(EventPublisher eventPublisher)
{
this.eventPublisher = eventPublisher;
}
/* (non-Javadoc)
* @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, Status status)
{
return null;
}
protected Map<String, Object> login(final String username, String password)
{
try
{
// get ticket
authenticationService.authenticate(username, password.toCharArray());
eventPublisher.publishEvent(new EventPreparator(){
@Override
public Event prepareEvent(String user, String networkId, String transactionId)
{
// TODO need to fix up to pass correct seqNo and alfrescoClientId
return new RepositoryEventImpl(-1l, "login", transactionId, networkId, new Date().getTime(),
username, null);
}
});
// add ticket to model for javascript and template access
Map<String, Object> model = new HashMap<String, Object>(7, 1.0f);
model.put("username", username);
model.put("ticket", authenticationService.getCurrentTicket());
return model;
}
catch(AuthenticationException e)
{
throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "Login failed");
}
finally
{
AuthenticationUtil.clearCurrentSecurityContext();
}
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.bean;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.sync.events.types.Event;
import org.alfresco.sync.events.types.RepositoryEventImpl;
import org.alfresco.sync.repo.events.EventPreparator;
import org.alfresco.sync.repo.events.EventPublisher;
/**
* Common code between Get based login and POST based login
*/
/* package scope */ abstract class AbstractLoginBean extends DeclarativeWebScript
{
// dependencies
private AuthenticationService authenticationService;
protected EventPublisher eventPublisher;
/**
* @param authenticationService
* AuthenticationService
*/
public void setAuthenticationService(AuthenticationService authenticationService)
{
this.authenticationService = authenticationService;
}
/**
* @param eventPublisher
* EventPublisher
*/
public void setEventPublisher(EventPublisher eventPublisher)
{
this.eventPublisher = eventPublisher;
}
/* (non-Javadoc)
*
* @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, Status status)
{
return null;
}
protected Map<String, Object> login(final String username, String password)
{
try
{
// get ticket
authenticationService.authenticate(username, password.toCharArray());
eventPublisher.publishEvent(new EventPreparator() {
@Override
public Event prepareEvent(String user, String networkId, String transactionId)
{
// TODO need to fix up to pass correct seqNo and alfrescoClientId
return new RepositoryEventImpl(-1l, "login", transactionId, networkId, new Date().getTime(),
username, null);
}
});
// add ticket to model for javascript and template access
Map<String, Object> model = new HashMap<String, Object>(7, 1.0f);
model.put("username", username);
model.put("ticket", authenticationService.getCurrentTicket());
return model;
}
catch (AuthenticationException e)
{
throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "Login failed");
}
finally
{
AuthenticationUtil.clearCurrentSecurityContext();
}
}
}

View File

@@ -23,42 +23,42 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.bean;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* WebScript java backed bean implementation - to return information about the
* authentication system, such as account mutability.
*
* @author Kevin Roast
*/
public class Authentication extends DeclarativeWebScript
{
private MutableAuthenticationService authenticationService;
public void setAuthenticationService(AuthenticationService authenticationService)
{
this.authenticationService = (MutableAuthenticationService)authenticationService;
}
/* (non-Javadoc)
* @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, Status status)
{
Map<String, Object> model = new HashMap<String, Object>(2);
model.put("creationAllowed", this.authenticationService.isAuthenticationCreationAllowed());
return model;
}
}
package org.alfresco.repo.web.scripts.bean;
import java.util.HashMap;
import java.util.Map;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
/**
* WebScript java backed bean implementation - to return information about the authentication system, such as account mutability.
*
* @author Kevin Roast
*/
public class Authentication extends DeclarativeWebScript
{
private MutableAuthenticationService authenticationService;
public void setAuthenticationService(AuthenticationService authenticationService)
{
this.authenticationService = (MutableAuthenticationService) authenticationService;
}
/* (non-Javadoc)
*
* @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, Status status)
{
Map<String, Object> model = new HashMap<String, Object>(2);
model.put("creationAllowed", this.authenticationService.isAuthenticationCreationAllowed());
return model;
}
}

View File

@@ -23,392 +23,391 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.bean;
import java.io.StringWriter;
import java.io.Writer;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.alfresco.repo.template.TemplateNode;
import org.alfresco.repo.web.scripts.RepositoryImageResolver;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.util.GUID;
import org.alfresco.util.SearchLanguageConversion;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
import org.springframework.extensions.surf.util.ParameterCheck;
import org.springframework.extensions.surf.util.URLEncoder;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Alfresco Keyword (simple) Search Service
*
* @author davidc
*/
public class KeywordSearch extends DeclarativeWebScript
{
// Logger
private static final Log logger = LogFactory.getLog(KeywordSearch.class);
// search parameters
// TODO: allow configuration of search store
protected static final StoreRef SEARCH_STORE = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore");
protected static final int DEFAULT_ITEMS_PER_PAGE = 10;
protected static final String QUERY_FORMAT = "query_";
// dependencies
protected ServiceRegistry serviceRegistry;
protected RepositoryImageResolver imageResolver;
protected SearchService searchService;
protected NodeService nodeService;
public void setSearchService(SearchService searchService)
{
this.searchService = searchService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setRepositoryImageResolver(RepositoryImageResolver imageResolver)
{
this.imageResolver = imageResolver;
}
public void setServiceRegistry(ServiceRegistry serviceRegistry)
{
this.serviceRegistry = serviceRegistry;
}
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
//
// process arguments
//
String searchTerms = req.getParameter("q");
ParameterCheck.mandatoryString("q", searchTerms);
String startPageArg = req.getParameter("p");
int startPage = 1;
try
{
startPage = Integer.valueOf(startPageArg);
}
catch(NumberFormatException e)
{
// NOTE: use default startPage
}
String itemsPerPageArg = req.getParameter("c");
int itemsPerPage = DEFAULT_ITEMS_PER_PAGE;
try
{
itemsPerPage = Integer.valueOf(itemsPerPageArg);
}
catch(NumberFormatException e)
{
// NOTE: use default itemsPerPage
}
Locale locale = I18NUtil.getLocale();
String language = req.getParameter("l");
if (language != null && language.length() > 0)
{
// NOTE: Simple conversion from XML Language Id to Java Locale Id
locale = new Locale(language.replace("-", "_"));
}
//
// execute the search
//
SearchResult results = search(searchTerms, startPage, itemsPerPage, locale, req);
//
// create model
//
Map<String, Object> model = new HashMap<String, Object>(7, 1.0f);
model.put("search", results);
return model;
}
/**
* Execute the search
*/
private SearchResult search(String searchTerms, int startPage, int itemsPerPage, Locale locale, WebScriptRequest req)
{
SearchResult searchResult = null;
ResultSet results = null;
try
{
// construct search statement
String[] terms = searchTerms.split(" ");
searchTerms = searchTerms.replaceAll("\"", "&quot;");
// Escape special characters in the terms, so that they can't confuse the parser
for (int i=0; i<terms.length; i++)
{
terms[i] = SearchLanguageConversion.escapeLuceneQuery(terms[i]);
}
Map<String, Object> statementModel = new HashMap<String, Object>(7, 1.0f);
statementModel.put("args", createArgs(req));
statementModel.put("terms", terms);
Writer queryWriter = new StringWriter(1024);
renderFormatTemplate(QUERY_FORMAT, statementModel, queryWriter);
String query = queryWriter.toString();
// execute query
if (logger.isDebugEnabled())
{
logger.debug("Search parameters: searchTerms=" + searchTerms + ", startPage=" + startPage + ", itemsPerPage=" + itemsPerPage + ", search locale=" + locale.toString());
logger.debug("Issuing lucene search: " + query);
}
SearchParameters parameters = new SearchParameters();
parameters.addStore(SEARCH_STORE);
parameters.setLanguage(SearchService.LANGUAGE_LUCENE);
parameters.setQuery(query);
if (locale != null)
{
parameters.addLocale(locale);
}
results = searchService.query(parameters);
int totalResults = results.length();
if (logger.isDebugEnabled())
logger.debug("Results: " + totalResults + " rows (limited: " + results.getResultSetMetaData().getLimitedBy() + ")");
// are we out-of-range
int totalPages = (totalResults / itemsPerPage);
totalPages += (totalResults % itemsPerPage != 0) ? 1 : 0;
if (totalPages != 0 && (startPage < 1 || startPage > totalPages))
{
throw new WebScriptException("Start page " + startPage + " is outside boundary of " + totalPages + " pages");
}
// construct search result
searchResult = new SearchResult();
searchResult.setSearchTerms(searchTerms);
searchResult.setLocale(locale);
searchResult.setItemsPerPage(itemsPerPage);
searchResult.setStartPage(startPage);
searchResult.setTotalResults(totalResults);
if (totalResults == 0)
{
searchResult.setTotalPages(0);
searchResult.setStartIndex(0);
searchResult.setTotalPageItems(0);
}
else
{
searchResult.setTotalPages(totalPages);
searchResult.setStartIndex(((startPage -1) * itemsPerPage) + 1);
searchResult.setTotalPageItems(Math.min(itemsPerPage, totalResults - searchResult.getStartIndex() + 1));
}
SearchTemplateNode[] nodes = new SearchTemplateNode[searchResult.getTotalPageItems()];
for (int i = 0; i < searchResult.getTotalPageItems(); i++)
{
NodeRef node = results.getNodeRef(i + searchResult.getStartIndex() - 1);
// Make the search resilient to invalid nodes
if (!nodeService.exists(node))
{
continue;
}
float score = results.getScore(i + searchResult.getStartIndex() - 1);
nodes[i] = new SearchTemplateNode(node, score);
}
searchResult.setResults(nodes);
return searchResult;
}
finally
{
if (results != null)
{
results.close();
}
}
}
/**
* Search Result
*
* @author davidc
*/
public static class SearchResult
{
private String id;
private String searchTerms;
private Locale locale;
private int itemsPerPage;
private int totalPages;
private int totalResults;
private int totalPageItems;
private int startPage;
private int startIndex;
private SearchTemplateNode[] results;
public int getItemsPerPage()
{
return itemsPerPage;
}
/*package*/ void setItemsPerPage(int itemsPerPage)
{
this.itemsPerPage = itemsPerPage;
}
public TemplateNode[] getResults()
{
return results;
}
/*package*/ void setResults(SearchTemplateNode[] results)
{
this.results = results;
}
public int getStartIndex()
{
return startIndex;
}
/*package*/ void setStartIndex(int startIndex)
{
this.startIndex = startIndex;
}
public int getStartPage()
{
return startPage;
}
/*package*/ void setStartPage(int startPage)
{
this.startPage = startPage;
}
public int getTotalPageItems()
{
return totalPageItems;
}
/*package*/ void setTotalPageItems(int totalPageItems)
{
this.totalPageItems = totalPageItems;
}
public int getTotalPages()
{
return totalPages;
}
/*package*/ void setTotalPages(int totalPages)
{
this.totalPages = totalPages;
}
public int getTotalResults()
{
return totalResults;
}
/*package*/ void setTotalResults(int totalResults)
{
this.totalResults = totalResults;
}
public String getSearchTerms()
{
return searchTerms;
}
/*package*/ void setSearchTerms(String searchTerms)
{
this.searchTerms = searchTerms;
}
public Locale getLocale()
{
return locale;
}
/**
* @return XML 1.0 Language Identification
*/
public String getLocaleId()
{
return locale.toString().replace('_', '-');
}
/*package*/ void setLocale(Locale locale)
{
this.locale = locale;
}
public String getId()
{
if (id == null)
{
id = GUID.generate();
}
return id;
}
}
/**
* Search result row template node
*/
public class SearchTemplateNode extends TemplateNode
{
protected final static String URL = "/api/node/content/{0}/{1}/{2}/{3}";
private static final long serialVersionUID = -1791913270786140012L;
private float score;
/**
* Construct
*/
public SearchTemplateNode(NodeRef nodeRef, float score)
{
super(nodeRef, serviceRegistry, KeywordSearch.this.imageResolver.getImageResolver());
this.score = score;
}
/**
* Gets the result row score
*/
public float getScore()
{
return score;
}
@Override
public String getUrl()
{
return MessageFormat.format(URL, new Object[] {
getNodeRef().getStoreRef().getProtocol(),
getNodeRef().getStoreRef().getIdentifier(),
getNodeRef().getId(),
URLEncoder.encode(getName()) } );
}
}
}
package org.alfresco.repo.web.scripts.bean;
import java.io.StringWriter;
import java.io.Writer;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
import org.springframework.extensions.surf.util.ParameterCheck;
import org.springframework.extensions.surf.util.URLEncoder;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.alfresco.repo.template.TemplateNode;
import org.alfresco.repo.web.scripts.RepositoryImageResolver;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.util.GUID;
import org.alfresco.util.SearchLanguageConversion;
/**
* Alfresco Keyword (simple) Search Service
*
* @author davidc
*/
public class KeywordSearch extends DeclarativeWebScript
{
// Logger
private static final Log logger = LogFactory.getLog(KeywordSearch.class);
// search parameters
// TODO: allow configuration of search store
protected static final StoreRef SEARCH_STORE = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore");
protected static final int DEFAULT_ITEMS_PER_PAGE = 10;
protected static final String QUERY_FORMAT = "query_";
// dependencies
protected ServiceRegistry serviceRegistry;
protected RepositoryImageResolver imageResolver;
protected SearchService searchService;
protected NodeService nodeService;
public void setSearchService(SearchService searchService)
{
this.searchService = searchService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setRepositoryImageResolver(RepositoryImageResolver imageResolver)
{
this.imageResolver = imageResolver;
}
public void setServiceRegistry(ServiceRegistry serviceRegistry)
{
this.serviceRegistry = serviceRegistry;
}
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
//
// process arguments
//
String searchTerms = req.getParameter("q");
ParameterCheck.mandatoryString("q", searchTerms);
String startPageArg = req.getParameter("p");
int startPage = 1;
try
{
startPage = Integer.valueOf(startPageArg);
}
catch (NumberFormatException e)
{
// NOTE: use default startPage
}
String itemsPerPageArg = req.getParameter("c");
int itemsPerPage = DEFAULT_ITEMS_PER_PAGE;
try
{
itemsPerPage = Integer.valueOf(itemsPerPageArg);
}
catch (NumberFormatException e)
{
// NOTE: use default itemsPerPage
}
Locale locale = I18NUtil.getLocale();
String language = req.getParameter("l");
if (language != null && language.length() > 0)
{
// NOTE: Simple conversion from XML Language Id to Java Locale Id
locale = new Locale(language.replace("-", "_"));
}
//
// execute the search
//
SearchResult results = search(searchTerms, startPage, itemsPerPage, locale, req);
//
// create model
//
Map<String, Object> model = new HashMap<String, Object>(7, 1.0f);
model.put("search", results);
return model;
}
/**
* Execute the search
*/
private SearchResult search(String searchTerms, int startPage, int itemsPerPage, Locale locale, WebScriptRequest req)
{
SearchResult searchResult = null;
ResultSet results = null;
try
{
// construct search statement
String[] terms = searchTerms.split(" ");
searchTerms = searchTerms.replaceAll("\"", "&quot;");
// Escape special characters in the terms, so that they can't confuse the parser
for (int i = 0; i < terms.length; i++)
{
terms[i] = SearchLanguageConversion.escapeLuceneQuery(terms[i]);
}
Map<String, Object> statementModel = new HashMap<String, Object>(7, 1.0f);
statementModel.put("args", createArgs(req));
statementModel.put("terms", terms);
Writer queryWriter = new StringWriter(1024);
renderFormatTemplate(QUERY_FORMAT, statementModel, queryWriter);
String query = queryWriter.toString();
// execute query
if (logger.isDebugEnabled())
{
logger.debug("Search parameters: searchTerms=" + searchTerms + ", startPage=" + startPage + ", itemsPerPage=" + itemsPerPage + ", search locale=" + locale.toString());
logger.debug("Issuing lucene search: " + query);
}
SearchParameters parameters = new SearchParameters();
parameters.addStore(SEARCH_STORE);
parameters.setLanguage(SearchService.LANGUAGE_LUCENE);
parameters.setQuery(query);
if (locale != null)
{
parameters.addLocale(locale);
}
results = searchService.query(parameters);
int totalResults = results.length();
if (logger.isDebugEnabled())
logger.debug("Results: " + totalResults + " rows (limited: " + results.getResultSetMetaData().getLimitedBy() + ")");
// are we out-of-range
int totalPages = (totalResults / itemsPerPage);
totalPages += (totalResults % itemsPerPage != 0) ? 1 : 0;
if (totalPages != 0 && (startPage < 1 || startPage > totalPages))
{
throw new WebScriptException("Start page " + startPage + " is outside boundary of " + totalPages + " pages");
}
// construct search result
searchResult = new SearchResult();
searchResult.setSearchTerms(searchTerms);
searchResult.setLocale(locale);
searchResult.setItemsPerPage(itemsPerPage);
searchResult.setStartPage(startPage);
searchResult.setTotalResults(totalResults);
if (totalResults == 0)
{
searchResult.setTotalPages(0);
searchResult.setStartIndex(0);
searchResult.setTotalPageItems(0);
}
else
{
searchResult.setTotalPages(totalPages);
searchResult.setStartIndex(((startPage - 1) * itemsPerPage) + 1);
searchResult.setTotalPageItems(Math.min(itemsPerPage, totalResults - searchResult.getStartIndex() + 1));
}
SearchTemplateNode[] nodes = new SearchTemplateNode[searchResult.getTotalPageItems()];
for (int i = 0; i < searchResult.getTotalPageItems(); i++)
{
NodeRef node = results.getNodeRef(i + searchResult.getStartIndex() - 1);
// Make the search resilient to invalid nodes
if (!nodeService.exists(node))
{
continue;
}
float score = results.getScore(i + searchResult.getStartIndex() - 1);
nodes[i] = new SearchTemplateNode(node, score);
}
searchResult.setResults(nodes);
return searchResult;
}
finally
{
if (results != null)
{
results.close();
}
}
}
/**
* Search Result
*
* @author davidc
*/
public static class SearchResult
{
private String id;
private String searchTerms;
private Locale locale;
private int itemsPerPage;
private int totalPages;
private int totalResults;
private int totalPageItems;
private int startPage;
private int startIndex;
private SearchTemplateNode[] results;
public int getItemsPerPage()
{
return itemsPerPage;
}
/* package */ void setItemsPerPage(int itemsPerPage)
{
this.itemsPerPage = itemsPerPage;
}
public TemplateNode[] getResults()
{
return results;
}
/* package */ void setResults(SearchTemplateNode[] results)
{
this.results = results;
}
public int getStartIndex()
{
return startIndex;
}
/* package */ void setStartIndex(int startIndex)
{
this.startIndex = startIndex;
}
public int getStartPage()
{
return startPage;
}
/* package */ void setStartPage(int startPage)
{
this.startPage = startPage;
}
public int getTotalPageItems()
{
return totalPageItems;
}
/* package */ void setTotalPageItems(int totalPageItems)
{
this.totalPageItems = totalPageItems;
}
public int getTotalPages()
{
return totalPages;
}
/* package */ void setTotalPages(int totalPages)
{
this.totalPages = totalPages;
}
public int getTotalResults()
{
return totalResults;
}
/* package */ void setTotalResults(int totalResults)
{
this.totalResults = totalResults;
}
public String getSearchTerms()
{
return searchTerms;
}
/* package */ void setSearchTerms(String searchTerms)
{
this.searchTerms = searchTerms;
}
public Locale getLocale()
{
return locale;
}
/**
* @return XML 1.0 Language Identification
*/
public String getLocaleId()
{
return locale.toString().replace('_', '-');
}
/* package */ void setLocale(Locale locale)
{
this.locale = locale;
}
public String getId()
{
if (id == null)
{
id = GUID.generate();
}
return id;
}
}
/**
* Search result row template node
*/
public class SearchTemplateNode extends TemplateNode
{
protected final static String URL = "/api/node/content/{0}/{1}/{2}/{3}";
private static final long serialVersionUID = -1791913270786140012L;
private float score;
/**
* Construct
*/
public SearchTemplateNode(NodeRef nodeRef, float score)
{
super(nodeRef, serviceRegistry, KeywordSearch.this.imageResolver.getImageResolver());
this.score = score;
}
/**
* Gets the result row score
*/
public float getScore()
{
return score;
}
@Override
public String getUrl()
{
return MessageFormat.format(URL, new Object[]{
getNodeRef().getStoreRef().getProtocol(),
getNodeRef().getStoreRef().getIdentifier(),
getNodeRef().getId(),
URLEncoder.encode(getName())});
}
}
}

View File

@@ -1,72 +1,71 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.bean;
import java.util.Map;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Login and establish a ticket
*
* @author davidc
*/
public class Login extends AbstractLoginBean
{
/* (non-Javadoc)
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
*/
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
// extract username and password
String username = req.getParameter("u");
if (username == null || username.length() == 0)
{
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Username not specified");
}
String password = req.getParameter("pw");
if (password == null)
{
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Password not specified");
}
try
{
return login(username, password);
}
catch(WebScriptException e)
{
status.setCode(e.getStatus());
status.setMessage(e.getMessage());
status.setRedirect(true);
return null;
}
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.bean;
import java.util.Map;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Login and establish a ticket
*
* @author davidc
*/
public class Login extends AbstractLoginBean
{
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse) */
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
// extract username and password
String username = req.getParameter("u");
if (username == null || username.length() == 0)
{
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Username not specified");
}
String password = req.getParameter("pw");
if (password == null)
{
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Password not specified");
}
try
{
return login(username, password);
}
catch (WebScriptException e)
{
status.setCode(e.getStatus());
status.setMessage(e.getMessage());
status.setRedirect(true);
return null;
}
}
}

View File

@@ -1,100 +1,99 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.bean;
import java.io.IOException;
import java.util.Map;
import jakarta.servlet.http.HttpServletResponse;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.extensions.surf.util.Content;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Post based login script
*/
public class LoginPost extends AbstractLoginBean
{
/* (non-Javadoc)
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse)
*/
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
// Extract user and password from JSON POST
Content c = req.getContent();
if (c == null)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Missing POST body.");
}
// TODO accept xml type.
// extract username and password from JSON object
JSONObject json;
try
{
json = new JSONObject(c.getContent());
String username = json.getString("username");
String password = json.getString("password");
if (username == null || username.length() == 0)
{
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Username not specified");
}
if (password == null)
{
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Password not specified");
}
try
{
return login(username, password);
}
catch(WebScriptException e)
{
status.setCode(e.getStatus());
status.setMessage(e.getMessage());
status.setRedirect(true);
return null;
}
}
catch (JSONException jErr)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
"Unable to parse JSON POST body: " + jErr.getMessage());
}
catch (IOException ioErr)
{
throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR,
"Unable to retrieve POST body: " + ioErr.getMessage());
}
}
}
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2023 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.repo.web.scripts.bean;
import java.io.IOException;
import java.util.Map;
import jakarta.servlet.http.HttpServletResponse;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.extensions.surf.util.Content;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* Post based login script
*/
public class LoginPost extends AbstractLoginBean
{
/* (non-Javadoc)
*
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse) */
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
{
// Extract user and password from JSON POST
Content c = req.getContent();
if (c == null)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Missing POST body.");
}
// TODO accept xml type.
// extract username and password from JSON object
JSONObject json;
try
{
json = new JSONObject(c.getContent());
String username = json.getString("username");
String password = json.getString("password");
if (username == null || username.length() == 0)
{
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Username not specified");
}
if (password == null)
{
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Password not specified");
}
try
{
return login(username, password);
}
catch (WebScriptException e)
{
status.setCode(e.getStatus());
status.setMessage(e.getMessage());
status.setRedirect(true);
return null;
}
}
catch (JSONException jErr)
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
"Unable to parse JSON POST body: " + jErr.getMessage());
}
catch (IOException ioErr)
{
throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR,
"Unable to retrieve POST body: " + ioErr.getMessage());
}
}
}

Some files were not shown because too many files have changed in this diff Show More