mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-21 18:09:20 +00:00
Merged DEV/SWIFT to HEAD
26495: Removed svn:mergeinfo from 'root' 26520: Fixed targetSchema values for merged-in patches 26521: ALF-5260 - RINF 06: Switch from iBatis to MyBatis - fix for selectChildAssocsWithoutParentAssocsOfType and selectChildAssocsByChildTypes 26531: Removed obsolete code to fix compilation error following OpenCMIS updates. 26551: Patch to remove old alf_*attribute* tables (ALF-3192, ALF-6724) 26555: Fixed ALF-7960: Upgrade incorrectly reports zero patches run - Use JdbcType.TIMESTAMP instead of DATE to prevent time truncation in alf_applied_patch 26557: Patch to remove old alf_*attribute* tables (ALF-3192, ALF-6724) - Support for all DBs - Included removal of sequence - Uses DAO hierarchical bean override for sequence removal 26577: SWIFT: fix AuthenticationTest.* fails - fallout from r25966 - keep "validate" as R/O but put back txn propogation (as before) 26583: SWIFT build: fix DefaultTypeConverterTest.testInterConversions() - fallout from OpenCMIS merge (r25458) 26615: Remove svn:mergeinfo from root (again) 26646: Test case addition related to ALF-619. setMembership() method on SiteService needs to check that the given site 'role' is valid. This issue was not reproduced. I'm checking in the test code I used to ensure that invalid roles are rejected. It'll keep the exception type stable from now on too (not implying it wasn't stable in the past!) 26744: ALF-8061 - MyBatis: fix mappings for Oracle (nullable parameters) - Activities, Audit, AVM 26745: Created NodeLocatorService which allows access to registered NodeLocators. Also created node-location.get webscript which provides access to the NodeLocationService via a RESTful webscript. 26774: Fixing failing NodeLocationServiceImplTest. 26799: ALF-8061 - MyBatis: fix mappings for Oracle (nullable parameters) - follow-on to r26744 26809: Fixed ALF-8157: Method removeSeconaryChildAssociation() in NodeService is spelt incorrectly - Old method is Deprecated and final - Redirect implementations to correctly-named method 26869: Javadoc update for LockService. 28254: ALF-8805: RINF 40: Lucene Removal: PersonService API - follow-on (remove unused SearchService) Note: Tested repo upgrade from V3.3 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28282 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
<webscript>
|
||||
<shortname>Locate Node</shortname>
|
||||
<description>
|
||||
Locates a Node in the repository using the specified Node Location strategy.
|
||||
</description>
|
||||
<url>/api/{store_type}/{store_id}/{node_id}/nodelocator/{node_locator_name}</url>
|
||||
<url>/api/nodelocator/{node_locator_name}</url>
|
||||
<format default="json"/>
|
||||
<authentication>user</authentication>
|
||||
<transaction allow="readonly">required</transaction>
|
||||
</webscript>
|
@@ -0,0 +1,11 @@
|
||||
{
|
||||
data:
|
||||
{
|
||||
<#if nodeRef?? >
|
||||
nodeRef: "${nodeRef}"
|
||||
<#else >
|
||||
nodeRef: null
|
||||
</#if>
|
||||
}
|
||||
}
|
||||
|
@@ -1254,4 +1254,11 @@
|
||||
<property name="nodeDAO" ref="nodeDAO"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<bean id="webscript.org.alfresco.repository.nodelocator.node-location.get"
|
||||
class="org.alfresco.repo.web.scripts.nodelocator.NodeLocationGet"
|
||||
parent="webscript">
|
||||
<property name="nodeLocatorService" ref="nodeLocatorService"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
package org.alfresco.repo.web.scripts.nodelocator;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeLocatorService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.springframework.extensions.surf.util.URLDecoder;
|
||||
import org.springframework.extensions.webscripts.DeclarativeWebScript;
|
||||
import org.springframework.extensions.webscripts.Status;
|
||||
import org.springframework.extensions.webscripts.WebScriptException;
|
||||
import org.springframework.extensions.webscripts.WebScriptRequest;
|
||||
|
||||
/**
|
||||
* @author Nick Smith
|
||||
* @since 4.0
|
||||
*
|
||||
*/
|
||||
public class NodeLocationGet extends DeclarativeWebScript
|
||||
{
|
||||
private static final String NODE_ID = "node_id";
|
||||
private static final String STORE_ID = "store_id";
|
||||
private static final String STORE_TYPE = "store_type";
|
||||
private static final String NODE_LOCATOR_NAME = "node_locator_name";
|
||||
private NodeLocatorService locatorService;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
|
||||
{
|
||||
Map<String, String> vars = req.getServiceMatch().getTemplateVars();
|
||||
// getting task id from request parameters
|
||||
String locatorName = vars.get(NODE_LOCATOR_NAME);
|
||||
|
||||
// No locatorname specified -> return 404
|
||||
if (locatorName == null)
|
||||
{
|
||||
throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "No NodeLocator strategy was specified!");
|
||||
}
|
||||
|
||||
NodeRef source = null;
|
||||
String storeType = vars.get(STORE_TYPE);
|
||||
String storeId= vars.get(STORE_ID);
|
||||
String nodeId= vars.get(NODE_ID);
|
||||
if(storeType!=null && storeId != null && nodeId != null)
|
||||
{
|
||||
source = new NodeRef(storeType, storeId, nodeId);
|
||||
}
|
||||
|
||||
Map<String, Serializable> params = mapParams(req);
|
||||
|
||||
NodeRef node = locatorService.getNode(locatorName, source, params);
|
||||
|
||||
Map<String, Object> model = new HashMap<String, Object>();
|
||||
model.put("nodeRef", node==null ? null : node.toString());
|
||||
return model;
|
||||
}
|
||||
|
||||
private Map<String, Serializable> mapParams(WebScriptRequest req)
|
||||
{
|
||||
Map<String, Serializable> params = new HashMap<String, Serializable>();
|
||||
for(String key: req.getParameterNames())
|
||||
{
|
||||
String value = req.getParameter(key);
|
||||
if (value != null)
|
||||
{
|
||||
String decodedValue = URLDecoder.decode(value);
|
||||
// TODO Handle type conversions here.
|
||||
params.put(key, decodedValue);
|
||||
}
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param locatorService the locatorService to set
|
||||
*/
|
||||
public void setNodeLocatorService(NodeLocatorService locatorService)
|
||||
{
|
||||
this.locatorService = locatorService;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
package org.alfresco.repo.web.scripts.nodelocator;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.model.Repository;
|
||||
import org.alfresco.repo.node.locator.AncestorNodeLocator;
|
||||
import org.alfresco.repo.node.locator.CompanyHomeNodeLocator;
|
||||
import org.alfresco.repo.node.locator.DocLibNodeLocator;
|
||||
import org.alfresco.repo.node.locator.SitesHomeNodeLocator;
|
||||
import org.alfresco.repo.node.locator.UserHomeNodeLocator;
|
||||
import org.alfresco.repo.node.locator.XPathNodeLocator;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.site.SiteServiceInternal;
|
||||
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
|
||||
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.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.site.SiteInfo;
|
||||
import org.alfresco.service.cmr.site.SiteService;
|
||||
import org.alfresco.service.cmr.site.SiteVisibility;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.json.JSONObject;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.extensions.surf.util.URLEncoder;
|
||||
import org.springframework.extensions.webscripts.TestWebScriptServer.GetRequest;
|
||||
import org.springframework.extensions.webscripts.TestWebScriptServer.Response;
|
||||
|
||||
/**
|
||||
* @author Nick Smith
|
||||
* @since 4.0
|
||||
*
|
||||
*/
|
||||
public class NodeLocationWebScriptTest extends BaseWebScriptTest
|
||||
{
|
||||
private static final String baseURL = "api/nodelocator/";
|
||||
private SiteServiceInternal siteService;
|
||||
private NodeService nodeService;
|
||||
private Repository repositoryHelper;
|
||||
private NodeRef companyHome;
|
||||
private NamespaceService namespaceService;
|
||||
|
||||
public void testCompanyHomeNodeLocator() throws Exception
|
||||
{
|
||||
String url = baseURL + CompanyHomeNodeLocator.NAME;
|
||||
checkNodeLocator(url, companyHome);
|
||||
}
|
||||
|
||||
public void testSitesHomeNodeLocator() throws Exception
|
||||
{
|
||||
String url = baseURL + SitesHomeNodeLocator.NAME;
|
||||
NodeRef sitesHome = siteService.getSiteRoot();
|
||||
checkNodeLocator(url, sitesHome);
|
||||
}
|
||||
|
||||
public void testDocLibNodeLocator() throws Exception
|
||||
{
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||
SiteInfo site = null;
|
||||
|
||||
NodeRef companyChild = makeChildContentNode(companyHome);
|
||||
try
|
||||
{
|
||||
// Set up site
|
||||
String siteName = "TestSite" + GUID.generate();
|
||||
site = siteService.createSite("", siteName, "Title", "Description", SiteVisibility.PUBLIC);
|
||||
NodeRef fooFolder = makeContainer(siteName, "Foo");
|
||||
NodeRef docLib = makeContainer(siteName, SiteService.DOCUMENT_LIBRARY);
|
||||
NodeRef fooChild = makeChildContentNode(fooFolder);
|
||||
NodeRef docLibChild = makeChildContentNode(docLib);
|
||||
|
||||
// Check returns company home if no source node specified.
|
||||
String noNodeUrl = baseURL + DocLibNodeLocator.NAME;
|
||||
checkNodeLocator(noNodeUrl, companyHome);
|
||||
|
||||
// Check returns company home if source is not in a site.
|
||||
String noSiteUrl = makeUrl(companyChild, DocLibNodeLocator.NAME);
|
||||
checkNodeLocator(noSiteUrl, companyHome);
|
||||
|
||||
// Check returns site doc lib if source is in site doc lib.
|
||||
String docLibUrl = makeUrl(docLibChild, DocLibNodeLocator.NAME);
|
||||
checkNodeLocator(docLibUrl, docLib);
|
||||
|
||||
// Check returns site doc lib if source is in other site container.
|
||||
String fooUrl = makeUrl(fooChild, DocLibNodeLocator.NAME);
|
||||
checkNodeLocator(fooUrl, docLib);
|
||||
}
|
||||
finally
|
||||
{
|
||||
nodeService.deleteNode(companyChild);
|
||||
if(site != null)
|
||||
{
|
||||
siteService.deleteSite(site.getShortName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testUserHomeNodeLocator() throws Exception
|
||||
{
|
||||
String url = baseURL + UserHomeNodeLocator.NAME;
|
||||
// Run as System User, no User Home.
|
||||
AuthenticationUtil.setRunAsUser(AuthenticationUtil.getSystemUserName());
|
||||
checkNodeLocator(url, null);
|
||||
|
||||
//Run as Admin User
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||
|
||||
NodeRef admin = repositoryHelper.getPerson();
|
||||
NodeRef userHome = repositoryHelper.getUserHome(admin);
|
||||
|
||||
checkNodeLocator(url, userHome);
|
||||
}
|
||||
|
||||
public void testAncestorOfTypeNodeLocator() throws Exception
|
||||
{
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||
NodeRef folder= makeChildFolderNode(companyHome);
|
||||
try
|
||||
{
|
||||
NodeRef sysFolder = makeChildSystemFolderNode(folder);
|
||||
NodeRef subFolder = makeChildFolderNode(sysFolder);
|
||||
NodeRef source = makeChildContentNode(subFolder);
|
||||
|
||||
// No params so should find first parent.
|
||||
String ancestorUrl = makeUrl(source, AncestorNodeLocator.NAME);
|
||||
checkNodeLocator(ancestorUrl, subFolder);
|
||||
|
||||
// Set type to cm:content. Should not match any node.
|
||||
String encodedContentType = URLEncoder.encode(ContentModel.TYPE_CONTENT.toPrefixString(namespaceService));
|
||||
String contentAncestorUrl = ancestorUrl + "?type=" + encodedContentType;
|
||||
checkNodeLocator(contentAncestorUrl, null);
|
||||
|
||||
// Set type to cm:systemfolder. Should find the sysFolder node.
|
||||
String encodedSysFolderType = URLEncoder.encode(ContentModel.TYPE_SYSTEM_FOLDER.toPrefixString(namespaceService));
|
||||
String sysFolderAncestorUrl = ancestorUrl + "?type=" + encodedSysFolderType;
|
||||
checkNodeLocator(sysFolderAncestorUrl, sysFolder);
|
||||
|
||||
// Set aspect to cm:ownable. Should not match any node.
|
||||
String encodedOwnableAspect= URLEncoder.encode(ContentModel.ASPECT_OWNABLE.toPrefixString(namespaceService));
|
||||
String ownableAncestorUrl = ancestorUrl + "?aspect=" + encodedOwnableAspect;
|
||||
checkNodeLocator(ownableAncestorUrl, null);
|
||||
|
||||
// Add ownable aspect to folder node. Now that node should be found.
|
||||
nodeService.addAspect(folder, ContentModel.ASPECT_OWNABLE, null);
|
||||
checkNodeLocator(ownableAncestorUrl, folder);
|
||||
|
||||
// Set aspect to cm:ownable and type to cm:systemfolder. Should not match any node.
|
||||
String ownableSysFolderAncestorUrl = sysFolderAncestorUrl + "&aspect=" + encodedOwnableAspect;
|
||||
checkNodeLocator(ownableSysFolderAncestorUrl, null);
|
||||
|
||||
// Set aspect to cm:ownable and type to cm:folder. Should find folder node.
|
||||
String encodedFOlderType = URLEncoder.encode(ContentModel.TYPE_FOLDER.toPrefixString(namespaceService));
|
||||
String ownableFolderAncestorUrl = ownableAncestorUrl + "&type=" + encodedFOlderType;
|
||||
checkNodeLocator(ownableFolderAncestorUrl, folder);
|
||||
}
|
||||
finally
|
||||
{
|
||||
nodeService.deleteNode(folder);
|
||||
}
|
||||
}
|
||||
|
||||
public void testXPathNodeLocator() throws Exception
|
||||
{
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||
NodeRef first = makeChildFolderNode(companyHome);
|
||||
try
|
||||
{
|
||||
NodeRef second = makeChildFolderNode(first);
|
||||
NodeRef content = makeChildContentNode(second);
|
||||
|
||||
// Check bad path returns null
|
||||
String badPath = URLEncoder.encode("cm:foo/cm:bar/cm:foobar");
|
||||
String badPathUrl = baseURL + XPathNodeLocator.NAME + "?query=" + badPath;
|
||||
checkNodeLocator(badPathUrl, null);
|
||||
|
||||
String path = nodeService.getPath(content).toPrefixString(namespaceService);
|
||||
String encodedPath = URLEncoder.encode(path);
|
||||
|
||||
// Check default store ref works.
|
||||
String defaultStoreUrl = baseURL + XPathNodeLocator.NAME + "?query=" +encodedPath;
|
||||
checkNodeLocator(defaultStoreUrl, content);
|
||||
|
||||
// Check specified store ref works.
|
||||
String storeIdUrl = defaultStoreUrl + "&store_type=workspace&store_id=SpacesStore";
|
||||
checkNodeLocator(storeIdUrl, content);
|
||||
|
||||
// Check node store ref works.
|
||||
String nodePathUrl = makeUrl(companyHome, XPathNodeLocator.NAME) + "?query=" + encodedPath;
|
||||
checkNodeLocator(nodePathUrl, content);
|
||||
}
|
||||
finally
|
||||
{
|
||||
nodeService.deleteNode(first);
|
||||
}
|
||||
}
|
||||
|
||||
private String makeUrl(NodeRef node, String locatorName)
|
||||
{
|
||||
StoreRef storeRef = node.getStoreRef();
|
||||
StringBuilder url = new StringBuilder("/api/");
|
||||
url.append(storeRef.getProtocol()).append("/")
|
||||
.append(storeRef.getIdentifier()).append("/")
|
||||
.append(node.getId()).append("/")
|
||||
.append("nodelocator").append("/")
|
||||
.append(locatorName);
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
private void checkNodeLocator(String url, NodeRef expNode) throws Exception
|
||||
{
|
||||
Response response = sendRequest(new GetRequest(url), 200);
|
||||
String jsonStr = response.getContentAsString();
|
||||
JSONObject json = new JSONObject(jsonStr);
|
||||
JSONObject result = json.getJSONObject("data");
|
||||
assertNotNull(result);
|
||||
String nodeRef = result.getString("nodeRef");
|
||||
String expResult = expNode == null ? "null" : expNode.toString();
|
||||
assertEquals(expResult, nodeRef);
|
||||
}
|
||||
|
||||
private NodeRef makeChildContentNode(NodeRef parent)
|
||||
{
|
||||
return makeChildNode(parent, ContentModel.TYPE_CONTENT);
|
||||
}
|
||||
|
||||
private NodeRef makeChildSystemFolderNode(NodeRef parent)
|
||||
{
|
||||
return makeChildNode(parent, ContentModel.TYPE_SYSTEM_FOLDER);
|
||||
}
|
||||
|
||||
private NodeRef makeChildFolderNode(NodeRef parent)
|
||||
{
|
||||
return makeChildNode(parent, ContentModel.TYPE_FOLDER);
|
||||
}
|
||||
|
||||
private NodeRef makeChildNode(NodeRef parent, QName type)
|
||||
{
|
||||
QName qName = QName.createQName("", GUID.generate());
|
||||
QName contains = ContentModel.ASSOC_CONTAINS;
|
||||
ChildAssociationRef result = nodeService.createNode(parent, contains, qName, type);
|
||||
return result.getChildRef();
|
||||
}
|
||||
|
||||
private NodeRef makeContainer(String siteName, String containerId)
|
||||
{
|
||||
QName type = ContentModel.TYPE_FOLDER;
|
||||
return siteService.createContainer(siteName, containerId, type, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
ApplicationContext appContext = getServer().getApplicationContext();
|
||||
this.siteService = (SiteServiceInternal) appContext.getBean("SiteService");
|
||||
this.nodeService = (NodeService) appContext.getBean("NodeService");
|
||||
this.namespaceService= (NamespaceService) appContext.getBean("NamespaceService");
|
||||
this.repositoryHelper = (Repository) appContext.getBean("repositoryHelper");
|
||||
this.companyHome = repositoryHelper.getCompanyHome();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user