Tagging Service: Initial implmentation of the tagging service, including tag scopes

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@9630 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Roy Wetherall 2008-07-02 15:53:41 +00:00
parent c1bbebd7ec
commit f13e6f19f2
16 changed files with 1786 additions and 10 deletions

View File

@ -45,6 +45,7 @@
<import resource="classpath:alfresco/preference-service-context.xml"/>
<import resource="classpath:alfresco/swf-transform-context.xml"/>
<import resource="classpath:alfresco/site-services-context.xml"/>
<import resource="classpath:alfresco/tagging-services-context.xml"/>
<import resource="classpath*:alfresco/patch/*-context.xml" />
<import resource="classpath*:alfresco/domain/*-context.xml" />

View File

@ -763,6 +763,17 @@
</properties>
</aspect>
<aspect name="cm:tagscope">
<title>Tag Scope</title>
<properties>
<property name="cm:tagScopeCache">
<title>Tags</title>
<type>d:content</type>
<protected>true</protected>
</property>
</properties>
</aspect>
<aspect name="cm:attachable">
<title>Attachable</title>
<associations>

View File

@ -0,0 +1,53 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<bean id="TaggingService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>org.alfresco.service.cmr.tagging.TaggingService</value>
</property>
<property name="target">
<ref bean="taggingService"/>
</property>
<property name="interceptorNames">
<list>
<idref local="TaggingService_transaction"/>
<idref bean="AuditMethodInterceptor"/>
<idref bean="exceptionTranslator"/>
<idref local="TaggingService_security"/>
</list>
</property>
</bean>
<bean id="TaggingService_transaction" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="*">${server.transaction.mode.default}</prop>
</props>
</property>
</bean>
<bean id="TaggingService_security" class="org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor" />
<bean id="taggingService" class="org.alfresco.repo.tagging.TaggingServiceImpl">
<property name="nodeService" ref="NodeService"/>
<property name="categoryService" ref="CategoryService"/>
<property name="searchService" ref="SearchService"/>
<property name="actionService" ref="ActionService"/>
<property name="contentService" ref="ContentService"/>
</bean>
<bean id="update-tagscope" class="org.alfresco.repo.tagging.UpdateTagScopesActionExecuter" parent="action-executer">
<property name="publicAction">
<value>false</value>
</property>
<property name="nodeService" ref="NodeService"/>
<property name="contentService" ref="ContentService"/>
<property name="taggingService" ref="TaggingService"/>
</bean>
</beans>

View File

@ -142,6 +142,10 @@ public interface ContentModel
static final QName ASPECT_TAGGABLE = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "taggable");
static final QName PROP_TAGS = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "taggable");
// tagscope aspect
static final QName ASPECT_TAGSCOPE = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "tagscope");
static final QName PROP_TAGSCOPE_CACHE = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "tagScopeCache");
// lock aspect
public final static QName ASPECT_LOCKABLE = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "lockable");
public final static QName PROP_LOCK_OWNER = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "lockOwner");

View File

