001/* 002 * (C) Copyright 2006-2010 Nuxeo SA (http://nuxeo.com/) and others. 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 * 016 * Contributors: 017 * Thierry Delprat 018 */ 019package org.nuxeo.apidoc.search; 020 021import java.util.ArrayList; 022import java.util.Arrays; 023import java.util.Collections; 024import java.util.HashMap; 025import java.util.List; 026import java.util.Map; 027 028import org.apache.commons.lang.text.StrBuilder; 029import org.nuxeo.apidoc.adapters.BaseNuxeoArtifactDocAdapter; 030import org.nuxeo.apidoc.adapters.BundleGroupDocAdapter; 031import org.nuxeo.apidoc.adapters.BundleInfoDocAdapter; 032import org.nuxeo.apidoc.adapters.ComponentInfoDocAdapter; 033import org.nuxeo.apidoc.adapters.ExtensionInfoDocAdapter; 034import org.nuxeo.apidoc.adapters.ExtensionPointInfoDocAdapter; 035import org.nuxeo.apidoc.adapters.ServiceInfoDocAdapter; 036import org.nuxeo.apidoc.api.BundleGroup; 037import org.nuxeo.apidoc.api.BundleInfo; 038import org.nuxeo.apidoc.api.ComponentInfo; 039import org.nuxeo.apidoc.api.DocumentationItem; 040import org.nuxeo.apidoc.api.ExtensionInfo; 041import org.nuxeo.apidoc.api.ExtensionPointInfo; 042import org.nuxeo.apidoc.api.NuxeoArtifact; 043import org.nuxeo.apidoc.api.QueryHelper; 044import org.nuxeo.apidoc.api.ServiceInfo; 045import org.nuxeo.apidoc.repository.RepositoryDistributionSnapshot; 046import org.nuxeo.apidoc.snapshot.DistributionSnapshot; 047import org.nuxeo.apidoc.snapshot.SnapshotManager; 048import org.nuxeo.ecm.core.api.CoreSession; 049import org.nuxeo.ecm.core.api.DocumentModel; 050import org.nuxeo.ecm.core.api.DocumentModelList; 051import org.nuxeo.ecm.core.query.sql.NXQL; 052import org.nuxeo.runtime.api.Framework; 053 054public class ArtifactSearcherImpl implements ArtifactSearcher { 055 056 protected NuxeoArtifact mapDoc2Artifact(DocumentModel doc) { 057 NuxeoArtifact artifact = null; 058 059 if (doc.getType().equals(BundleGroup.TYPE_NAME)) { 060 artifact = new BundleGroupDocAdapter(doc); 061 } else if (doc.getType().equals(BundleInfo.TYPE_NAME)) { 062 artifact = new BundleInfoDocAdapter(doc); 063 } else if (doc.getType().equals(ComponentInfo.TYPE_NAME)) { 064 artifact = new ComponentInfoDocAdapter(doc); 065 } else if (doc.getType().equals(ExtensionPointInfo.TYPE_NAME)) { 066 artifact = new ExtensionPointInfoDocAdapter(doc); 067 } else if (doc.getType().equals(ExtensionInfo.TYPE_NAME)) { 068 artifact = new ExtensionInfoDocAdapter(doc); 069 } else if (doc.getType().equals(DistributionSnapshot.TYPE_NAME)) { 070 artifact = new RepositoryDistributionSnapshot(doc); 071 } else if (doc.getType().equals(ServiceInfo.TYPE_NAME)) { 072 artifact = new ServiceInfoDocAdapter(doc); 073 } 074 075 return artifact; 076 } 077 078 @Override 079 public List<NuxeoArtifact> searchArtifact(CoreSession session, String fulltext) { 080 List<NuxeoArtifact> result = new ArrayList<NuxeoArtifact>(); 081 StrBuilder q = new StrBuilder("SELECT * FROM Document WHERE " + NXQL.ECM_PRIMARYTYPE + " IN ('"); 082 q.appendWithSeparators(Arrays.asList(BundleGroup.TYPE_NAME, BundleInfo.TYPE_NAME, ComponentInfo.TYPE_NAME, 083 ExtensionPointInfo.TYPE_NAME, ExtensionInfo.TYPE_NAME, DistributionSnapshot.TYPE_NAME, 084 ServiceInfo.TYPE_NAME), "', '"); 085 q.append("')"); 086 String query = q.toString(); 087 if (fulltext != null) { 088 query += " AND " + NXQL.ECM_FULLTEXT + " = " + NXQL.escapeString(fulltext); 089 } 090 DocumentModelList docs = session.query(query); 091 for (DocumentModel doc : docs) { 092 NuxeoArtifact artifact = mapDoc2Artifact(doc); 093 if (artifact != null) { 094 result.add(artifact); 095 } 096 } 097 return result; 098 } 099 100 @Override 101 public List<DocumentationItem> searchDocumentation(CoreSession session, String distribId, String fulltext, 102 String targetType) { 103 DistributionSnapshot snap = Framework.getLocalService(SnapshotManager.class).getSnapshot(distribId, session); 104 DocumentModel dist = ((RepositoryDistributionSnapshot) snap).getDoc(); 105 String query = QueryHelper.select(DocumentationItem.TYPE_NAME, dist, NXQL.ECM_FULLTEXT, fulltext); 106 if (targetType != null) { 107 query += " AND " + DocumentationItem.PROP_TARGET_TYPE + " = " + NXQL.escapeString(targetType); 108 } 109 DocumentModelList docs = session.query(query); 110 List<DocumentationItem> result = new ArrayList<DocumentationItem>(); 111 for (DocumentModel doc : docs) { 112 DocumentationItem docItem = doc.getAdapter(DocumentationItem.class); 113 if (docItem != null) { 114 result.add(docItem); 115 } 116 } 117 return result; 118 } 119 120 @Override 121 public List<NuxeoArtifact> filterArtifact(CoreSession session, String distribId, String type, String fulltext) { 122 List<NuxeoArtifact> result = new ArrayList<NuxeoArtifact>(); 123 124 List<NuxeoArtifact> matchingArtifacts = searchArtifact(session, fulltext); 125 List<DocumentationItem> matchingDocumentationItems = searchDocumentation(session, distribId, fulltext, null); 126 127 Map<String, ArtifactWithWeight> sortMap = new HashMap<String, ArtifactWithWeight>(); 128 129 for (NuxeoArtifact matchingArtifact : matchingArtifacts) { 130 NuxeoArtifact resultArtifact = resolveInTree(session, distribId, matchingArtifact, type); 131 if (resultArtifact != null) { 132 if (sortMap.containsKey(resultArtifact.getId())) { 133 sortMap.get(resultArtifact.getId()).addHit(); 134 } else { 135 sortMap.put(resultArtifact.getId(), new ArtifactWithWeight(resultArtifact)); 136 } 137 } 138 } 139 140 for (DocumentationItem matchingDocumentationItem : matchingDocumentationItems) { 141 NuxeoArtifact resultArtifact = resolveInTree(session, distribId, matchingDocumentationItem, type); 142 if (resultArtifact != null) { 143 if (sortMap.containsKey(resultArtifact.getId())) { 144 sortMap.get(resultArtifact.getId()).addHit(); 145 } else { 146 sortMap.put(resultArtifact.getId(), new ArtifactWithWeight(resultArtifact)); 147 } 148 } 149 } 150 151 List<ArtifactWithWeight> artifacts = new ArrayList<ArtifactWithWeight>(sortMap.values()); 152 Collections.sort(artifacts); 153 154 for (ArtifactWithWeight item : artifacts) { 155 result.add(item.getArtifact()); 156 } 157 return result; 158 } 159 160 protected NuxeoArtifact resolveInTree(CoreSession session, String distribId, NuxeoArtifact matchingArtifact, 161 String searchedType) { 162 String cType = matchingArtifact.getArtifactType(); 163 if (cType.equals(searchedType)) { 164 return matchingArtifact; 165 } 166 BaseNuxeoArtifactDocAdapter docAdapter = (BaseNuxeoArtifactDocAdapter) matchingArtifact; 167 DocumentModel doc = docAdapter.getDoc(); 168 List<DocumentModel> parents = session.getParentDocuments(doc.getRef()); 169 Collections.reverse(parents); 170 for (DocumentModel parent : parents) { 171 if (parent.getType().equals(searchedType)) { 172 return mapDoc2Artifact(parent); 173 } 174 } 175 return null; 176 } 177 178 protected NuxeoArtifact resolveInTree(CoreSession session, String distribId, 179 DocumentationItem matchingDocumentationItem, String searchedType) { 180 DistributionSnapshot snap = Framework.getLocalService(SnapshotManager.class).getSnapshot(distribId, session); 181 String targetId = matchingDocumentationItem.getTarget(); 182 String targetType = matchingDocumentationItem.getTargetType(); 183 NuxeoArtifact artifact; 184 if (targetType.equals(BundleGroup.TYPE_NAME)) { 185 artifact = snap.getBundleGroup(targetId); 186 } else if (targetType.equals(BundleInfo.TYPE_NAME)) { 187 artifact = snap.getBundle(targetId); 188 } else if (targetType.equals(ComponentInfo.TYPE_NAME)) { 189 artifact = snap.getComponent(targetId); 190 } else if (targetType.equals(ExtensionPointInfo.TYPE_NAME)) { 191 artifact = snap.getExtensionPoint(targetId); 192 } else if (targetType.equals(ExtensionInfo.TYPE_NAME)) { 193 artifact = snap.getContribution(targetId); 194 } else if (targetType.equals(ServiceInfo.TYPE_NAME)) { 195 artifact = snap.getService(targetId); 196 } else { 197 artifact = null; 198 } 199 return resolveInTree(session, distribId, artifact, searchedType); 200 } 201 202}