diff --git a/source/java/org/alfresco/repo/jscript/ScriptNode.java b/source/java/org/alfresco/repo/jscript/ScriptNode.java index 3f85abab64..a0a258e816 100644 --- a/source/java/org/alfresco/repo/jscript/ScriptNode.java +++ b/source/java/org/alfresco/repo/jscript/ScriptNode.java @@ -2023,6 +2023,72 @@ public class ScriptNode implements Serializable, Scopeable return (ScriptThumbnail[])result.toArray(new ScriptThumbnail[result.size()]); } + // ------------------------------------------------------------------------------ + // Tag methods + + /** + * Adds a tag to the node + * + * @param tag tag name + */ + public void addTag(String tag) + { + this.services.getTaggingService().addTag(this.nodeRef, tag); + } + + /** + * Removes a tag from the node + * + * @param tag tag name + */ + public void removeTag(String tag) + { + this.services.getTaggingService().removeTag(this.nodeRef, tag); + } + + /** + * Get all the tags applied to this node + * + * @return String[] array containing all the tag applied to this node + */ + public String[] getTags() + { + List tags = this.services.getTaggingService().getTags(this.nodeRef); + return (String[])tags.toArray(new String[tags.size()]); + } + + /** + * Sets whether this node is a tag scope or not + * + * @param value true if this node is a tag scope, false otherwise + */ + public void setIsTagScope(boolean value) + { + boolean currentValue = this.services.getTaggingService().isTagScope(this.nodeRef); + if (currentValue != value) + { + if (value == true) + { + // Add the tag scope + this.services.getTaggingService().addTagScope(this.nodeRef); + } + else + { + // Remove the tag scope + this.services.getTaggingService().removeTagScope(this.nodeRef); + } + } + } + + /** + * Gets whether this node is a tag scope + * + * @return boolean true if this node is a tag scope, false otherwise + */ + public boolean getIsTagScope() + { + return this.services.getTaggingService().isTagScope(this.nodeRef); + } // ------------------------------------------------------------------------------ // Helper methods diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneCategoryServiceImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneCategoryServiceImpl.java index b057c19c55..53e5ea6ee4 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneCategoryServiceImpl.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneCategoryServiceImpl.java @@ -413,7 +413,7 @@ public class LuceneCategoryServiceImpl implements CategoryService LuceneIndexerAndSearcher lias = (LuceneIndexerAndSearcher) indexerAndSearcher; String field = "@" + catProperty; - SearchService searchService = lias.getSearcher(storeRef, true); + SearchService searchService = lias.getSearcher(storeRef, false); if (searchService instanceof LuceneSearcher) { LuceneSearcher luceneSearcher = (LuceneSearcher)searchService; diff --git a/source/java/org/alfresco/repo/service/ServiceDescriptorRegistry.java b/source/java/org/alfresco/repo/service/ServiceDescriptorRegistry.java index d0fa44cfe0..4ee5ab0e70 100644 --- a/source/java/org/alfresco/repo/service/ServiceDescriptorRegistry.java +++ b/source/java/org/alfresco/repo/service/ServiceDescriptorRegistry.java @@ -57,6 +57,7 @@ import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PersonService; +import org.alfresco.service.cmr.tagging.TaggingService; import org.alfresco.service.cmr.thumbnail.ThumbnailService; import org.alfresco.service.cmr.version.VersionService; import org.alfresco.service.cmr.view.ExporterService; @@ -433,4 +434,12 @@ public class ServiceDescriptorRegistry { return (ThumbnailService)getService(THUMBNAIL_SERVICE); } + + /** + * @see org.alfresco.service.ServiceRegistry#getTaggingService() + */ + public TaggingService getTaggingService() + { + return (TaggingService)getService(TAGGING_SERVICE); + } } diff --git a/source/java/org/alfresco/repo/tagging/TaggingServiceImpl.java b/source/java/org/alfresco/repo/tagging/TaggingServiceImpl.java index 31df2c17e3..4bf4dbef19 100644 --- a/source/java/org/alfresco/repo/tagging/TaggingServiceImpl.java +++ b/source/java/org/alfresco/repo/tagging/TaggingServiceImpl.java @@ -152,6 +152,21 @@ public class TaggingServiceImpl implements TaggingService } } + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#deleteTag(org.alfresco.service.cmr.repository.StoreRef, java.lang.String) + */ + public void deleteTag(StoreRef storeRef, String tag) + { + // Lower the case of the tag + tag = tag.toLowerCase(); + + NodeRef tagNodeRef = getTagNodeRef(storeRef, tag); + if (tagNodeRef != null) + { + this.categoryService.deleteCategory(tagNodeRef); + } + } + /** * @see org.alfresco.service.cmr.tagging.TaggingService#getTags() */ @@ -167,6 +182,15 @@ public class TaggingServiceImpl implements TaggingService return result; } + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#getTags(org.alfresco.service.cmr.repository.StoreRef, java.lang.String) + */ + public List getTags(StoreRef storeRef, String filter) + { + // TODO + return null; + } + /** * @see org.alfresco.service.cmr.tagging.TaggingService#addTag(org.alfresco.service.cmr.repository.NodeRef, java.lang.String) */ @@ -298,6 +322,14 @@ public class TaggingServiceImpl implements TaggingService return result; } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#isTagScope(org.alfresco.service.cmr.repository.NodeRef) + */ + public boolean isTagScope(NodeRef nodeRef) + { + return this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE); + } /** * @see org.alfresco.service.cmr.tagging.TaggingService#addTagScope(org.alfresco.service.cmr.repository.NodeRef) @@ -421,26 +453,33 @@ public class TaggingServiceImpl implements TaggingService // Lower the case of the tag tag = tag.toLowerCase(); + // + // "+PATH:\"/cm:taggable/cm:" + ISOed(tag) + "/member\"" + // TODO return null; } /** - * @see org.alfresco.service.cmr.tagging.TaggingService#findTaggedNodes(java.lang.String, org.alfresco.service.cmr.tagging.TagScope) + * @see org.alfresco.service.cmr.tagging.TaggingService#findTaggedNodes(java.lang.String, org.alfresco.service.cmr.repository.NodeRef) */ - public List findTaggedNodes(String tag, TagScope tagScope) + public List findTaggedNodes(String tag, NodeRef nodeRef) { // Lower the case of the tag tag = tag.toLowerCase(); + // + // "+PATH:\"/cm:taggable/cm:" + ISOed(tag) + "/member\" +PATH:\"" + pathOfTheNode + "//*\"" + // TODO return null; } /** + * Helper method that takes an input stream and converts it into a list of tag details * - * @param is - * @return + * @param is input stream + * @return List list of tag details */ /*package*/ static List readTagDetails(InputStream is) { @@ -460,7 +499,6 @@ public class TaggingServiceImpl implements TaggingService } catch (IOException exception) { - throw new AlfrescoRuntimeException("Unable to read tag details", exception); } @@ -468,9 +506,10 @@ public class TaggingServiceImpl implements TaggingService } /** + * Helper method to convert a list of tag details into a string. * - * @param tagDetails - * @param os + * @param tagDetails list of tag details + * @return String string of tag details */ /*package*/ static String tagDetailsToString(List tagDetails) { diff --git a/source/java/org/alfresco/repo/tagging/TaggingServiceImplTest.java b/source/java/org/alfresco/repo/tagging/TaggingServiceImplTest.java index 70a6ccb827..2b4be109b0 100644 --- a/source/java/org/alfresco/repo/tagging/TaggingServiceImplTest.java +++ b/source/java/org/alfresco/repo/tagging/TaggingServiceImplTest.java @@ -32,11 +32,14 @@ import java.util.Map; import javax.transaction.UserTransaction; import org.alfresco.model.ContentModel; +import org.alfresco.repo.jscript.ClasspathScriptLocation; 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.ScriptLocation; +import org.alfresco.service.cmr.repository.ScriptService; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.tagging.TagDetails; @@ -56,6 +59,7 @@ public class TaggingServiceImplTest extends BaseAlfrescoSpringTest { /** Services */ private TaggingService taggingService; + private ScriptService scriptService; private static StoreRef storeRef; private static NodeRef rootNode; @@ -85,6 +89,7 @@ public class TaggingServiceImplTest extends BaseAlfrescoSpringTest this.authenticationService = (AuthenticationService) this.applicationContext.getBean("authenticationService"); this.actionService = (ActionService)this.applicationContext.getBean("actionService"); this.transactionService = (TransactionService)this.applicationContext.getBean("transactionComponent"); + this.scriptService = (ScriptService)this.applicationContext.getBean("scriptService"); if (init == false) { @@ -196,7 +201,28 @@ public class TaggingServiceImplTest extends BaseAlfrescoSpringTest assertTrue(this.taggingService.isTag(TaggingServiceImplTest.storeRef, TAG_1)); assertTrue(this.taggingService.isTag(TaggingServiceImplTest.storeRef, UPPER_TAG)); assertTrue(this.taggingService.isTag(TaggingServiceImplTest.storeRef, LOWER_TAG)); - tx.commit(); + + // Remove a tag + this.taggingService.deleteTag(TaggingServiceImplTest.storeRef, UPPER_TAG); + + tx.commit(); + 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)); + assertFalse(tags.contains(LOWER_TAG)); + + // Check isTag method + assertFalse(this.taggingService.isTag(TaggingServiceImplTest.storeRef, TAG_2)); + assertTrue(this.taggingService.isTag(TaggingServiceImplTest.storeRef, TAG_1)); + assertFalse(this.taggingService.isTag(TaggingServiceImplTest.storeRef, UPPER_TAG)); + assertFalse(this.taggingService.isTag(TaggingServiceImplTest.storeRef, LOWER_TAG)); + + tx.commit(); } public void testAddRemoveTag() @@ -233,6 +259,7 @@ public class TaggingServiceImplTest extends BaseAlfrescoSpringTest } public void testTagScopeFindAddRemove() + throws Exception { // Get scopes for node without TagScope tagScope = this.taggingService.findTagScope(this.subDocument); @@ -340,8 +367,7 @@ public class TaggingServiceImplTest extends BaseAlfrescoSpringTest assertEquals(2, ts1.getTags().size()); assertEquals(2, ts2.getTags().size()); - tx.commit(); - + tx.commit(); } private void addTag(NodeRef nodeRef, String tag, int tagCount, NodeRef tagScopeNodeRef) @@ -489,4 +515,18 @@ public class TaggingServiceImplTest extends BaseAlfrescoSpringTest } } } + + // == Test the JavaScript API == + + public void testJSAPI() throws Exception + { + Map model = new HashMap(0); + model.put("folder", this.folder); + model.put("subFolder", this.subFolder); + model.put("document", this.document); + model.put("subDocument", this.subDocument); + + ScriptLocation location = new ClasspathScriptLocation("org/alfresco/repo/tagging/script/test_taggingService.js"); + this.scriptService.executeScript(location, model); + } } diff --git a/source/java/org/alfresco/repo/tagging/script/test_taggingService.js b/source/java/org/alfresco/repo/tagging/script/test_taggingService.js new file mode 100644 index 0000000000..71e1270b19 --- /dev/null +++ b/source/java/org/alfresco/repo/tagging/script/test_taggingService.js @@ -0,0 +1,24 @@ +function testAddRemoveTag() +{ + var tags = document.tags; + test.assertNotNull(tags); + test.assertEquals(0, tags.length); + + document.addTag("mouse"); + document.addTag("snake"); + document.addTag("snail"); + + tags = document.tags; + test.assertNotNull(tags); + test.assertEquals(3, tags.length); + + document.removeTag("cat"); + document.removeTag("snake"); + + tags = document.tags; + test.assertNotNull(tags); + test.assertEquals(2, tags.length); +} + +// Execute test's +testAddRemoveTag(); \ No newline at end of file diff --git a/source/java/org/alfresco/service/ServiceRegistry.java b/source/java/org/alfresco/service/ServiceRegistry.java index f53232de21..02f5be1de6 100644 --- a/source/java/org/alfresco/service/ServiceRegistry.java +++ b/source/java/org/alfresco/service/ServiceRegistry.java @@ -56,6 +56,7 @@ import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PersonService; +import org.alfresco.service.cmr.tagging.TaggingService; import org.alfresco.service.cmr.thumbnail.ThumbnailService; import org.alfresco.service.cmr.version.VersionService; import org.alfresco.service.cmr.view.ExporterService; @@ -121,6 +122,7 @@ public interface ServiceRegistry static final QName AVM_LOCKING_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "AVMLockingService"); static final QName VIRT_SERVER_REGISTRY = QName.createQName(NamespaceService.ALFRESCO_URI, "VirtServerRegistry"); static final QName THUMBNAIL_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "ThumbnailService"); + static final QName TAGGING_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "TaggingService"); /** * Get the list of services provided by the Repository @@ -393,4 +395,11 @@ public interface ServiceRegistry */ @NotAuditable ThumbnailService getThumbnailService(); + + /** + * Get the Tagging Service + * @return + */ + @NotAuditable + TaggingService getTaggingService(); } diff --git a/source/java/org/alfresco/service/cmr/tagging/TaggingService.java b/source/java/org/alfresco/service/cmr/tagging/TaggingService.java index a2bd3b3046..463a7a8a7c 100644 --- a/source/java/org/alfresco/service/cmr/tagging/TaggingService.java +++ b/source/java/org/alfresco/service/cmr/tagging/TaggingService.java @@ -30,6 +30,8 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; /** + * Taggin Service Interface + * * @author Roy Wetherall */ public interface TaggingService @@ -37,49 +39,78 @@ public interface TaggingService /** * Indicates whether the tag already exists * - * @param tag - * @return + * @param storeRef store reference + * @param tag tag name + * @return boolean true if the tag exists, false otherwise */ boolean isTag(StoreRef storeRef, String tag); /** * Get all the tags currently available * - * @return + * @return List list of tags */ List getTags(StoreRef storeRef); + /** + * Get all the tags currently available that match the provided filter. + * + * @param storeRef store reference + * @param filter tag filter + * @return List list of tags + */ + List getTags(StoreRef storeRef, String filter); + /** * Create a new tag * - * @param tag + * @param storeRef store reference + * @param tag tag name */ void createTag(StoreRef storeRef, String tag); + /** + * Delete an existing tag + * + * @param storeRef store reference + * @param tag tag name + */ + void deleteTag(StoreRef storeRef, String tag); + /** * Add a tag to a node. Creating the tag if it does not already exist. * - * @param nodeRef - * @param tag + * @param nodeRef node reference + * @param tag tag name */ void addTag(NodeRef nodeRef, String tag); /** * Remove a tag from a node. * - * @param nodeRef - * @param tag + * @param nodeRef node reference + * @param tag tag name */ void removeTag(NodeRef nodeRef, String tag); /** * Get all the tags on a node * - * @param nodeRef - * @return + * @param nodeRef node reference + * @return List list of tags on the node */ List getTags(NodeRef nodeRef); + + + /** + * Indicates whether the node reference is a tag scope + * + * @param nodeRef node reference + * @return boolean true if node is a tag scope, false otherwise + */ + boolean isTagScope(NodeRef nodeRef); + /** * Adds a tag scope to the specified node * @@ -88,8 +119,11 @@ public interface TaggingService void addTagScope(NodeRef nodeRef); /** + * Removes a tag scope from a specified node. * - * @param nodeRef + * Note that any tag count information will be lost when the scope if removed. + * + * @param nodeRef node reference */ void removeTagScope(NodeRef nodeRef); @@ -107,9 +141,14 @@ public interface TaggingService TagScope findTagScope(NodeRef nodeRef); /** + * Finds all the tag scopes for the specified node. + *

+ * The resulting list of tag scopes is ordered with the 'nearest' at the bedining of the list. + *

+ * If no tag scopes are found an empty list is returned. * - * @param nodeRef - * @return + * @param nodeRef node reference + * @return List list of tag scopes */ List findAllTagScopes(NodeRef nodeRef); @@ -123,13 +162,13 @@ public interface TaggingService /** * Find all nodes that have been tagged with the specified tag and reside within - * the tag scope. + * the context of the node reference provided. * - * @param tag - * @param tagScope - * @return + * @param tag tag name + * @param nodeRef node providing context for the search + * @return List list of nodes tagged in the context specified, empty if none found */ - List findTaggedNodes(String tag, TagScope tagScope); + List findTaggedNodes(String tag, NodeRef nodeRef); }