mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-16 17:55:15 +00:00
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:
parent
c1bbebd7ec
commit
f13e6f19f2
@ -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" />
|
||||
|
||||
|
@ -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>
|
||||
|
53
config/alfresco/tagging-services-context.xml
Normal file
53
config/alfresco/tagging-services-context.xml
Normal 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>
|
@ -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");
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
|
133
source/java/org/alfresco/repo/tagging/TagDetailsImpl.java
Normal file
133
source/java/org/alfresco/repo/tagging/TagDetailsImpl.java
Normal 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;
|
||||
}
|
||||
}
|
139
source/java/org/alfresco/repo/tagging/TagScopeImpl.java
Normal file
139
source/java/org/alfresco/repo/tagging/TagScopeImpl.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
480
source/java/org/alfresco/repo/tagging/TaggingServiceImpl.java
Normal file
480
source/java/org/alfresco/repo/tagging/TaggingServiceImpl.java
Normal 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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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)));
|
||||
}
|
||||
|
||||
}
|
@ -24,8 +24,6 @@
|
||||
*/
|
||||
package org.alfresco.repo.thumbnail;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import org.alfresco.service.cmr.repository.TransformationOptions;
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
47
source/java/org/alfresco/service/cmr/tagging/TagDetails.java
Normal file
47
source/java/org/alfresco/service/cmr/tagging/TagDetails.java
Normal 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();
|
||||
}
|
49
source/java/org/alfresco/service/cmr/tagging/TagScope.java
Normal file
49
source/java/org/alfresco/service/cmr/tagging/TagScope.java
Normal 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);
|
||||
}
|
135
source/java/org/alfresco/service/cmr/tagging/TaggingService.java
Normal file
135
source/java/org/alfresco/service/cmr/tagging/TaggingService.java
Normal 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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user