001
014
015 package com.liferay.portlet.documentlibrary.util;
016
017 import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
018 import com.liferay.portal.kernel.dao.orm.DynamicQuery;
019 import com.liferay.portal.kernel.dao.orm.Property;
020 import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
021 import com.liferay.portal.kernel.exception.PortalException;
022 import com.liferay.portal.kernel.exception.SystemException;
023 import com.liferay.portal.kernel.log.Log;
024 import com.liferay.portal.kernel.log.LogFactoryUtil;
025 import com.liferay.portal.kernel.portlet.LiferayPortletURL;
026 import com.liferay.portal.kernel.portlet.LiferayWindowState;
027 import com.liferay.portal.kernel.search.BaseIndexer;
028 import com.liferay.portal.kernel.search.BooleanClauseOccur;
029 import com.liferay.portal.kernel.search.BooleanQuery;
030 import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
031 import com.liferay.portal.kernel.search.Document;
032 import com.liferay.portal.kernel.search.DocumentImpl;
033 import com.liferay.portal.kernel.search.Field;
034 import com.liferay.portal.kernel.search.SearchContext;
035 import com.liferay.portal.kernel.search.SearchEngineUtil;
036 import com.liferay.portal.kernel.search.SearchException;
037 import com.liferay.portal.kernel.search.Summary;
038 import com.liferay.portal.kernel.util.ArrayUtil;
039 import com.liferay.portal.kernel.util.GetterUtil;
040 import com.liferay.portal.kernel.util.PropsKeys;
041 import com.liferay.portal.kernel.util.StringPool;
042 import com.liferay.portal.kernel.util.Validator;
043 import com.liferay.portal.kernel.workflow.WorkflowConstants;
044 import com.liferay.portal.model.Group;
045 import com.liferay.portal.security.permission.ActionKeys;
046 import com.liferay.portal.security.permission.PermissionChecker;
047 import com.liferay.portal.service.GroupLocalServiceUtil;
048 import com.liferay.portal.service.persistence.GroupActionableDynamicQuery;
049 import com.liferay.portal.util.PortletKeys;
050 import com.liferay.portal.util.PrefsPropsUtil;
051 import com.liferay.portal.util.PropsValues;
052 import com.liferay.portlet.documentlibrary.asset.DLFileEntryAssetRendererFactory;
053 import com.liferay.portlet.documentlibrary.model.DLFileEntry;
054 import com.liferay.portlet.documentlibrary.model.DLFileEntryMetadata;
055 import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
056 import com.liferay.portlet.documentlibrary.model.DLFileVersion;
057 import com.liferay.portlet.documentlibrary.model.DLFolder;
058 import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
059 import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
060 import com.liferay.portlet.documentlibrary.service.DLFileEntryMetadataLocalServiceUtil;
061 import com.liferay.portlet.documentlibrary.service.DLFileEntryTypeLocalServiceUtil;
062 import com.liferay.portlet.documentlibrary.service.DLFolderServiceUtil;
063 import com.liferay.portlet.documentlibrary.service.permission.DLFileEntryPermission;
064 import com.liferay.portlet.documentlibrary.service.persistence.DLFileEntryActionableDynamicQuery;
065 import com.liferay.portlet.documentlibrary.service.persistence.DLFolderActionableDynamicQuery;
066 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
067 import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
068 import com.liferay.portlet.dynamicdatamapping.storage.Fields;
069 import com.liferay.portlet.dynamicdatamapping.storage.StorageEngineUtil;
070 import com.liferay.portlet.dynamicdatamapping.util.DDMIndexerUtil;
071 import com.liferay.portlet.expando.model.ExpandoBridge;
072 import com.liferay.portlet.expando.util.ExpandoBridgeFactoryUtil;
073 import com.liferay.portlet.expando.util.ExpandoBridgeIndexerUtil;
074
075 import java.io.IOException;
076 import java.io.InputStream;
077
078 import java.util.ArrayList;
079 import java.util.Collection;
080 import java.util.LinkedHashMap;
081 import java.util.List;
082 import java.util.Locale;
083 import java.util.Set;
084 import java.util.TreeSet;
085
086 import javax.portlet.PortletRequest;
087 import javax.portlet.PortletURL;
088 import javax.portlet.WindowStateException;
089
090
095 public class DLIndexer extends BaseIndexer {
096
097 public static final String[] CLASS_NAMES = {DLFileEntry.class.getName()};
098
099 public static final String PORTLET_ID = PortletKeys.DOCUMENT_LIBRARY;
100
101 public DLIndexer() {
102 setFilterSearch(true);
103 setPermissionAware(true);
104 }
105
106 public String[] getClassNames() {
107 return CLASS_NAMES;
108 }
109
110 public String getPortletId() {
111 return PORTLET_ID;
112 }
113
114 @Override
115 public boolean hasPermission(
116 PermissionChecker permissionChecker, String entryClassName,
117 long entryClassPK, String actionId)
118 throws Exception {
119
120 return DLFileEntryPermission.contains(
121 permissionChecker, entryClassPK, ActionKeys.VIEW);
122 }
123
124 @Override
125 public void postProcessContextQuery(
126 BooleanQuery contextQuery, SearchContext searchContext)
127 throws Exception {
128
129 int status = GetterUtil.getInteger(
130 searchContext.getAttribute(Field.STATUS),
131 WorkflowConstants.STATUS_APPROVED);
132
133 if (status != WorkflowConstants.STATUS_ANY) {
134 contextQuery.addRequiredTerm(Field.STATUS, status);
135 }
136
137 long[] folderIds = searchContext.getFolderIds();
138
139 if ((folderIds != null) && (folderIds.length > 0)) {
140 if (folderIds[0] == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
141 return;
142 }
143
144 BooleanQuery folderIdsQuery = BooleanQueryFactoryUtil.create(
145 searchContext);
146
147 for (long folderId : folderIds) {
148 try {
149 DLFolderServiceUtil.getFolder(folderId);
150 }
151 catch (Exception e) {
152 continue;
153 }
154
155 folderIdsQuery.addTerm(Field.FOLDER_ID, folderId);
156 }
157
158 contextQuery.add(folderIdsQuery, BooleanClauseOccur.MUST);
159 }
160 }
161
162 @Override
163 public void postProcessSearchQuery(
164 BooleanQuery searchQuery, SearchContext searchContext)
165 throws Exception {
166
167 Set<DDMStructure> ddmStructuresSet = new TreeSet<DDMStructure>();
168
169 long[] groupIds = searchContext.getGroupIds();
170
171 if ((groupIds != null) && (groupIds.length > 0)) {
172 List<DLFileEntryType> dlFileEntryTypes =
173 DLFileEntryTypeLocalServiceUtil.getFileEntryTypes(groupIds);
174
175 for (DLFileEntryType dlFileEntryType : dlFileEntryTypes) {
176 ddmStructuresSet.addAll(dlFileEntryType.getDDMStructures());
177 }
178 }
179
180 Group group = GroupLocalServiceUtil.getCompanyGroup(
181 searchContext.getCompanyId());
182
183 DDMStructure tikaRawMetadataStructure =
184 DDMStructureLocalServiceUtil.fetchStructure(
185 group.getGroupId(), "TikaRawMetadata");
186
187 if (tikaRawMetadataStructure != null) {
188 ddmStructuresSet.add(tikaRawMetadataStructure);
189 }
190
191 for (DDMStructure ddmStructure : ddmStructuresSet) {
192 addSearchDDMStruture(searchQuery, searchContext, ddmStructure);
193 }
194
195 String keywords = searchContext.getKeywords();
196
197 if (Validator.isNull(keywords)) {
198 addSearchTerm(searchQuery, searchContext, Field.DESCRIPTION, false);
199 addSearchTerm(searchQuery, searchContext, Field.TITLE, false);
200 addSearchTerm(searchQuery, searchContext, Field.USER_NAME, false);
201 }
202
203 addSearchTerm(searchQuery, searchContext, "extension", false);
204 addSearchTerm(searchQuery, searchContext, "fileEntryTypeId", false);
205 addSearchTerm(searchQuery, searchContext, "path", false);
206
207 LinkedHashMap<String, Object> params =
208 (LinkedHashMap<String, Object>)searchContext.getAttribute("params");
209
210 if (params != null) {
211 String expandoAttributes = (String)params.get("expandoAttributes");
212
213 if (Validator.isNotNull(expandoAttributes)) {
214 addSearchExpando(searchQuery, searchContext, expandoAttributes);
215 }
216 }
217 }
218
219 protected void addFileEntryTypeAttributes(
220 Document document, DLFileVersion dlFileVersion)
221 throws PortalException, SystemException {
222
223 List<DLFileEntryMetadata> dlFileEntryMetadatas =
224 DLFileEntryMetadataLocalServiceUtil.
225 getFileVersionFileEntryMetadatas(
226 dlFileVersion.getFileVersionId());
227
228 for (DLFileEntryMetadata dlFileEntryMetadata : dlFileEntryMetadatas) {
229 Fields fields = null;
230
231 try {
232 fields = StorageEngineUtil.getFields(
233 dlFileEntryMetadata.getDDMStorageId());
234 }
235 catch (Exception e) {
236 }
237
238 if (fields != null) {
239 DDMStructure ddmStructure =
240 DDMStructureLocalServiceUtil.getStructure(
241 dlFileEntryMetadata.getDDMStructureId());
242
243 DDMIndexerUtil.addAttributes(document, ddmStructure, fields);
244 }
245 }
246 }
247
248 @Override
249 protected void doDelete(Object obj) throws Exception {
250 DLFileEntry dlFileEntry = (DLFileEntry)obj;
251
252 Document document = new DocumentImpl();
253
254 document.addUID(PORTLET_ID, dlFileEntry.getFileEntryId());
255
256 SearchEngineUtil.deleteDocument(
257 getSearchEngineId(), dlFileEntry.getCompanyId(),
258 document.get(Field.UID));
259 }
260
261 @Override
262 protected Document doGetDocument(Object obj) throws Exception {
263 DLFileEntry dlFileEntry = (DLFileEntry)obj;
264
265 if (_log.isDebugEnabled()) {
266 _log.debug("Indexing document " + dlFileEntry);
267 }
268
269 boolean indexContent = true;
270
271 InputStream is = null;
272
273 try {
274 if (PropsValues.DL_FILE_INDEXING_MAX_SIZE == 0) {
275 indexContent = false;
276 }
277 else if (PropsValues.DL_FILE_INDEXING_MAX_SIZE != -1) {
278 if (dlFileEntry.getSize() >
279 PropsValues.DL_FILE_INDEXING_MAX_SIZE) {
280
281 indexContent = false;
282 }
283 }
284
285 if (indexContent) {
286 String[] ignoreExtensions = PrefsPropsUtil.getStringArray(
287 PropsKeys.DL_FILE_INDEXING_IGNORE_EXTENSIONS,
288 StringPool.COMMA);
289
290 if (ArrayUtil.contains(
291 ignoreExtensions,
292 StringPool.PERIOD + dlFileEntry.getExtension())) {
293
294 indexContent = false;
295 }
296 }
297
298 if (indexContent) {
299 is = dlFileEntry.getFileVersion().getContentStream(false);
300 }
301 }
302 catch (Exception e) {
303 }
304
305 if (indexContent && (is == null)) {
306 if (_log.isDebugEnabled()) {
307 _log.debug(
308 "Document " + dlFileEntry + " does not have any content");
309 }
310
311 return null;
312 }
313
314 DLFileVersion dlFileVersion = dlFileEntry.getFileVersion();
315
316 try {
317 Document document = getBaseModelDocument(
318 PORTLET_ID, dlFileEntry, dlFileVersion);
319
320 if (indexContent) {
321 try {
322 document.addFile(Field.CONTENT, is, dlFileEntry.getTitle());
323 }
324 catch (IOException ioe) {
325 throw new SearchException(
326 "Cannot extract text from file" + dlFileEntry);
327 }
328 }
329
330 document.addText(Field.DESCRIPTION, dlFileEntry.getDescription());
331 document.addKeyword(Field.FOLDER_ID, dlFileEntry.getFolderId());
332 document.addText(
333 Field.PROPERTIES, dlFileEntry.getLuceneProperties());
334 document.addText(Field.TITLE, dlFileEntry.getTitle());
335
336 document.addKeyword(
337 "dataRepositoryId", dlFileEntry.getDataRepositoryId());
338 document.addKeyword("extension", dlFileEntry.getExtension());
339 document.addKeyword(
340 "fileEntryTypeId", dlFileEntry.getFileEntryTypeId());
341 document.addKeyword("path", dlFileEntry.getTitle());
342
343 ExpandoBridge expandoBridge =
344 ExpandoBridgeFactoryUtil.getExpandoBridge(
345 dlFileEntry.getCompanyId(), DLFileEntry.class.getName(),
346 dlFileVersion.getFileVersionId());
347
348 ExpandoBridgeIndexerUtil.addAttributes(document, expandoBridge);
349
350 addFileEntryTypeAttributes(document, dlFileVersion);
351
352 if (!dlFileVersion.isInTrash() &&
353 dlFileVersion.isInTrashContainer()) {
354
355 DLFolder trashedFolder = dlFileVersion.getTrashContainer();
356
357 addTrashFields(
358 document, DLFolder.class.getName(),
359 trashedFolder.getFolderId(), null, null,
360 DLFileEntryAssetRendererFactory.TYPE);
361
362 document.addKeyword(
363 Field.ROOT_ENTRY_CLASS_NAME, DLFolder.class.getName());
364 document.addKeyword(
365 Field.ROOT_ENTRY_CLASS_PK, trashedFolder.getFolderId());
366 document.addKeyword(
367 Field.STATUS, WorkflowConstants.STATUS_IN_TRASH);
368 }
369
370 if (_log.isDebugEnabled()) {
371 _log.debug("Document " + dlFileEntry + " indexed successfully");
372 }
373
374 return document;
375 }
376 finally {
377 if (is != null) {
378 try {
379 is.close();
380 }
381 catch (IOException ioe) {
382 }
383 }
384 }
385 }
386
387 @Override
388 protected Summary doGetSummary(
389 Document document, Locale locale, String snippet,
390 PortletURL portletURL) {
391
392 LiferayPortletURL liferayPortletURL = (LiferayPortletURL)portletURL;
393
394 liferayPortletURL.setLifecycle(PortletRequest.ACTION_PHASE);
395
396 try {
397 liferayPortletURL.setWindowState(LiferayWindowState.EXCLUSIVE);
398 }
399 catch (WindowStateException wse) {
400 }
401
402 String fileEntryId = document.get(Field.ENTRY_CLASS_PK);
403
404 portletURL.setParameter("struts_action", "/document_library/get_file");
405 portletURL.setParameter("fileEntryId", fileEntryId);
406
407 Summary summary = createSummary(document, Field.TITLE, Field.CONTENT);
408
409 summary.setMaxContentLength(200);
410 summary.setPortletURL(portletURL);
411
412 return summary;
413 }
414
415 @Override
416 protected void doReindex(Object obj) throws Exception {
417 DLFileEntry dlFileEntry = (DLFileEntry)obj;
418
419 DLFileVersion dlFileVersion = dlFileEntry.getFileVersion();
420
421 if (!dlFileVersion.isApproved() && !dlFileVersion.isInTrash()) {
422 return;
423 }
424
425 Document document = getDocument(dlFileEntry);
426
427 if (document != null) {
428 SearchEngineUtil.updateDocument(
429 getSearchEngineId(), dlFileEntry.getCompanyId(), document);
430 }
431 }
432
433 @Override
434 protected void doReindex(String className, long classPK) throws Exception {
435 DLFileEntry dlFileEntry = DLFileEntryLocalServiceUtil.getFileEntry(
436 classPK);
437
438 doReindex(dlFileEntry);
439 }
440
441 @Override
442 protected void doReindex(String[] ids) throws Exception {
443 if (ids.length == 1) {
444 long companyId = GetterUtil.getLong(ids[0]);
445
446 reindexFolders(companyId);
447 reindexRoot(companyId);
448 }
449 else {
450 long companyId = GetterUtil.getLong(ids[0]);
451 long groupId = GetterUtil.getLong(ids[2]);
452 long dataRepositoryId = GetterUtil.getLong(ids[3]);
453
454 reindexFileEntries(companyId, groupId, dataRepositoryId);
455 }
456 }
457
458 @Override
459 protected String getPortletId(SearchContext searchContext) {
460 return PORTLET_ID;
461 }
462
463 protected void reindexFileEntries(
464 long companyId, final long groupId, final long dataRepositoryId)
465 throws PortalException, SystemException {
466
467 final Collection<Document> documents = new ArrayList<Document>();
468
469 ActionableDynamicQuery actionableDynamicQuery =
470 new DLFileEntryActionableDynamicQuery() {
471
472 @Override
473 protected void addCriteria(DynamicQuery dynamicQuery) {
474 Property property = PropertyFactoryUtil.forName("folderId");
475
476 long folderId = DLFolderConstants.getFolderId(
477 groupId, dataRepositoryId);
478
479 dynamicQuery.add(property.eq(folderId));
480 }
481
482 @Override
483 protected void performAction(Object object) throws PortalException {
484 DLFileEntry dlFileEntry = (DLFileEntry)object;
485
486 Document document = getDocument(dlFileEntry);
487
488 if (document != null) {
489 documents.add(document);
490 }
491 }
492
493 };
494
495 actionableDynamicQuery.setGroupId(groupId);
496
497 actionableDynamicQuery.performActions();
498
499 SearchEngineUtil.updateDocuments(
500 getSearchEngineId(), companyId, documents);
501 }
502
503 protected void reindexFolders(final long companyId)
504 throws PortalException, SystemException {
505
506 ActionableDynamicQuery actionableDynamicQuery =
507 new DLFolderActionableDynamicQuery() {
508
509 @Override
510 protected void performAction(Object object) throws PortalException {
511 DLFolder dlFolder = (DLFolder)object;
512
513 String portletId = PortletKeys.DOCUMENT_LIBRARY;
514 long groupId = dlFolder.getGroupId();
515 long folderId = dlFolder.getFolderId();
516
517 String[] newIds = {
518 String.valueOf(companyId), portletId,
519 String.valueOf(groupId), String.valueOf(folderId)
520 };
521
522 reindex(newIds);
523 }
524
525 };
526
527 actionableDynamicQuery.setCompanyId(companyId);
528
529 actionableDynamicQuery.performActions();
530 }
531
532 protected void reindexRoot(final long companyId)
533 throws PortalException, SystemException {
534
535 ActionableDynamicQuery actionableDynamicQuery =
536 new GroupActionableDynamicQuery() {
537
538 @Override
539 protected void performAction(Object object) throws PortalException {
540 Group group = (Group)object;
541
542 String portletId = PortletKeys.DOCUMENT_LIBRARY;
543 long groupId = group.getGroupId();
544 long folderId = groupId;
545
546 String[] newIds = {
547 String.valueOf(companyId), portletId,
548 String.valueOf(groupId), String.valueOf(folderId)
549 };
550
551 reindex(newIds);
552 }
553
554 };
555
556 actionableDynamicQuery.setCompanyId(companyId);
557
558 actionableDynamicQuery.performActions();
559 }
560
561 private static Log _log = LogFactoryUtil.getLog(DLIndexer.class);
562
563 }