Site Service CRUD API's (Java, JavaScript and REST), unit test methods added to JS API to help unit test JS API's

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8986 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Roy Wetherall
2008-05-01 16:48:30 +00:00
parent c5733ca5ae
commit 5194966123
8 changed files with 440 additions and 72 deletions

View File

@@ -59,6 +59,12 @@
</property> </property>
</bean> </bean>
<bean id="testScript" parent="baseJavaScriptExtension" class="org.alfresco.repo.jscript.ScriptTestUtils">
<property name="extensionName">
<value>test</value>
</property>
</bean>
<bean id="actionsScript" parent="baseJavaScriptExtension" class="org.alfresco.repo.jscript.Actions"> <bean id="actionsScript" parent="baseJavaScriptExtension" class="org.alfresco.repo.jscript.Actions">
<property name="extensionName"> <property name="extensionName">
<value>actions</value> <value>actions</value>

View File

@@ -0,0 +1,99 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.jscript;
import org.alfresco.error.AlfrescoRuntimeException;
/**
* @author Roy Wetherall
*/
public class ScriptTestUtils extends BaseScopableProcessorExtension
{
public void assertEquals(Object expected, Object value, String message)
{
if (expected.equals(value) == false)
{
if (message == null)
{
message = "Expected value '" + expected + "' was '" + value + "'";
}
throw new AlfrescoRuntimeException(message);
}
}
public void assertNotNull(Object value, String message)
{
if (value == null)
{
if (message == null)
{
message = "Unexpected null value encountered.";
}
throw new AlfrescoRuntimeException(message);
}
}
public void assertNull(Object value, String message)
{
if (value != null)
{
if (message == null)
{
message = "Unexpected non-null value encountered.";
}
throw new AlfrescoRuntimeException(message);
}
}
public void assertTrue(boolean value, String message)
{
if (value == false)
{
if (message == null)
{
message = "Value is not True";
}
throw new AlfrescoRuntimeException(message);
}
}
public void assertFalse(boolean value, String message)
{
if (value == true)
{
if (message == null)
{
message = "Value is not False";
}
throw new AlfrescoRuntimeException(message);
}
}
public void fail(String message)
{
throw new AlfrescoRuntimeException(message);
}
}

View File

@@ -33,4 +33,10 @@ public interface SiteService
*/ */
// TODO audit information // TODO audit information
List<SiteInfo> listSites(String nameFilter, String sitePresetFilter); List<SiteInfo> listSites(String nameFilter, String sitePresetFilter);
SiteInfo getSite(String shortName);
void updateSite(SiteInfo siteInfo);
void deleteSite(String shortName);
} }

View File