@ -101,7 +101,7 @@ public class PreferenceServiceImplTest extends BaseAlfrescoSpringTest
prefs.put("atTheRoot", "thisIsAtTheRoot");
this.preferenceService.setPreferences(USER_ONE, prefs);
// assertEquals(USER_ONE, AuthenticationUtil.getCurrentUserName());
//assertEquals(USER_ONE, AuthenticationUtil.getCurrentUserName());
NodeRef personNodeRef = this.personService.getPerson(USER_ONE);
ContentReader reader = this.contentService.getReader(personNodeRef, ContentModel.PROP_PREFERENCE_VALUES);
@ -133,13 +133,13 @@ public class PreferenceServiceImplTest extends BaseAlfrescoSpringTest
assertNotNull(prefs);
assertEquals(0, prefs.size());
// assertEquals(USER_ONE, AuthenticationUtil.getCurrentUserName());
//assertEquals(USER_ONE, AuthenticationUtil.getCurrentUserName());
}
public void xtestBadUser()
{
//assertEquals(USER_ONE, authenticationComponent.getCurrentUserName());
assertEquals(USER_ONE, authenticationComponent.getCurrentUserName());
try
{

View File

@ -3,6 +3,7 @@ package org.alfresco.repo.site;
import java.util.List;
import java.util.Map;
import org.alfresco.service.Auditable;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
@ -25,7 +26,6 @@ public interface SiteService
* @param isPublic whether the site is public or not
* @return SiteInfo information about the created site
*/
// TODO ... audit information
SiteInfo createSite(String sitePreset, String shortName, String title, String description, boolean isPublic);
/**
@ -35,7 +35,6 @@ public interface SiteService
* @param sitePresetFilter site preset filter
* @return List<SiteInfo> list of site information
*/
// TODO audit information
List<SiteInfo> listSites(String nameFilter, String sitePresetFilter);
/**

View File

@ -0,0 +1,133 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.tagging;
import org.alfresco.service.cmr.tagging.TagDetails;
/**
* Contains the details of a tag within a specific tag scope.
*
* @author Roy Wetherall
*/
public class TagDetailsImpl implements TagDetails
{
/** Tag name */
private String tagName;
/** Tag count */
private int tagCount;
/**
* Constructor
*
* @param tagScope tag scope
* @param tagName tag name
* @param tagCount tag count
*/
/*package*/ TagDetailsImpl(String tagName, int tagCount)
{
this.tagName = tagName;
this.tagCount = tagCount;
}
/**
* @see org.alfresco.service.cmr.tagging.TagDetails#getTagName()
*/
public String getTagName()
{
return this.tagName;
}
/**
* @see org.alfresco.service.cmr.tagging.TagDetails#getTagCount()
*/
public int getTagCount()
{
return this.tagCount;
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
return this.tagName.hashCode();
}
/**
* Increment the tag count.
*/
/*protected*/ void incrementCount()
{
this.tagCount = this.tagCount + 1;
}
/**
* Decrement the tag count
*/
/*protected*/ void decrementCount()
{
this.tagCount = tagCount - 1;
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj instanceof TagDetailsImpl)
{
TagDetailsImpl that = (TagDetailsImpl) obj;
return (this.tagName.equals(that.tagName));
}
else
{
return false;
}
}
/**
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
public int compareTo(TagDetails o)
{
int result = 0;
if (this.tagCount < o.getTagCount())
{
result = 1;
}
else if (this.tagCount > o.getTagCount())
{
result = -1;
}
return result;
}
}

View File

@ -0,0 +1,139 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.tagging;
import java.util.List;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.tagging.TagDetails;
import org.alfresco.service.cmr.tagging.TagScope;
/**
* Tag Scope.
*
* Represents the roll up of tags within the scope of a node tree.
*
* @author Roy Wetherall
*/
public class TagScopeImpl implements TagScope
{
/** Node reference of node that has the tag scope aspect applied */
private NodeRef nodeRef;
/** Ordered list of tag details */
private List<TagDetails> tagDetails;
/**
* Constructor
*
* @param nodeRef node reference
*/
/*package*/ TagScopeImpl(NodeRef nodeRef, List<TagDetails> tagDetails)
{
this.nodeRef = nodeRef;
this.tagDetails = tagDetails;
}
/**
* Get the node reference of the tag scope
*
* @return node reference of the tag scope
*/
public NodeRef getNodeRef()
{
return this.nodeRef;
}
/**
* @see org.alfresco.service.cmr.tagging.TagScope#getTags()
*/
public List<TagDetails> getTags()
{
return this.tagDetails;
}
/**
* @see org.alfresco.service.cmr.tagging.TagScope#getTags(int)
*/
public List<TagDetails> getTags(int topN)
{
return this.tagDetails.subList(0, topN);
}
/**
* @see org.alfresco.service.cmr.tagging.TagScope#getTag(java.lang.String)
*/
public TagDetails getTag(String tag)
{
TagDetails result = null;
for (TagDetails tagDetails : this.tagDetails)
{
if (tagDetails.getTagName().equals(tag) == true)
{
result = tagDetails;
break;
}
}
return result;
}
/**
* @see org.alfresco.service.cmr.tagging.TagScope#isTagInScope(java.lang.String)
*/
public boolean isTagInScope(String tag)
{
return (getTag(tag) != null);
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
return this.nodeRef.hashCode();
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj instanceof TagScopeImpl)
{
TagScopeImpl that = (TagScopeImpl) obj;
return (this.nodeRef.equals(that.nodeRef));
}
else
{
return false;
}
}
}

View File

@ -0,0 +1,480 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.tagging;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
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.CategoryService;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.tagging.TagDetails;
import org.alfresco.service.cmr.tagging.TagScope;
import org.alfresco.service.cmr.tagging.TaggingService;
import org.alfresco.util.ISO9075;
/**
* Tagging service implementation
*
* @author Roy Wetherall
*/
public class TaggingServiceImpl implements TaggingService
{
/** Node service */
private NodeService nodeService;
/** Categorty Service */
private CategoryService categoryService;
/** Search Service */
private SearchService searchService;
/** Action Service */
private ActionService actionService;
/** Content Service */
private ContentService contentService;
/** Tag Details Delimiter */
private static final String TAG_DETAILS_DELIMITER = "|";
/**
* Set the cateogry service
*
* @param categoryService trhe category service
*/
public void setCategoryService(CategoryService categoryService)
{
this.categoryService = categoryService;
}
/**
* Set the node service
*
* @param nodeService the node service
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* Set the search service
*
* @param searchService the search service
*/
public void setSearchService(SearchService searchService)
{
this.searchService = searchService;
}
/**
* Set the action service
*
* @return ActionService action service
*/
public void setActionService(ActionService actionService)
{
this.actionService = actionService;
}
/**
* Set the content service
*
* @param contentService content service
*/
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
/**
* @see org.alfresco.service.cmr.tagging.TaggingService#isTag(java.lang.String)
*/
public boolean isTag(StoreRef storeRef, String tag)
{
return (getTagNodeRef(storeRef, tag) != null);
}
/**
* @see org.alfresco.service.cmr.tagging.TaggingService#createTag(java.lang.String)
*/
public void createTag(StoreRef storeRef, String tag)
{
if (isTag(storeRef, tag) == false)
{
this.categoryService.createRootCategory(storeRef, ContentModel.ASPECT_TAGGABLE, tag);
}
}
/**
* @see org.alfresco.service.cmr.tagging.TaggingService#getTags()
*/
public List<String> getTags(StoreRef storeRef)
{
Collection<ChildAssociationRef> rootCategories = this.categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE);
List<String> result = new ArrayList<String>(rootCategories.size());
for (ChildAssociationRef rootCategory : rootCategories)
{
String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), ContentModel.PROP_NAME);
result.add(name);
}
return result;
}
/**
* @see org.alfresco.service.cmr.tagging.TaggingService#addTag(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
*/
public void addTag(NodeRef nodeRef, String tag)
{
// Get the tag node reference
NodeRef newTagNodeRef = getTagNodeRef(nodeRef.getStoreRef(), tag);
if (newTagNodeRef == null)
{
// Create the new tag
newTagNodeRef = this.categoryService.createRootCategory(nodeRef.getStoreRef(), ContentModel.ASPECT_TAGGABLE, tag);
}
List<NodeRef> tagNodeRefs = new ArrayList(5);
if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGGABLE) == false)
{
// Add the aspect
this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_TAGGABLE, null);
}
else
{
// Get the current tags
List<NodeRef> currentTagNodes = (List<NodeRef>)this.nodeService.getProperty(nodeRef, ContentModel.PROP_TAGS);
if (currentTagNodes != null)
{
tagNodeRefs = currentTagNodes;
}
}
// Add the new tag (assuming it's not already been added
if (tagNodeRefs.contains(newTagNodeRef) == false)
{
tagNodeRefs.add(newTagNodeRef);
this.nodeService.setProperty(nodeRef, ContentModel.PROP_TAGS, (Serializable)tagNodeRefs);
updateTagScope(nodeRef, tag, true);
}
}
/**
* Gets the node reference for a given tag.
* <p>
* Returns null if tag is not present.
*
* @param storeRef store reference
* @param tag tag
* @return NodeRef tag node reference or null not exist
*/
private NodeRef getTagNodeRef(StoreRef storeRef, String tag)
{
NodeRef tagNodeRef = null;
String query = "+PATH:\"cm:taggable/cm:" + ISO9075.encode(tag) + "\"";
ResultSet resultSet = this.searchService.query(storeRef, SearchService.LANGUAGE_LUCENE, query);
if (resultSet.length() != 0)
{
tagNodeRef = resultSet.getNodeRef(0);
}
return tagNodeRef;
}
/**
* Update the relevant tag scopes when a tag is added or removed from a node.
*
* @param nodeRef node reference
* @param tag tag
* @param add if true then the tag is added, false if the tag is removed
*/
private void updateTagScope(NodeRef nodeRef, String tag, boolean add)
{
Action action = this.actionService.createAction(UpdateTagScopesActionExecuter.NAME);
action.setParameterValue(UpdateTagScopesActionExecuter.PARAM_TAG_NAME, tag);
action.setParameterValue(UpdateTagScopesActionExecuter.PARAM_ADD_TAG, add);
this.actionService.executeAction(action, nodeRef, false, true);
}
/**
* @see org.alfresco.service.cmr.tagging.TaggingService#removeTag(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
*/
public void removeTag(NodeRef nodeRef, String tag)
{
// Check for the taggable aspect
if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGGABLE) == true)
{
// Get the tag node reference
NodeRef newTagNodeRef = getTagNodeRef(nodeRef.getStoreRef(), tag);
if (newTagNodeRef != null)
{
// Get the current tags
List<NodeRef> currentTagNodes = (List<NodeRef>)this.nodeService.getProperty(nodeRef, ContentModel.PROP_TAGS);
if (currentTagNodes != null &&
currentTagNodes.size() != 0 &&
currentTagNodes.contains(newTagNodeRef) == true)
{
currentTagNodes.remove(newTagNodeRef);
this.nodeService.setProperty(nodeRef, ContentModel.PROP_TAGS, (Serializable)currentTagNodes);
updateTagScope(nodeRef, tag, false);
}
}
}
}
/**
* @see org.alfresco.service.cmr.tagging.TaggingService#getTags(org.alfresco.service.cmr.repository.NodeRef)
*/
public List<String> getTags(NodeRef nodeRef)
{
List<String> result = new ArrayList<String>(10);
// Check for the taggable aspect
if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGGABLE) == true)
{
// Get the current tags
List<NodeRef> currentTagNodes = (List<NodeRef>)this.nodeService.getProperty(nodeRef, ContentModel.PROP_TAGS);
if (currentTagNodes != null)
{
for (NodeRef currentTagNode : currentTagNodes)
{
String tag = (String)this.nodeService.getProperty(currentTagNode, ContentModel.PROP_NAME);
result.add(tag);
}
}
}
return result;
}
/**
* @see org.alfresco.service.cmr.tagging.TaggingService#addTagScope(org.alfresco.service.cmr.repository.NodeRef)
*/
public void addTagScope(NodeRef nodeRef)
{
if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE) == false)
{
this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE, null);
}
}
/**
* @see org.alfresco.service.cmr.tagging.TaggingService#removeTagScope(org.alfresco.service.cmr.repository.NodeRef)
*/
public void removeTagScope(NodeRef nodeRef)
{
if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE) == true)
{
this.nodeService.removeAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE);
}
}
/**
* @see org.alfresco.service.cmr.tagging.TaggingService#findTagScope(org.alfresco.service.cmr.repository.NodeRef)
*/
public TagScope findTagScope(NodeRef nodeRef)
{
TagScope tagScope = null;
if (this.nodeService.exists(nodeRef) == true)
{
List<NodeRef> tagScopeNodeRefs = new ArrayList<NodeRef>(3);
getTagScopes(nodeRef, tagScopeNodeRefs);
if (tagScopeNodeRefs.size() != 0)
{
tagScope = new TagScopeImpl(tagScopeNodeRefs.get(0), getTagDetails(tagScopeNodeRefs.get(0)));
}
}
return tagScope;
}
/**
* Gets the tag details list for a given tag scope node reference
*
* @param nodeRef tag scope node reference
* @return List<TagDetails> ordered list of tag details for the tag scope
*/
private List<TagDetails> getTagDetails(NodeRef nodeRef)
{
List<TagDetails> tagDetails = new ArrayList<TagDetails>(13);
ContentReader reader = this.contentService.getReader(nodeRef, ContentModel.PROP_TAGSCOPE_CACHE);
if (reader != null)
{
tagDetails = TaggingServiceImpl.readTagDetails(reader.getContentInputStream());
}
return tagDetails;
}
/**
* @see org.alfresco.service.cmr.tagging.TaggingService#findAllTagScopes(org.alfresco.service.cmr.repository.NodeRef)
*/
public List<TagScope> findAllTagScopes(NodeRef nodeRef)
{
List<TagScope> result = null;
if (this.nodeService.exists(nodeRef) == true)
{
List<NodeRef> tagScopeNodeRefs = new ArrayList<NodeRef>(3);
getTagScopes(nodeRef, tagScopeNodeRefs);
if (tagScopeNodeRefs.size() != 0)
{
result = new ArrayList<TagScope>(tagScopeNodeRefs.size());
for (NodeRef tagScopeNodeRef : tagScopeNodeRefs)
{
result.add(new TagScopeImpl(tagScopeNodeRef, getTagDetails(tagScopeNodeRef)));
}
}
else
{
result = Collections.emptyList();
}
}
return result;
}
/**
* Traverses up the node's primary parent placing all tag scope's in a list.
* <p>
* If none are found then the list is empty.
*
* @param nodeRef node reference
* @param tagScopes list of tag scopes
*/
private void getTagScopes(NodeRef nodeRef, List<NodeRef> tagScopes)
{
if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE) == true)
{
tagScopes.add(nodeRef);
}
ChildAssociationRef assoc = this.nodeService.getPrimaryParent(nodeRef);
if (assoc != null)
{
NodeRef parent = assoc.getParentRef();
if (parent != null)
{
getTagScopes(parent, tagScopes);
}
}
}
/**
* @see org.alfresco.service.cmr.tagging.TaggingService#findTaggedNodes(java.lang.String)
*/
public List<NodeRef> findTaggedNodes(String tag)
{
// TODO
return null;
}
/**
* @see org.alfresco.service.cmr.tagging.TaggingService#findTaggedNodes(java.lang.String, org.alfresco.service.cmr.tagging.TagScope)
*/
public List<NodeRef> findTaggedNodes(String tag, TagScope tagScope)
{
// TODO
return null;
}
/**
*
* @param is
* @return
*/
/*package*/ static List<TagDetails> readTagDetails(InputStream is)
{
List<TagDetails> result = new ArrayList<TagDetails>(25);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
try
{
String nextLine = reader.readLine();
while (nextLine != null)
{
String[] values = nextLine.split("\\" + TAG_DETAILS_DELIMITER);
result.add(new TagDetailsImpl(values[0], Integer.parseInt(values[1])));
nextLine = reader.readLine();
}
}
catch (IOException exception)
{
throw new AlfrescoRuntimeException("Unable to read tag details", exception);
}
return result;
}
/**
*
* @param tagDetails
* @param os
*/
/*package*/ static String tagDetailsToString(List<TagDetails> tagDetails)
{
StringBuffer result = new StringBuffer(255);
boolean bFirst = true;
for (TagDetails details : tagDetails)
{
if (bFirst == false)
{
result.append("\n");
}
else
{
bFirst = false;
}
result.append(details.getTagName());
result.append(TAG_DETAILS_DELIMITER);
result.append(details.getTagCount());
}
return result.toString();
}
}

