001
014
015 package com.liferay.portal.lar.backgroundtask;
016
017 import com.liferay.portal.kernel.backgroundtask.BackgroundTaskResult;
018 import com.liferay.portal.kernel.backgroundtask.BaseBackgroundTaskExecutor;
019 import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
020 import com.liferay.portal.kernel.dao.orm.DynamicQuery;
021 import com.liferay.portal.kernel.dao.orm.Property;
022 import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
023 import com.liferay.portal.kernel.exception.PortalException;
024 import com.liferay.portal.kernel.exception.SystemException;
025 import com.liferay.portal.kernel.lar.PortletDataContext;
026 import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
027 import com.liferay.portal.kernel.log.Log;
028 import com.liferay.portal.kernel.log.LogFactoryUtil;
029 import com.liferay.portal.kernel.search.Indexer;
030 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
031 import com.liferay.portal.kernel.search.SearchException;
032 import com.liferay.portal.kernel.util.ArrayUtil;
033 import com.liferay.portal.kernel.util.GetterUtil;
034 import com.liferay.portal.kernel.util.MapUtil;
035 import com.liferay.portal.kernel.util.ReflectionUtil;
036 import com.liferay.portal.kernel.util.StringBundler;
037 import com.liferay.portal.kernel.util.StringPool;
038 import com.liferay.portal.model.BackgroundTask;
039 import com.liferay.portal.model.User;
040 import com.liferay.portlet.documentlibrary.model.DLFileEntry;
041 import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
042 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
043 import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
044 import com.liferay.portlet.journal.model.JournalArticle;
045 import com.liferay.portlet.journal.service.persistence.JournalArticleActionableDynamicQuery;
046 import com.liferay.portlet.journal.util.JournalArticleIndexer;
047
048 import java.io.Serializable;
049
050 import java.lang.reflect.Method;
051
052 import java.util.ArrayList;
053 import java.util.HashSet;
054 import java.util.List;
055 import java.util.Map;
056 import java.util.Set;
057
058
061 public class StagingIndexingBackgroundTaskExecutor
062 extends BaseBackgroundTaskExecutor {
063
064 public StagingIndexingBackgroundTaskExecutor() {
065 setSerial(true);
066 }
067
068 @Override
069 public BackgroundTaskResult execute(BackgroundTask backgroundTask)
070 throws Exception {
071
072 Map<String, Serializable> taskContextMap =
073 backgroundTask.getTaskContextMap();
074
075 PortletDataContext portletDataContext =
076 (PortletDataContext)taskContextMap.get("portletDataContext");
077
078 try {
079 deleteDocuments(portletDataContext);
080 }
081 catch (Exception e) {
082 _log.error("Unable to delete documents", e);
083 }
084
085 boolean importPermissions = MapUtil.getBoolean(
086 portletDataContext.getParameterMap(),
087 PortletDataHandlerKeys.PERMISSIONS);
088
089 if (importPermissions) {
090 long userId = MapUtil.getLong(taskContextMap, "userId");
091
092 if (userId > 0) {
093 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
094 User.class);
095
096 indexer.reindex(userId);
097 }
098 }
099
100 Map<String, Map<?, ?>> newPrimaryKeysMaps =
101 portletDataContext.getNewPrimaryKeysMaps();
102
103 for (Map.Entry<String, Map<?, ?>> newPrimaryKeysMapsEntry :
104 newPrimaryKeysMaps.entrySet()) {
105
106 String className = newPrimaryKeysMapsEntry.getKey();
107
108 Indexer indexer = IndexerRegistryUtil.getIndexer(className);
109
110 if ((indexer == null) &&
111 !className.equals(DDMStructure.class.getName())) {
112
113 continue;
114 }
115
116 Map<?, ?> newPrimaryKeysMap = newPrimaryKeysMapsEntry.getValue();
117
118 List<Long> newPrimaryKeys = new ArrayList<Long>();
119
120 for (Object object : newPrimaryKeysMap.values()) {
121 long classPK = GetterUtil.getLong(object);
122
123 if (classPK > 0) {
124 newPrimaryKeys.add(classPK);
125 }
126 }
127
128 if (className.equals(DDMStructure.class.getName())) {
129 reindexDDMStructures(
130 newPrimaryKeys, newPrimaryKeysMaps,
131 portletDataContext.getGroupId());
132 }
133 else {
134 for (Long classPK : newPrimaryKeys) {
135 indexer.reindex(className, classPK);
136 }
137 }
138 }
139
140 return BackgroundTaskResult.SUCCESS;
141 }
142
143 protected void deleteDocuments(PortletDataContext portletDataContext) {
144 Map<String, List<String>> deletionKeysMap =
145 portletDataContext.getDeletionKeysMap();
146
147 for (String className : deletionKeysMap.keySet()) {
148 Indexer indexer = IndexerRegistryUtil.getIndexer(className);
149
150 List<String> uids = deletionKeysMap.get(className);
151
152 for (String uid : uids) {
153 try {
154 indexer.delete(portletDataContext.getCompanyId(), uid);
155 }
156 catch (SearchException se) {
157 _log.error("Unable to delete document with UID " + uid, se);
158 }
159 }
160 }
161 }
162
163 protected ActionableDynamicQuery getJournalArticleActionableDynamicQuery(
164 long groupId, final Map<?, ?> journalArticleIds,
165 final String[] ddmStructureKeys)
166 throws Exception {
167
168 ActionableDynamicQuery journalArticleActionableDynamicQuery =
169 new JournalArticleActionableDynamicQuery() {
170
171 @Override
172 protected void addCriteria(DynamicQuery dynamicQuery) {
173 Property structureIdProperty = PropertyFactoryUtil.forName(
174 "structureId");
175
176 dynamicQuery.add(structureIdProperty.in(ddmStructureKeys));
177 }
178
179 @Override
180 protected void performAction(Object object) throws PortalException {
181 JournalArticle article = (JournalArticle)object;
182
183 if (containsValue(
184 journalArticleIds, article.getResourcePrimKey())) {
185
186 return;
187 }
188
189 try {
190 _journalArticleIndexer.doReindex(article, false);
191 }
192 catch (Exception e) {
193 throw new PortalException(e);
194 }
195 }
196
197 private final JournalArticleIndexer _journalArticleIndexer =
198 (JournalArticleIndexer)IndexerRegistryUtil.getIndexer(
199 JournalArticle.class);
200
201 };
202
203 journalArticleActionableDynamicQuery.setGroupId(groupId);
204
205 return journalArticleActionableDynamicQuery;
206 }
207
208 protected void reindexDDMStructures(
209 List<Long> ddmStructureIds,
210 final Map<String, Map<?, ?>> newPrimaryKeysMaps, long groupId)
211 throws Exception {
212
213 if ((ddmStructureIds == null) || ddmStructureIds.isEmpty()) {
214 return;
215 }
216
217 Set<Long> descendantDDMStructureIds = new HashSet<Long>();
218
219 for (long structureId : ddmStructureIds) {
220 DDMStructure ddmStructure =
221 DDMStructureLocalServiceUtil.getDDMStructure(structureId);
222
223 descendantDDMStructureIds.addAll(
224 getDescendantDDMStructureIds(
225 ddmStructure.getGroupId(), ddmStructure.getStructureId()));
226 }
227
228 int i = 0;
229
230 String[] ddmStructureKeys =
231 new String[descendantDDMStructureIds.size()];
232
233 for (long ddmStructureId : descendantDDMStructureIds) {
234 DDMStructure ddmStructure =
235 DDMStructureLocalServiceUtil.getDDMStructure(ddmStructureId);
236
237 ddmStructureKeys[i++] = ddmStructure.getStructureKey();
238 }
239
240
241
242 Map<?, ?> articleIds = (Map<?, ?>)newPrimaryKeysMaps.get(
243 JournalArticle.class.getName());
244
245 ActionableDynamicQuery journalArticleActionableDynamicQuery =
246 getJournalArticleActionableDynamicQuery(
247 groupId, articleIds, ddmStructureKeys);
248
249 journalArticleActionableDynamicQuery.performActions();
250
251
252
253 List<DLFileEntry> dlFileEntries = new ArrayList<DLFileEntry>();
254
255 try {
256 Method method = ReflectionUtil.getDeclaredMethod(
257 DLFileEntryLocalServiceUtil.class, "getDDMStructureFileEntries",
258 long.class, long[].class);
259
260 Object object = method.invoke(
261 DLFileEntryLocalServiceUtil.class, groupId,
262 ArrayUtil.toLongArray(descendantDDMStructureIds));
263
264 if (object != null) {
265 dlFileEntries = (List<DLFileEntry>)object;
266 }
267 }
268 catch (Exception e) {
269 List<DLFileEntry> allDlFileEntries =
270 DLFileEntryLocalServiceUtil.getDDMStructureFileEntries(
271 ArrayUtil.toLongArray(descendantDDMStructureIds));
272
273 for (DLFileEntry dlFileEntry : allDlFileEntries) {
274 if (groupId == dlFileEntry.getGroupId()) {
275 dlFileEntries.add(dlFileEntry);
276 }
277 }
278 }
279
280 Map<?, ?> dlFileEntryPrimaryKeysMap = newPrimaryKeysMaps.get(
281 DLFileEntry.class.getName());
282
283 Indexer dlFileEntryIndexer = IndexerRegistryUtil.getIndexer(
284 DLFileEntry.class);
285
286 for (DLFileEntry dlFileEntry : dlFileEntries) {
287 if (containsValue(
288 dlFileEntryPrimaryKeysMap, dlFileEntry.getFileEntryId())) {
289
290 continue;
291 }
292
293 dlFileEntryIndexer.reindex(dlFileEntry);
294 }
295 }
296
297 protected boolean containsValue(Map<?, ?> map, long value) {
298 if ((map == null) || map.isEmpty() || (value <= 0)) {
299 return false;
300 }
301
302 for (Object object : map.values()) {
303 if (GetterUtil.getLong(object) == value) {
304 return true;
305 }
306 }
307
308 return false;
309 }
310
311 protected void getDescendantDDMStructureIds(
312 List<Long> ddmStructureIds, long groupId, long parentDDMStructureId)
313 throws PortalException, SystemException {
314
315 DynamicQuery query = DDMStructureLocalServiceUtil.dynamicQuery();
316
317 Property groupProperty = PropertyFactoryUtil.forName("groupId");
318
319 query.add(groupProperty.eq(groupId));
320
321 Property parentStructureIdProperty = PropertyFactoryUtil.forName(
322 "parentStructureId");
323
324 query.add(parentStructureIdProperty.eq(parentDDMStructureId));
325
326 List<DDMStructure> ddmStructures =
327 DDMStructureLocalServiceUtil.dynamicQuery(query);
328
329 for (DDMStructure ddmStructure : ddmStructures) {
330 ddmStructureIds.add(ddmStructure.getStructureId());
331
332 getDescendantDDMStructureIds(
333 ddmStructureIds, ddmStructure.getGroupId(),
334 ddmStructure.getStructureId());
335 }
336 }
337
338 protected List<Long> getDescendantDDMStructureIds(
339 long groupId, long ddmStructureId)
340 throws PortalException, SystemException {
341
342 List<Long> ddmStructureIds = new ArrayList<Long>();
343
344 getDescendantDDMStructureIds(ddmStructureIds, groupId, ddmStructureId);
345
346 ddmStructureIds.add(0, ddmStructureId);
347
348 return ddmStructureIds;
349 }
350
351 @Override
352 public String handleException(BackgroundTask backgroundTask, Exception e) {
353 StringBundler sb = new StringBundler(4);
354
355 sb.append("Indexing failed after importing with the following error: ");
356 sb.append(e.getMessage());
357 sb.append(StringPool.PERIOD);
358 sb.append(StringPool.SPACE);
359 sb.append("Please reindex site manually.");
360
361 String message = sb.toString();
362
363 if (_log.isInfoEnabled()) {
364 _log.info(message);
365 }
366
367 return message;
368 }
369
370 private static Log _log = LogFactoryUtil.getLog(
371 StagingIndexingBackgroundTaskExecutor.class);
372
373 }