1 17 package org.alfresco.repo.search.impl.lucene; 18 19 import java.util.ArrayList ; 20 import java.util.Collection ; 21 import java.util.Collections ; 22 import java.util.HashMap ; 23 import java.util.HashSet ; 24 import java.util.Iterator ; 25 import java.util.List ; 26 import java.util.Set ; 27 28 import org.alfresco.error.AlfrescoRuntimeException; 29 import org.alfresco.model.ContentModel; 30 import org.alfresco.repo.search.IndexerException; 31 import org.alfresco.service.cmr.dictionary.DictionaryService; 32 import org.alfresco.service.cmr.repository.ChildAssociationRef; 33 import org.alfresco.service.cmr.repository.NodeRef; 34 import org.alfresco.service.cmr.repository.NodeService; 35 import org.alfresco.service.cmr.repository.Path; 36 import org.alfresco.service.cmr.repository.StoreRef; 37 import org.alfresco.service.cmr.search.CategoryService; 38 import org.alfresco.service.cmr.search.ResultSet; 39 import org.alfresco.service.cmr.search.ResultSetRow; 40 import org.alfresco.service.namespace.NamespacePrefixResolver; 41 import org.alfresco.service.namespace.QName; 42 import org.alfresco.util.ISO9075; 43 import org.bouncycastle.crypto.paddings.ISO7816d4Padding; 44 45 public class LuceneCategoryServiceImpl implements CategoryService 46 { 47 private NodeService nodeService; 48 49 private NamespacePrefixResolver namespacePrefixResolver; 50 51 private DictionaryService dictionaryService; 52 53 private LuceneIndexerAndSearcher indexerAndSearcher; 54 55 public LuceneCategoryServiceImpl() 56 { 57 super(); 58 } 59 60 62 public void setNodeService(NodeService nodeService) 63 { 64 this.nodeService = nodeService; 65 } 66 67 public void setNamespacePrefixResolver(NamespacePrefixResolver namespacePrefixResolver) 68 { 69 this.namespacePrefixResolver = namespacePrefixResolver; 70 } 71 72 public void setDictionaryService(DictionaryService dictionaryService) 73 { 74 this.dictionaryService = dictionaryService; 75 } 76 77 public void setIndexerAndSearcher(LuceneIndexerAndSearcher indexerAndSearcher) 78 { 79 this.indexerAndSearcher = indexerAndSearcher; 80 } 81 82 public Collection <ChildAssociationRef> getChildren(NodeRef categoryRef, Mode mode, Depth depth) 83 { 84 if (categoryRef == null) 85 { 86 return Collections.<ChildAssociationRef> emptyList(); 87 } 88 ResultSet resultSet = null; 89 try 90 { 91 StringBuilder luceneQuery = new StringBuilder (64); 92 93 if (!mode.equals(Mode.ALL)) 94 { 95 luceneQuery.append(mode.equals(Mode.SUB_CATEGORIES) ? "-" : "").append("PATH_WITH_REPEATS:\""); 96 luceneQuery.append(buildXPath(nodeService.getPath(categoryRef))).append("/"); 97 if (depth.equals(Depth.ANY)) 98 { 99 luceneQuery.append("/"); 100 } 101 luceneQuery.append("member").append("\" "); 102 } 103 104 if (!mode.equals(Mode.MEMBERS)) 105 { 106 luceneQuery.append("PATH_WITH_REPEATS:\""); 107 luceneQuery.append(buildXPath(nodeService.getPath(categoryRef))).append("/"); 108 if (depth.equals(Depth.ANY)) 109 { 110 luceneQuery.append("/"); 111 } 112 luceneQuery.append("*").append("\" "); 113 } 114 115 resultSet = indexerAndSearcher.getSearcher(categoryRef.getStoreRef(), false).query(categoryRef.getStoreRef(), "lucene", luceneQuery.toString(), null, null); 116 117 return resultSetToChildAssocCollection(resultSet); 118 } 119 finally 120 { 121 if (resultSet != null) 122 { 123 resultSet.close(); 124 } 125 } 126 } 127 128 private String buildXPath(Path path) 129 { 130 StringBuilder pathBuffer = new StringBuilder (64); 131 for (Iterator <Path.Element> elit = path.iterator(); elit.hasNext(); ) 132 { 133 Path.Element element = elit.next(); 134 if (!(element instanceof Path.ChildAssocElement)) 135 { 136 throw new IndexerException("Confused path: " + path); 137 } 138 Path.ChildAssocElement cae = (Path.ChildAssocElement) element; 139 if (cae.getRef().getParentRef() != null) 140 { 141 pathBuffer.append("/"); 142 pathBuffer.append(getPrefix(cae.getRef().getQName().getNamespaceURI())); 143 pathBuffer.append(ISO9075.encode(cae.getRef().getQName().getLocalName())); 144 } 145 } 146 return pathBuffer.toString(); 147 } 148 149 HashMap <String , String > prefixLookup = new HashMap <String , String >(); 150 151 private String getPrefix(String uri) 152 { 153 String prefix = prefixLookup.get(uri); 154 if (prefix == null) 155 { 156 Collection <String > prefixes = namespacePrefixResolver.getPrefixes(uri); 157 for (String first : prefixes) 158 { 159 prefix = first; 160 break; 161 } 162 163 prefixLookup.put(uri, prefix); 164 } 165 if (prefix == null) 166 { 167 return ""; 168 } 169 else 170 { 171 return prefix + ":"; 172 } 173 174 } 175 176 private Collection <ChildAssociationRef> resultSetToChildAssocCollection(ResultSet resultSet) 177 { 178 List <ChildAssociationRef> collection = new ArrayList <ChildAssociationRef>(); 179 if (resultSet != null) 180 { 181 for (ResultSetRow row : resultSet) 182 { 183 ChildAssociationRef car = nodeService.getPrimaryParent(row.getNodeRef()); 184 collection.add(car); 185 } 186 } 187 return collection; 188 } 190 191 public Collection <ChildAssociationRef> getCategories(StoreRef storeRef, QName aspectQName, Depth depth) 192 { 193 Collection <ChildAssociationRef> assocs = new ArrayList <ChildAssociationRef>(); 194 Set <NodeRef> nodeRefs = getClassificationNodes(storeRef, aspectQName); 195 for (NodeRef nodeRef : nodeRefs) 196 { 197 assocs.addAll(getChildren(nodeRef, Mode.SUB_CATEGORIES, depth)); 198 } 199 return assocs; 200 } 201 202 private Set <NodeRef> getClassificationNodes(StoreRef storeRef, QName qname) 203 { 204 ResultSet resultSet = null; 205 try 206 { 207 resultSet = indexerAndSearcher.getSearcher(storeRef, false).query(storeRef, "lucene", "PATH_WITH_REPEATS:\"/" + getPrefix(qname.getNamespaceURI()) + ISO9075.encode(qname.getLocalName()) + "\"", 208 null, null); 209 210 Set <NodeRef> nodeRefs = new HashSet <NodeRef>(resultSet.length()); 211 for (ResultSetRow row : resultSet) 212 { 213 nodeRefs.add(row.getNodeRef()); 214 } 215 216 return nodeRefs; 217 } 218 finally 219 { 220 if (resultSet != null) 221 { 222 resultSet.close(); 223 } 224 } 225 } 226 227 public Collection <ChildAssociationRef> getClassifications(StoreRef storeRef) 228 { 229 ResultSet resultSet = null; 230 try 231 { 232 resultSet = indexerAndSearcher.getSearcher(storeRef, false).query(storeRef, "lucene", "PATH_WITH_REPEATS:\"//cm:categoryRoot/*\"", null, null); 233 return resultSetToChildAssocCollection(resultSet); 234 } 235 finally 236 { 237 if (resultSet != null) 238 { 239 resultSet.close(); 240 } 241 } 242 } 243 244 public Collection <QName> getClassificationAspects() 245 { 246 List <QName> list = new ArrayList <QName>(); 247 for (QName aspect : dictionaryService.getAllAspects()) 248 { 249 if (dictionaryService.isSubClass(aspect, ContentModel.ASPECT_CLASSIFIABLE)) 250 { 251 list.add(aspect); 252 } 253 } 254 return list; 255 } 256 257 public NodeRef createClassifiction(StoreRef storeRef, QName typeName, String attributeName) 258 { 259 throw new UnsupportedOperationException (); 260 } 261 262 public Collection <ChildAssociationRef> getRootCategories(StoreRef storeRef, QName aspectName) 263 { 264 Collection <ChildAssociationRef> assocs = new ArrayList <ChildAssociationRef>(); 265 Set <NodeRef> nodeRefs = getClassificationNodes(storeRef, aspectName); 266 for (NodeRef nodeRef : nodeRefs) 267 { 268 assocs.addAll(getChildren(nodeRef, Mode.SUB_CATEGORIES, Depth.IMMEDIATE)); 269 } 270 return assocs; 271 } 272 273 public NodeRef createCategory(NodeRef parent, String name) 274 { 275 if(!nodeService.exists(parent)) 276 { 277 throw new AlfrescoRuntimeException("Missing category?"); 278 } 279 String uri = nodeService.getPrimaryParent(parent).getQName().getNamespaceURI(); 280 String validLocalName = QName.createValidLocalName(name); 281 NodeRef newCategory = nodeService.createNode(parent, ContentModel.ASSOC_SUBCATEGORIES, QName.createQName(uri, validLocalName), ContentModel.TYPE_CATEGORY).getChildRef(); 282 nodeService.setProperty(newCategory, ContentModel.PROP_NAME, name); 283 return newCategory; 284 } 285 286 public NodeRef createRootCategory(StoreRef storeRef, QName aspectName, String name) 287 { 288 Set <NodeRef> nodeRefs = getClassificationNodes(storeRef, aspectName); 289 if(nodeRefs.size() == 0) 290 { 291 throw new AlfrescoRuntimeException("Missing classification: "+aspectName); 292 } 293 NodeRef parent = nodeRefs.iterator().next(); 294 return createCategory(parent, name); 295 } 296 297 public void deleteCategory(NodeRef nodeRef) 298 { 299 nodeService.deleteNode(nodeRef); 300 } 301 302 public void deleteClassification(StoreRef storeRef, QName aspectName) 303 { 304 throw new UnsupportedOperationException (); 305 } 306 307 308 309 310 311 } 312 | Popular Tags |