View File

@ -0,0 +1,484 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.tagging;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.transaction.UserTransaction;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.repository.ContentService;
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.security.AuthenticationService;
import org.alfresco.service.cmr.tagging.TagDetails;
import org.alfresco.service.cmr.tagging.TagScope;
import org.alfresco.service.cmr.tagging.TaggingService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.BaseAlfrescoSpringTest;
/**
* Tagging service implementation unit test
*
* @author Roy Wetherall
*/
public class TaggingServiceImplTest extends BaseAlfrescoSpringTest
{
/** Services */
private TaggingService taggingService;
private static StoreRef storeRef;
private static NodeRef rootNode;
private NodeRef folder;
private NodeRef subFolder;
private NodeRef document;
private NodeRef subDocument;
private static final String TAG_1 = "tagOne";
private static final String TAG_2 = "tagTwo";
private static final String TAG_3 = "tagThree";
private static boolean init = false;
@Override
protected void onSetUpBeforeTransaction() throws Exception
{
super.onSetUpBeforeTransaction();
// Get services
this.taggingService = (TaggingService)this.applicationContext.getBean("TaggingService");
this.nodeService = (NodeService) this.applicationContext.getBean("nodeService");
this.contentService = (ContentService) this.applicationContext.getBean("contentService");
this.authenticationService = (AuthenticationService) this.applicationContext.getBean("authenticationService");
this.actionService = (ActionService)this.applicationContext.getBean("actionService");
this.transactionService = (TransactionService)this.applicationContext.getBean("transactionComponent");
if (init == false)
{
UserTransaction tx = this.transactionService.getUserTransaction();
tx.begin();
// Authenticate as the system user
AuthenticationComponent authenticationComponent = (AuthenticationComponent) this.applicationContext
.getBean("authenticationComponent");
authenticationComponent.setSystemUserAsCurrentUser();
// Create the store and get the root node
TaggingServiceImplTest.storeRef = this.nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis());
TaggingServiceImplTest.rootNode = this.nodeService.getRootNode(TaggingServiceImplTest.storeRef);
// Create the required tagging category
NodeRef catContainer = nodeService.createNode(TaggingServiceImplTest.rootNode, ContentModel.ASSOC_CHILDREN, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "categoryContainer"), ContentModel.TYPE_CONTAINER).getChildRef();
NodeRef catRoot = nodeService.createNode(
catContainer,
ContentModel.ASSOC_CHILDREN,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "categoryRoot"),
ContentModel.TYPE_CATEGORYROOT).getChildRef();
nodeService.createNode(
catRoot,
ContentModel.ASSOC_CATEGORIES,
ContentModel.ASPECT_TAGGABLE,
ContentModel.TYPE_CATEGORY).getChildRef();
init = true;
tx.commit();
}
}
@Override
protected void onSetUpInTransaction() throws Exception
{
// Authenticate as the system user
AuthenticationComponent authenticationComponent = (AuthenticationComponent) this.applicationContext
.getBean("authenticationComponent");
authenticationComponent.setSystemUserAsCurrentUser();
// Create a folder
Map<QName, Serializable> folderProps = new HashMap<QName, Serializable>(1);
folderProps.put(ContentModel.PROP_NAME, "testFolder");
folder = this.nodeService.createNode(
TaggingServiceImplTest.rootNode,
ContentModel.ASSOC_CHILDREN,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "testFolder"),
ContentModel.TYPE_FOLDER,
folderProps).getChildRef();
// Create a node
Map<QName, Serializable> docProps = new HashMap<QName, Serializable>(1);
docProps.put(ContentModel.PROP_NAME, "testDocument.txt");
document = this.nodeService.createNode(
folder,
ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "testDocument.txt"),
ContentModel.TYPE_CONTENT,
docProps).getChildRef();
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
props.put(ContentModel.PROP_NAME, "subFolder");
subFolder = this.nodeService.createNode(
folder,
ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "subFolder"),
ContentModel.TYPE_FOLDER,
props).getChildRef();
props = new HashMap<QName, Serializable>(1);
props.put(ContentModel.PROP_NAME, "subDocument.txt");
subDocument = this.nodeService.createNode(
subFolder,
ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "subDocument.txt"),
ContentModel.TYPE_CONTENT,
props).getChildRef();
}
public void testTagCRUD()
throws Exception
{
// Get the tags
List<String> tags = this.taggingService.getTags(TaggingServiceImplTest.storeRef);
assertNotNull(tags);
assertEquals(0, tags.size());
// Create a tag
this.taggingService.createTag(TaggingServiceImplTest.storeRef, TAG_1);
setComplete();
endTransaction();
UserTransaction tx = this.transactionService.getUserTransaction();
tx.begin();
// Get all the tags
tags = this.taggingService.getTags(TaggingServiceImplTest.storeRef);
assertNotNull(tags);
assertEquals(1, tags.size());
assertTrue(tags.contains(TAG_1));
// Check isTag method
assertFalse(this.taggingService.isTag(TaggingServiceImplTest.storeRef, TAG_2));
assertTrue(this.taggingService.isTag(TaggingServiceImplTest.storeRef, TAG_1));
tx.commit();
}
public void testAddRemoveTag()
throws Exception
{
List<String> tags = this.taggingService.getTags(this.document);
assertNotNull(tags);
assertTrue(tags.isEmpty());
assertTrue(this.taggingService.isTag(TaggingServiceImplTest.storeRef, TAG_1));
this.taggingService.addTag(this.document, TAG_1);
tags = this.taggingService.getTags(this.document);
assertNotNull(tags);
assertEquals(1, tags.size());
assertTrue(tags.contains(TAG_1));
assertFalse(this.taggingService.isTag(TaggingServiceImplTest.storeRef, TAG_2));
this.taggingService.addTag(this.document, TAG_2);
assertTrue(this.taggingService.isTag(TaggingServiceImplTest.storeRef, TAG_2));
tags = this.taggingService.getTags(this.document);
assertNotNull(tags);
assertEquals(2, tags.size());
assertTrue(tags.contains(TAG_1));
assertTrue(tags.contains(TAG_2));
this.taggingService.removeTag(this.document, TAG_1);
tags = this.taggingService.getTags(this.document);
assertNotNull(tags);
assertEquals(1, tags.size());
assertFalse(tags.contains(TAG_1));
assertTrue(tags.contains(TAG_2));
}
public void testTagScopeFindAddRemove()
{
// Get scopes for node without
TagScope tagScope = this.taggingService.findTagScope(this.subDocument);
assertNull(tagScope);
List<TagScope> tagScopes = this.taggingService.findAllTagScopes(this.subDocument);
assertNotNull(tagScopes);
assertEquals(0, tagScopes.size());
// Add scopes
// TODO should the add return the created scope ??
this.taggingService.addTagScope(this.folder);
this.taggingService.addTagScope(this.subFolder);
// Get the scopes
tagScope = this.taggingService.findTagScope(this.subDocument);
assertNotNull(tagScope);
tagScopes = this.taggingService.findAllTagScopes(this.subDocument);
assertNotNull(tagScopes);
assertEquals(2, tagScopes.size());
tagScope = this.taggingService.findTagScope(this.subFolder);
assertNotNull(tagScope);
tagScopes = this.taggingService.findAllTagScopes(this.subFolder);
assertNotNull(tagScopes);
assertEquals(2, tagScopes.size());
tagScope = this.taggingService.findTagScope(this.folder);
assertNotNull(tagScope);
tagScopes = this.taggingService.findAllTagScopes(this.folder);
assertNotNull(tagScopes);
assertEquals(1, tagScopes.size());
// Remove a scope
this.taggingService.removeTagScope(this.folder);
tagScope = this.taggingService.findTagScope(this.subDocument);
assertNotNull(tagScope);
tagScopes = this.taggingService.findAllTagScopes(this.subDocument);
assertNotNull(tagScopes);
assertEquals(1, tagScopes.size());
tagScope = this.taggingService.findTagScope(this.subFolder);
assertNotNull(tagScope);
tagScopes = this.taggingService.findAllTagScopes(this.subFolder);
assertNotNull(tagScopes);
assertEquals(1, tagScopes.size());
tagScope = this.taggingService.findTagScope(this.folder);
assertNull(tagScope);
tagScopes = this.taggingService.findAllTagScopes(this.folder);
assertNotNull(tagScopes);
assertEquals(0, tagScopes.size());
}
public void testTagScope()
throws Exception
{
// TODO add some tags before the scopes are added
// Add some tag scopes
this.taggingService.addTagScope(this.folder);
this.taggingService.addTagScope(this.subFolder);
// Get the tag scope
TagScope ts1 = this.taggingService.findTagScope(this.subDocument);
TagScope ts2 = this.taggingService.findTagScope(this.folder);
setComplete();
endTransaction();
addTag(this.subDocument, TAG_1, 1, ts1.getNodeRef());
addTag(this.subDocument, TAG_2, 1, ts1.getNodeRef());
addTag(this.subDocument, TAG_3, 1, ts1.getNodeRef());
addTag(this.subFolder, TAG_1, 2, ts1.getNodeRef());
addTag(this.subFolder, TAG_2, 2, ts1.getNodeRef());
addTag(this.folder, TAG_2, 3, ts2.getNodeRef());
UserTransaction tx = this.transactionService.getUserTransaction();
tx.begin();
// re get the tag scopes
ts1 = this.taggingService.findTagScope(this.subDocument);
ts2 = this.taggingService.findTagScope(this.folder);
// check the order and count of the tagscopes
assertEquals(2, ts1.getTags().get(0).getTagCount());
assertEquals(2, ts1.getTags().get(1).getTagCount());
assertEquals(1, ts1.getTags().get(2).getTagCount());
assertEquals(3, ts2.getTags().get(0).getTagCount());
assertEquals(TAG_2, ts2.getTags().get(0).getTagName());
assertEquals(2, ts2.getTags().get(1).getTagCount());
assertEquals(TAG_1, ts2.getTags().get(1).getTagName());
assertEquals(1, ts2.getTags().get(2).getTagCount());
assertEquals(TAG_3, ts2.getTags().get(2).getTagName());
tx.commit();
removeTag(this.folder, TAG_2, 2, ts2.getNodeRef());
removeTag(this.subFolder, TAG_2, 1, ts1.getNodeRef());
removeTag(this.subFolder, TAG_1, 1, ts1.getNodeRef());
removeTag(this.subDocument, TAG_1, 0, ts1.getNodeRef());
tx = this.transactionService.getUserTransaction();
tx.begin();
// re get the tag scopes
ts1 = this.taggingService.findTagScope(this.subDocument);
ts2 = this.taggingService.findTagScope(this.folder);
assertEquals(2, ts1.getTags().size());
assertEquals(2, ts2.getTags().size());
tx.commit();
}
private void addTag(NodeRef nodeRef, String tag, int tagCount, NodeRef tagScopeNodeRef)
throws Exception
{
UserTransaction tx = this.transactionService.getUserTransaction();
tx.begin();
// Add some tags
this.taggingService.addTag(nodeRef, tag);
tx.commit();
// Wait a bit cos we want the background threads to kick in and update the tag scope
int count = 0;
boolean bCreated = false;
while (true)
{
UserTransaction tx2 = this.transactionService.getUserTransaction();
tx2.begin();
try
{
// Get the tag scope
List<TagScope> tagScopes = this.taggingService.findAllTagScopes(nodeRef);
TagScope checkTagScope = null;
for (TagScope tagScope : tagScopes)
{
if (tagScope.getNodeRef().equals(tagScopeNodeRef) == true)
{
checkTagScope = tagScope;
break;
}
}
assertNotNull(checkTagScope);
// Check that tag scopes are in the correct order
List<TagDetails> tagDetailsList = checkTagScope.getTags();
for (TagDetails tagDetails : tagDetailsList)
{
if (tagDetails.getTagName().equals(tag) == true &&
tagDetails.getTagCount() == tagCount)
{
bCreated = true;
break;
}
}
if (bCreated == true)
{
break;
}
// Wait to give the threads a chance to execute
Thread.sleep(1000);
if (count == 10)
{
fail("The background task to update the tag scope failed");
}
count ++;
}
finally
{
tx2.commit();
}
}
}
private void removeTag(NodeRef nodeRef, String tag, int tagCount, NodeRef tagScopeNodeRef)
throws Exception
{
UserTransaction tx = this.transactionService.getUserTransaction();
tx.begin();
// Add some tags
this.taggingService.removeTag(nodeRef, tag);
tx.commit();
// Wait a bit cos we want the background threads to kick in and update the tag scope
int count = 0;
boolean bRemoved = false;
boolean bMissing = (tagCount == 0);
while (true)
{
UserTransaction tx2 = this.transactionService.getUserTransaction();
tx2.begin();
try
{
// Get the tag scope
List<TagScope> tagScopes = this.taggingService.findAllTagScopes(nodeRef);
TagScope checkTagScope = null;
for (TagScope tagScope : tagScopes)
{
if (tagScope.getNodeRef().equals(tagScopeNodeRef) == true)
{
checkTagScope = tagScope;
break;
}
}
assertNotNull(checkTagScope);
// Check that tag scopes are in the correct order
boolean bFound = false;
List<TagDetails> tagDetailsList = checkTagScope.getTags();
for (TagDetails tagDetails : tagDetailsList)
{
if (tagDetails.getTagName().equals(tag) == true )
{
if (tagDetails.getTagCount() == tagCount)
{
bRemoved = true;
}
bFound = true;
break;
}
}
if (bRemoved == true)
{
break;
}
else if (bMissing == true && bFound == false)
{
break;
}
// Wait to give the threads a chance to execute
Thread.sleep(1000);
if (count == 10)
{
fail("The background task to update the tag scope failed");
}
count ++;
}
finally
{
tx2.commit();
}
}
}
}