@@ -30,6 +30,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.avm.AVMRepository; import org.alfresco.repo.avm.AVMRepository;
import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationComponent;
@@ -47,6 +48,7 @@ import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.util.AbstractLifecycleBean; import org.alfresco.util.AbstractLifecycleBean;
import org.alfresco.util.ISO9075;
import org.alfresco.util.PropertyMap; import org.alfresco.util.PropertyMap;
import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEvent;
@@ -105,28 +107,10 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
public SiteInfo createSite(String sitePreset, String shortName, String title, String description, boolean isPublic) public SiteInfo createSite(String sitePreset, String shortName, String title, String description, boolean isPublic)
{ {
// TODO: /// TODO check for shortname duplicates
// 1. Check that the site preset exists
// 2. Check that the short name of the site isn't a duplicate
// 3. AVM create:
// 3a. Find the site preset AVM folder
// 3b. Create a new site folder in the correct location (named by the short name)
// 3c. Copy the contents of the site preset folder into the new site folder
// 3d. Mangle files as needed during copy ??
// 4. DM create:
// 4a. Find the site preset DM folder ??
// 4b. Create a new site in the correct location (named by short name)
// 4c. Set meta-data
// 4d. Set up memberships (copying from site preset DM folder??)
// 4e. Set up another details (rules) on site from DM preset folder ??
// 5. Return created site information
// 4. DM create .. create the DM object that represents the site
// Get the site parent node reference // Get the site parent node reference
NodeRef siteParent = getDMSiteParent(shortName); NodeRef siteParent = getSiteParent(shortName);
// Create the site node // Create the site node
PropertyMap properties = new PropertyMap(4); PropertyMap properties = new PropertyMap(4);
@@ -148,32 +132,32 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
this.permissionService.setPermission(siteNodeRef, PermissionService.ALL_AUTHORITIES, SITE_CONSUMER, true); this.permissionService.setPermission(siteNodeRef, PermissionService.ALL_AUTHORITIES, SITE_CONSUMER, true);
} }
// 5. Return created site information // Return created site information
SiteInfo siteInfo = new SiteInfo(sitePreset, shortName, title, description, isPublic); SiteInfo siteInfo = new SiteInfo(sitePreset, shortName, title, description, isPublic);
return siteInfo; return siteInfo;
} }
private NodeRef getDMSiteParent(String shortName) private NodeRef getSiteParent(String shortName)
{ {
// TODO // TODO
// For now just return the site root, later we may build folder structure based on the shortname to // For now just return the site root, later we may build folder structure based on the shortname to
// spread the sites about // spread the sites about
return getDMSiteRoot(); return getSiteRoot();
} }
private NodeRef getDMSiteRoot() private NodeRef getSiteRoot()
{ {
// Get the root 'sites' folder // Get the root 'sites' folder
ResultSet resultSet = this.searchService.query(SITE_DM_STORE, SearchService.LANGUAGE_LUCENE, "PATH:\"cm:sites\""); ResultSet resultSet = this.searchService.query(SITE_DM_STORE, SearchService.LANGUAGE_LUCENE, "PATH:\"cm:sites\"");
if (resultSet.length() == 0) if (resultSet.length() == 0)
{ {
// TODO // TODO
throw new RuntimeException("No root sites folder exists"); throw new AlfrescoRuntimeException("No root sites folder exists");
} }
else if (resultSet.length() != 1) else if (resultSet.length() != 1)
{ {
// TODO // TODO
throw new RuntimeException("More than one root sites folder exists"); throw new AlfrescoRuntimeException("More than one root sites folder exists");
} }
NodeRef sitesRoot = resultSet.getNodeRef(0); NodeRef sitesRoot = resultSet.getNodeRef(0);
@@ -188,12 +172,10 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
// TODO // TODO
// - take into consideration the filters set // - take into consideration the filters set
// - take into consideration that the sites may not just be in a flat list under the site root // - take into consideration that the sites may not just be in a flat list under the site root
// - should we be taking the list from the AVM store, since we can have an AVM site pointing to
// the default DM data site
// TODO // TODO
// For now just return the list of sites present under the site root // For now just return the list of sites present under the site root
NodeRef siteRoot = getDMSiteRoot(); NodeRef siteRoot = getSiteRoot();
List<ChildAssociationRef> assocs = this.nodeService.getChildAssocs(siteRoot, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); List<ChildAssociationRef> assocs = this.nodeService.getChildAssocs(siteRoot, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
List<SiteInfo> result = new ArrayList<SiteInfo>(assocs.size()); List<SiteInfo> result = new ArrayList<SiteInfo>(assocs.size());
for (ChildAssociationRef assoc : assocs) for (ChildAssociationRef assoc : assocs)
@@ -214,6 +196,15 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
String description = (String)properties.get(ContentModel.PROP_DESCRIPTION); String description = (String)properties.get(ContentModel.PROP_DESCRIPTION);
// Determine whether the space is public or not // Determine whether the space is public or not
boolean isPublic = isSitePublic(siteNodeRef);
// Create and return the site information
SiteInfo siteInfo = new SiteInfo(sitePreset, shortName, title, description, isPublic);
return siteInfo;
}
private boolean isSitePublic(NodeRef siteNodeRef)
{
boolean isPublic = false; boolean isPublic = false;
Set<AccessPermission> permissions = this.permissionService.getAllSetPermissions(siteNodeRef); Set<AccessPermission> permissions = this.permissionService.getAllSetPermissions(siteNodeRef);
for (AccessPermission permission : permissions) for (AccessPermission permission : permissions)
@@ -225,10 +216,84 @@ public class SiteServiceImpl extends AbstractLifecycleBean implements SiteServic
break; break;
} }
} }
return isPublic;
}
/**
* @see org.alfresco.repo.site.SiteService#getSite(java.lang.String)
*/
public SiteInfo getSite(String shortName)
{
SiteInfo result = null;
// Create and return the site information // Get the site node
SiteInfo siteInfo = new SiteInfo(sitePreset, shortName, title, description, isPublic); NodeRef siteNodeRef = getSiteNodeRef(shortName);
return siteInfo; if (siteNodeRef != null)
{
// Create the site info
result = createSiteInfo(siteNodeRef);
}
// Return the site information
return result;
}
private NodeRef getSiteNodeRef(String shortName)
{
NodeRef result = null;
ResultSet resultSet = this.searchService.query(SITE_DM_STORE, SearchService.LANGUAGE_LUCENE, "PATH:\"cm:sites/cm:" + ISO9075.encode(shortName) + "\"");
if (resultSet.length() == 1)
{
result = resultSet.getNodeRef(0);
}
return result;
}
public void updateSite(SiteInfo siteInfo)
{
NodeRef siteNodeRef = getSiteNodeRef(siteInfo.getShortName());
if (siteNodeRef == null)
{
throw new AlfrescoRuntimeException("Can not update site " + siteInfo.getShortName() + " because it does not exist.");
}
// Note: the site preset and short name can not be updated
// Update the properties of the site
Map<QName, Serializable> properties = this.nodeService.getProperties(siteNodeRef);
properties.put(ContentModel.PROP_TITLE, siteInfo.getTitle());
properties.put(ContentModel.PROP_DESCRIPTION, siteInfo.getDescription());
this.nodeService.setProperties(siteNodeRef, properties);
// Update the isPublic flag
boolean isPublic = isSitePublic(siteNodeRef);
if (isPublic != siteInfo.getIsPublic());
{
if (siteInfo.getIsPublic() == true)
{
// Add the permission
this.permissionService.setPermission(siteNodeRef, PermissionService.ALL_AUTHORITIES, SITE_CONSUMER, true);
}
else
{
// Remove the permission
this.permissionService.deletePermission(siteNodeRef, PermissionService.ALL_AUTHORITIES, SITE_CONSUMER);
}
}
}
/**
* @see org.alfresco.repo.site.SiteService#deleteSite(java.lang.String)
*/
public void deleteSite(String shortName)
{
NodeRef siteNodeRef = getSiteNodeRef(shortName);
if (siteNodeRef == null)
{
throw new AlfrescoRuntimeException("Can not delete site " + shortName + " because it does not exist.");
}
this.nodeService.deleteNode(siteNodeRef);
} }
/** /**

View File

@@ -27,6 +27,7 @@ package org.alfresco.repo.site;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.jscript.ClasspathScriptLocation; import org.alfresco.repo.jscript.ClasspathScriptLocation;
import org.alfresco.service.cmr.repository.ScriptLocation; import org.alfresco.service.cmr.repository.ScriptLocation;
import org.alfresco.service.cmr.repository.ScriptService; import org.alfresco.service.cmr.repository.ScriptService;
@@ -129,16 +130,78 @@ public class SiteServiceImplTest extends BaseAlfrescoSpringTest
} }
public void testGetSite()
{
// Get a site that isn't there
SiteInfo siteInfo = this.siteService.getSite("testGetSite");
assertNull(siteInfo);
// Create a test site
this.siteService.createSite(TEST_SITE_PRESET, "testGetSite", TEST_TITLE, TEST_DESCRIPTION, true);
// Get the test site
siteInfo = this.siteService.getSite("testGetSite");
assertNotNull(siteInfo);
checkSiteInfo(siteInfo, TEST_SITE_PRESET, "testGetSite", TEST_TITLE, TEST_DESCRIPTION, true);
}
public void testUpdateSite()
{
SiteInfo siteInfo = new SiteInfo(TEST_SITE_PRESET, "testUpdateSite", "changedTitle", "changedDescription", false);
// update a site that isn't there
try
{
this.siteService.updateSite(siteInfo);
fail("Shouldn't be able to update a site that does not exist");
}
catch (AlfrescoRuntimeException exception)
{
// Expected
}
// Create a test site
this.siteService.createSite(TEST_SITE_PRESET, "testUpdateSite", TEST_TITLE, TEST_DESCRIPTION, true);
// Update the details of the site
this.siteService.updateSite(siteInfo);
siteInfo = this.siteService.getSite("testUpdateSite");
checkSiteInfo(siteInfo, TEST_SITE_PRESET, "testUpdateSite", "changedTitle", "changedDescription", false);
// Update the permission again
siteInfo.setIsPublic(true);
this.siteService.updateSite(siteInfo);
checkSiteInfo(siteInfo, TEST_SITE_PRESET, "testUpdateSite", "changedTitle", "changedDescription", true);
}
public void testDeleteSite()
{
// delete a site that isn't there
try
{
this.siteService.deleteSite("testDeleteSite");
fail("Shouldn't be able to delete a site that does not exist");
}
catch (AlfrescoRuntimeException exception)
{
// Expected
}
// Create a test site
this.siteService.createSite(TEST_SITE_PRESET, "testUpdateSite", TEST_TITLE, TEST_DESCRIPTION, true);
assertNotNull(this.siteService.getSite("testUpdateSite"));
// Delete the site
this.siteService.deleteSite("testUpdateSite");
assertNull(this.siteService.getSite("testUpdateSite"));
}
// == Test the JavaScript API ==
public void testJSAPI() throws Exception public void testJSAPI() throws Exception
{ {
ScriptLocation location = new ClasspathScriptLocation("org/alfresco/repo/site/script/test_siteService.js"); ScriptLocation location = new ClasspathScriptLocation("org/alfresco/repo/site/script/test_siteService.js");
String result = (String)this.scriptService.executeScript(location, new HashMap<String, Object>(0)); this.scriptService.executeScript(location, new HashMap<String, Object>(0));
// Check the result and fail if message returned
if (result != null && result.length() != 0)
{
fail("The site service text JS script failed: " + result);
}
} }
} }

View File

@@ -67,7 +67,7 @@ public class ScriptSiteService extends BaseScopableProcessorExtension
public Site createSite(String sitePreset, String shortName, String title, String descripion, boolean isPublic) public Site createSite(String sitePreset, String shortName, String title, String descripion, boolean isPublic)
{ {
SiteInfo siteInfo = this.siteService.createSite(sitePreset, shortName, title, descripion, isPublic); SiteInfo siteInfo = this.siteService.createSite(sitePreset, shortName, title, descripion, isPublic);
return new Site(siteInfo); return new Site(this.siteService, siteInfo);
} }
/** /**
@@ -86,8 +86,27 @@ public class ScriptSiteService extends BaseScopableProcessorExtension
List<Site> sites = new ArrayList<Site>(siteInfos.size()); List<Site> sites = new ArrayList<Site>(siteInfos.size());
for (SiteInfo siteInfo : siteInfos) for (SiteInfo siteInfo : siteInfos)
{ {
sites.add(new Site(siteInfo)); sites.add(new Site(this.siteService, siteInfo));
} }
return sites; return sites;
} }
/**
* Get a site for a provided site short name.
* <p>
* Returns null if the site does not exist.
*
* @param shortName short name of the site
* @return Site the site, null if does not exist
*/
public Site getSite(String shortName)
{
Site site = null;
SiteInfo siteInfo = this.siteService.getSite(shortName);
if (siteInfo != null)
{
site = new Site(this.siteService, siteInfo);
}
return site;
}
} }

