001
014
015 package com.liferay.portal.search;
016
017 import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
018 import com.liferay.portal.kernel.lar.StagingIndexingDeletionThreadLocal;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.search.Document;
022 import com.liferay.portal.kernel.search.DocumentImpl;
023 import com.liferay.portal.kernel.search.Indexable;
024 import com.liferay.portal.kernel.search.IndexableType;
025 import com.liferay.portal.kernel.search.Indexer;
026 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
027 import com.liferay.portal.model.BaseModel;
028 import com.liferay.portal.model.StagedModel;
029 import com.liferay.portal.service.ServiceContext;
030 import com.liferay.portal.spring.aop.AnnotationChainableMethodAdvice;
031 import com.liferay.portlet.documentlibrary.model.DLFileEntry;
032 import com.liferay.portlet.documentlibrary.util.DLFileEntryIndexer;
033
034 import java.lang.annotation.Annotation;
035 import java.lang.reflect.Method;
036
037 import org.aopalliance.intercept.MethodInvocation;
038
039
042 public class IndexableAdvice
043 extends AnnotationChainableMethodAdvice<Indexable> {
044
045 @Override
046 public void afterReturning(MethodInvocation methodInvocation, Object result)
047 throws Throwable {
048
049 if (result == null) {
050 return;
051 }
052
053 Indexable indexable = findAnnotation(methodInvocation);
054
055 if (indexable == _nullIndexable) {
056 return;
057 }
058
059 Method method = methodInvocation.getMethod();
060
061 Class<?> returnType = method.getReturnType();
062
063 if (!BaseModel.class.isAssignableFrom(returnType)) {
064 if (_log.isWarnEnabled()) {
065 _log.warn(
066 methodInvocation + " does not have a valid return type");
067 }
068
069 return;
070 }
071
072 Indexer indexer = null;
073
074 if (StagedModel.class.isAssignableFrom(returnType) &&
075 ExportImportThreadLocal.isImportInProcess()) {
076
077 if (indexable.type() == IndexableType.DELETE) {
078 try {
079 indexer = IndexerRegistryUtil.getIndexer(
080 returnType.getName());
081
082 String className = indexer.getClass().getName();
083
084 Document document = null;
085
086 if (className.equals(DLFileEntryIndexer.class.getName())) {
087 DLFileEntry dlFileEntry = (DLFileEntry)result;
088
089 document = new DocumentImpl();
090
091 document.addUID(
092 DLFileEntryIndexer.PORTLET_ID,
093 dlFileEntry.getFileEntryId());
094 }
095 else {
096 document = indexer.getDocument(result);
097 }
098
099 StagingIndexingDeletionThreadLocal.setDeletionKey(
100 className, document.getUID());
101 }
102 catch (Exception e) {
103 }
104 }
105
106 if (_log.isDebugEnabled()) {
107 _log.debug("Skipping indexing until the import is finished");
108 }
109
110 return;
111 }
112
113 if (indexer == null) {
114 indexer = IndexerRegistryUtil.getIndexer(returnType.getName());
115 }
116
117 if (indexer == null) {
118 serviceBeanAopCacheManager.removeMethodInterceptor(
119 methodInvocation, this);
120
121 return;
122 }
123
124 Object[] arguments = methodInvocation.getArguments();
125
126 for (int i = arguments.length - 1; i >= 0; i--) {
127 if (arguments[i] instanceof ServiceContext) {
128 ServiceContext serviceContext = (ServiceContext)arguments[i];
129
130 if (serviceContext.isIndexingEnabled()) {
131 break;
132 }
133
134 return;
135 }
136 }
137
138 if (indexable.type() == IndexableType.DELETE) {
139 indexer.delete(result);
140 }
141 else {
142 indexer.reindex(result);
143 }
144 }
145
146 @Override
147 public Indexable getNullAnnotation() {
148 return _nullIndexable;
149 }
150
151 private static Log _log = LogFactoryUtil.getLog(IndexableAdvice.class);
152
153 private static Indexable _nullIndexable =
154 new Indexable() {
155
156 @Override
157 public Class<? extends Annotation> annotationType() {
158 return Indexable.class;
159 }
160
161 @Override
162 public IndexableType type() {
163 return null;
164 }
165
166 };
167
168 }