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