View File

@@ -27,6 +27,7 @@ package org.alfresco.repo.site.script;
import java.io.Serializable; import java.io.Serializable;
import org.alfresco.repo.site.SiteInfo; import org.alfresco.repo.site.SiteInfo;
import org.alfresco.repo.site.SiteService;
/** /**
* @author Roy Wetherall * @author Roy Wetherall
@@ -34,42 +35,133 @@ import org.alfresco.repo.site.SiteInfo;
public class Site implements Serializable public class Site implements Serializable
{ {
private static final long serialVersionUID = 8013569574120957923L; private static final long serialVersionUID = 8013569574120957923L;
/** Site information */
private SiteInfo siteInfo; private SiteInfo siteInfo;
public Site(SiteInfo siteInfo) /** Site service */
private SiteService siteService;
/** Indicates whether there are any outstanding changes that need to be saved */
private boolean isDirty = false;
/**
* Constructor
*
* @param siteInfo site information
*/
/*package*/ Site(SiteService siteService, SiteInfo siteInfo)
{ {
this.siteService = siteService;
this.siteInfo = siteInfo; this.siteInfo = siteInfo;
} }
/**
* Get the site preset
*
* @return String the site preset
*/
public String getSitePreset() public String getSitePreset()
{ {
return this.siteInfo.getSitePreset(); return this.siteInfo.getSitePreset();
} }
/**
* Set the short name
*
* @return String the short name
*/
public String getShortName() public String getShortName()
{ {
return this.siteInfo.getShortName(); return this.siteInfo.getShortName();
} }
/**
* Get the title
*
* @return String the site title
*/
public String getTitle() public String getTitle()
{ {
return this.siteInfo.getTitle(); return this.siteInfo.getTitle();
} }
// TODO set title /**
* Set the title
*
* @param title the title
*/
public void setTitle(String title)
{
this.isDirty = true;
this.siteInfo.setTitle(title);
}
/**
* Get the description
*
* @return String the description
*/
public String getDescription() public String getDescription()
{ {
return this.siteInfo.getDescription(); return this.siteInfo.getDescription();
} }
// TODO set description /**
* Set the description
*
* @param description the description
*/
public void setDescription(String description)
{
this.isDirty = true;
this.siteInfo.setDescription(description);
}
/**
* Gets whether the site is public or not
*
* @return true is public false otherwise
*/
public boolean getIsPublic() public boolean getIsPublic()
{ {
return this.siteInfo.getIsPublic(); return this.siteInfo.getIsPublic();
} }
// TODO set isPublic /**
* Set whether the site is public or not
*
* @param isPublic true the site is public false otherwise
*/
public void setIsPublic(boolean isPublic)
{
this.isDirty = true;
this.siteInfo.setIsPublic(isPublic);
}
/**
* Saves any outstanding updates to the site details.
* <p>
* If properties of the site are changed and save is not called, those changes will be lost.
*/
public void save()
{
if (this.isDirty == true)
{
// Update the site details
this.siteService.updateSite(this.siteInfo);
// Reset the dirty flag
this.isDirty = false;
}
}
/**
* Deletes the site
*/
public void deleteSite()
{
// Delete the site
this.siteService.deleteSite(this.siteInfo.getShortName());
}
} }

