001/* 002 * Copyright 2012 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.web.repository.content.jcr; 017 018import java.util.Collections; 019import java.util.HashSet; 020import java.util.Set; 021 022import javax.jcr.Node; 023import javax.jcr.PathNotFoundException; 024import javax.jcr.RepositoryException; 025import javax.jcr.Value; 026import javax.jcr.ValueFactory; 027 028import org.ametys.plugins.repository.AmetysRepositoryException; 029import org.ametys.plugins.repository.RepositoryConstants; 030import org.ametys.plugins.repository.jcr.DefaultAmetysObject; 031import org.ametys.plugins.repository.jcr.JCRAmetysObject; 032 033/** 034 * Helper class which provides methods to manage tags on {@link JCRAmetysObject}s. 035 */ 036public final class TaggableAmetysObjectHelper 037{ 038 039 /** Constant for tags metadata. */ 040 public static final String METADATA_TAGS = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":tags"; 041 042 private TaggableAmetysObjectHelper() 043 { 044 // Hide the default constructor. 045 } 046 047 /** 048 * Tag a {@link JCRAmetysObject}. 049 * @param object the {@link JCRAmetysObject} to tag. 050 * @return the object tags. 051 * @throws AmetysRepositoryException if failed to tag Ametys object 052 */ 053 public static Set<String> getTags(JCRAmetysObject object) throws AmetysRepositoryException 054 { 055 try 056 { 057 Node node = getNode(object); 058 Value[] values = node.getProperty(METADATA_TAGS).getValues(); 059 Set<String> tags = new HashSet<>(values.length); 060 061 for (Value value : values) 062 { 063 tags.add(value.getString()); 064 } 065 066 return tags; 067 } 068 catch (PathNotFoundException e) 069 { 070 return Collections.emptySet(); 071 } 072 catch (RepositoryException e) 073 { 074 throw new AmetysRepositoryException("Unable to get tags property", e); 075 } 076 } 077 078 /** 079 * Tag a {@link JCRAmetysObject}. 080 * @param object the {@link JCRAmetysObject} to tag. 081 * @param tag the tag to put on the object. 082 * @throws AmetysRepositoryException if an error occurs. 083 */ 084 public static void tag(JCRAmetysObject object, String tag) throws AmetysRepositoryException 085 { 086 try 087 { 088 Node node = getNode(object); 089 Value[] values = new Value[0]; 090 091 if (node.hasProperty(METADATA_TAGS)) 092 { 093 values = node.getProperty(METADATA_TAGS).getValues(); 094 } 095 096 Set<String> tags = new HashSet<>(values.length + 1); 097 098 for (Value value : values) 099 { 100 tags.add(value.getString()); 101 } 102 103 if (tags.add(tag)) 104 { 105 ValueFactory valueFactory = node.getSession().getValueFactory(); 106 Set<Value> newValues = new HashSet<>(tags.size()); 107 108 for (String currentTag : tags) 109 { 110 newValues.add(valueFactory.createValue(currentTag)); 111 } 112 113 node.setProperty(METADATA_TAGS, newValues.toArray(new Value[newValues.size()])); 114 } 115 } 116 catch (RepositoryException e) 117 { 118 throw new AmetysRepositoryException("Unable to set tags property", e); 119 } 120 } 121 122 /** 123 * Tag a {@link JCRAmetysObject}. 124 * @param object the {@link JCRAmetysObject} to tag. 125 * @param tag the tag to remove on the object. 126 * @throws AmetysRepositoryException if an error occurs. 127 */ 128 public static void untag(JCRAmetysObject object, String tag) throws AmetysRepositoryException 129 { 130 try 131 { 132 Node node = getNode(object); 133 Value[] values = new Value[0]; 134 135 if (node.hasProperty(METADATA_TAGS)) 136 { 137 values = node.getProperty(METADATA_TAGS).getValues(); 138 } 139 140 Set<String> tags = new HashSet<>(values.length + 1); 141 142 for (Value value : values) 143 { 144 tags.add(value.getString()); 145 } 146 147 if (tags.remove(tag)) 148 { 149 ValueFactory valueFactory = node.getSession().getValueFactory(); 150 Set<Value> newValues = new HashSet<>(tags.size()); 151 152 for (String currentTag : tags) 153 { 154 newValues.add(valueFactory.createValue(currentTag)); 155 } 156 157 node.setProperty(METADATA_TAGS, newValues.toArray(new Value[newValues.size()])); 158 } 159 } 160 catch (RepositoryException e) 161 { 162 throw new AmetysRepositoryException("Unable to set tags property", e); 163 } 164 } 165 166 /** 167 * Get an object's base node. 168 * @param object the object which node to get. 169 * @return the object's base node. 170 */ 171 protected static Node getNode(JCRAmetysObject object) 172 { 173 Node node = null; 174 175 if (object instanceof DefaultAmetysObject) 176 { 177 node = ((DefaultAmetysObject) object).getBaseNode(); 178 } 179 else 180 { 181 node = object.getNode(); 182 } 183 184 return node; 185 } 186 187}