View File

@ -0,0 +1,194 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.tagging;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ParameterDefinitionImpl;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.tagging.TagDetails;
import org.alfresco.service.cmr.tagging.TagScope;
import org.alfresco.service.cmr.tagging.TaggingService;
/**
* Update tag scopes action executer.
*
* NOTE: This action is used to facilitate the async update of tag scopes. It is not intended for genereral useage.
*
* @author Roy Wetherall
*/
public class UpdateTagScopesActionExecuter extends ActionExecuterAbstractBase
{
/** Node Service */
private NodeService nodeService;
/** Content Service */
private ContentService contentService;
/** Tagging Service */
private TaggingService taggingService;
/** Action name and parameters */
public static final String NAME = "update-tagscope";
public static final String PARAM_TAG_NAME = "tag_name";
public static final String PARAM_ADD_TAG = "add_tag";
/**
* Set the node service
*
* @param nodeService node service
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* Set the content service
*
* @param contentService the content service
*/
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
/**
* Set the tagging service
*
* @param taggingService the tagging service
*/
public void setTaggingService(TaggingService taggingService)
{
this.taggingService = taggingService;
}
/**
* @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
{
if (this.nodeService.exists(actionedUponNodeRef) == true)
{
// Get the parameter values
String tagName = (String)action.getParameterValue(PARAM_TAG_NAME);
Boolean isAdd = (Boolean)action.getParameterValue(PARAM_ADD_TAG);
// Get the tag scopes for the actioned upon node
List<TagScope> tagScopes = this.taggingService.findAllTagScopes(actionedUponNodeRef);
// Update each tag scope
for (TagScope tagScope : tagScopes)
{
NodeRef tagScopeNodeRef = tagScope.getNodeRef();
List<TagDetails> tags = null;
// Get the current tags
ContentReader contentReader = this.contentService.getReader(tagScopeNodeRef, ContentModel.PROP_TAGSCOPE_CACHE);
if (contentReader == null)
{
tags = new ArrayList<TagDetails>(1);
}
else
{
tags = TaggingServiceImpl.readTagDetails(contentReader.getContentInputStream());
}
TagDetails currentTag = null;
for (TagDetails tag : tags)
{
if (tag.getTagName().equals(tagName) == true)
{
currentTag = tag;
break;
}
}
if (isAdd == true)
{
if (currentTag == null)
{
tags.add(new TagDetailsImpl(tagName, 1));
}
else
{
((TagDetailsImpl)currentTag).incrementCount();
}
}
else
{
if (currentTag != null)
{
int currentTagCount = currentTag.getTagCount();
if (currentTagCount == 1)
{
tags.remove(currentTag);
}
else
{
((TagDetailsImpl)currentTag).decrementCount();
}
}
}
// Order the list
Collections.sort(tags);
// Write new content back to tag scope
String tagContent = TaggingServiceImpl.tagDetailsToString(tags);
ContentWriter contentWriter = this.contentService.getWriter(tagScopeNodeRef, ContentModel.PROP_TAGSCOPE_CACHE, true);
contentWriter.setEncoding("UTF-8");
contentWriter.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
contentWriter.putContent(tagContent);
}
}
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
@Override
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_TAG_NAME, DataTypeDefinition.TEXT, true, getParamDisplayLabel(PARAM_TAG_NAME)));
paramList.add(new ParameterDefinitionImpl(PARAM_ADD_TAG, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_ADD_TAG)));
}
}

View File

@ -24,8 +24,6 @@
*/
package org.alfresco.repo.thumbnail;
import java.lang.reflect.Constructor;
import org.alfresco.service.cmr.repository.TransformationOptions;
/**

View File

@ -27,19 +27,68 @@ package org.alfresco.service.cmr.preference;
import java.io.Serializable;
import java.util.Map;
import org.alfresco.service.Auditable;
/**
* @author Roy Wetherall
*/
public interface PreferenceService
{
/**
* Get all preferences for a particular user
*
* @param userName the user name
* @return Map<String, Serializable> a map containing the preference values, empty if none
*/
@Auditable(key = Auditable.Key.ARG_0, parameters = {"userName"})
Map<String, Serializable> getPreferences(String userName);
/**
* Get the preferences for a particular user.
* <p>
* If no filter if provided all preferences are returned.
* <p>
* If a filter is provided it's used to filter the results. For example the filter
* "alfresco.myComp" will only return filters that are in the "namespace" alfresco.myComp.
*
* @param userName the user name
* @param preferenceFilter the preference filter
* @return Map<String, Serializable> a map containing the preference values, empty if none
*/
@Auditable(key = Auditable.Key.ARG_0, parameters = {"userName", "preferenceFilter"})
Map<String, Serializable> getPreferences(String userName, String preferenceFilter);
/**
* Sets the preference values for a user.
* <p>
* Values provided overlay those already present.
* <p>
* Preference value names can be "namespaced" by using package notation. For example
* "alfresc.myComp.myValue".
*
* @param userName the user name
* @param preferences the preference values
*/
@Auditable(key = Auditable.Key.ARG_0, parameters = {"userName", "preferences"})
void setPreferences(String userName, Map<String, Serializable> preferences);
/**
* Clears all the preferences for a particular user.
*
* @param userName the user name
*/
@Auditable(key = Auditable.Key.ARG_0, parameters = {"userName"})
void clearPreferences(String userName);
/**
* Clears the preferences for a particular user that match the filter optionally provided.
* <p>
* If no filter if present then all preferences are cleared.
*
* @param userName the user name
* @param preferenceFilter the preference filter
*/
@Auditable(key = Auditable.Key.ARG_0, parameters = {"userName", "preferenceFilter"})
void clearPreferences(String userName, String preferenceFilter);
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.service.cmr.tagging;
/**
* Tag details interface.
*
* @author Roy Wetherall
*/
public interface TagDetails extends Comparable<TagDetails>
{
/**
* Get the name of the tag
*
* @return String tag name
*/
String getTagName();
/**
* Get the tag count
*
* @return int tag count
*/
int getTagCount();
}

View File

@ -0,0 +1,49 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.service.cmr.tagging;
import java.util.List;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* Tag Scope Inteface.
*
* Represents the roll up of tags within the scope of a node tree.
*
* @author Roy Wetherall
*/
public interface TagScope
{
NodeRef getNodeRef();
List<TagDetails> getTags();
List<TagDetails> getTags(int topN);
TagDetails getTag(String tag);
boolean isTagInScope(String tag);
}

View File

@ -0,0 +1,135 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.service.cmr.tagging;
import java.util.List;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
/**
* @author Roy Wetherall
*/
public interface TaggingService
{
/**
* Indicates whether the tag already exists
*
* @param tag
* @return
*/
boolean isTag(StoreRef storeRef, String tag);
/**
* Get all the tags currently available
*
* @return
*/
List<String> getTags(StoreRef storeRef);
/**
* Create a new tag
*
* @param tag
*/
void createTag(StoreRef storeRef, String tag);
/**
* Add a tag to a node. Creating the tag if it does not already exist.
*
* @param nodeRef
* @param tag
*/
void addTag(NodeRef nodeRef, String tag);
/**
* Remove a tag from a node.
*
* @param nodeRef
* @param tag
*/
void removeTag(NodeRef nodeRef, String tag);
/**
* Get all the tags on a node
*
* @param nodeRef
* @return
*/
List<String> getTags(NodeRef nodeRef);
/**
* Adds a tag scope to the specified node
*
* @param nodeRef node reference
*/
void addTagScope(NodeRef nodeRef);
/**
*
* @param nodeRef
*/
void removeTagScope(NodeRef nodeRef);
/**
* Finds the 'nearest' tag scope for the specified node.
* <p>
* The 'nearest' tag scope is discovered by walking up the primary parent path
* untill a tag scope is found or the root node is reached.
* <p>
* If no tag scope if found then a null value is returned.
*
* @param nodeRef node reference
* @return the 'nearest' tag scope or null if none found
*/
TagScope findTagScope(NodeRef nodeRef);
/**
*
* @param nodeRef
* @return
*/
List<TagScope> findAllTagScopes(NodeRef nodeRef);
/**
* Find all nodes that have been tagged with the specified tag.
*
* @param tag tag name
* @return List<NodeRef> list of nodes tagged with specified tag, empty of none found
*/
List<NodeRef> findTaggedNodes(String tag);
/**
* Find all nodes that have been tagged with the specified tag and reside within
* the tag scope.
*
* @param tag
* @param tagScope
* @return
*/
List<NodeRef> findTaggedNodes(String tag, TagScope tagScope);
}