View File

@@ -1,29 +1,47 @@
var failure = ""; function checkSite(site, sitePreset, shortName, title, description, isPublic)
// Try and create a site
var site = siteService.createSite("sitePreset", "siteShortName", "siteTitle", "siteDescription", true);
// Check that the site details are correct
if (site.sitePreset != "sitePreset")
{ {
failure += "\nSite preset is not set on created site"; test.assertNotNull(site, "Site should not be null");
} test.assertEquals(sitePreset, site.sitePreset, "Site preset incorrect for site " + shortName);
if (site.shortName != "siteShortName") test.assertEquals(shortName, site.shortName, "Site shortname incorrect");
{ test.assertEquals(title, site.title, "Site title incorrect for site " + shortName);
failure += "\nSite short name is not set on created site"; test.assertEquals(description, site.description, "Site description incorrect for site " + shortName);
} test.assertEquals(isPublic, site.isPublic, "Site ispublic incorrect for site " + shortName);
if (site.title != "siteTitle")
{
failure += "\nSite title is not set on created site";
}
if (site.description != "siteDescription")
{
failure += "\nSite description is not set on created site";
}
if (site.isPublic != true)
{
failure += "\nCreated site should be marked public";
} }
// Return the failure message function testCRUD()
failure; {
// Try and get a site that doesn't exist
var site = siteService.getSite("siteShortName");
test.assertNull(site, "Site should not have been found.");
// Try and create a site
site = siteService.createSite("sitePreset", "siteShortName", "siteTitle", "siteDescription", true);
checkSite(site, "sitePreset", "siteShortName", "siteTitle", "siteDescription", true);
// Try and get the created site
site = siteService.getSite("siteShortName");
checkSite(site, "sitePreset", "siteShortName", "siteTitle", "siteDescription", true);
// Try and update the values of the site
site.title = "abc123abc";
site.description = "abc123abc";
site.isPublic = false;
checkSite(site, "sitePreset", "siteShortName", "abc123abc", "abc123abc", false);
site.save();
site = siteService.getSite("siteShortName");
checkSite(site, "sitePreset", "siteShortName", "abc123abc", "abc123abc", false);
// Delete the site
site.deleteSite();
site = siteService.getSite("siteShortName");
test.assertNull(site, "");
}
function testListSites()
{
// TODO
}
// Execute test's
testCRUD();
testListSites();