1
22
23 package com.liferay.portlet.wiki.service.impl;
24
25 import com.liferay.portal.PortalException;
26 import com.liferay.portal.SystemException;
27 import com.liferay.portal.kernel.configuration.Filter;
28 import com.liferay.portal.kernel.log.Log;
29 import com.liferay.portal.kernel.log.LogFactoryUtil;
30 import com.liferay.portal.kernel.search.BooleanClauseOccur;
31 import com.liferay.portal.kernel.search.BooleanQuery;
32 import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
33 import com.liferay.portal.kernel.search.Field;
34 import com.liferay.portal.kernel.search.Hits;
35 import com.liferay.portal.kernel.search.SearchEngineUtil;
36 import com.liferay.portal.kernel.search.SearchException;
37 import com.liferay.portal.kernel.search.TermQuery;
38 import com.liferay.portal.kernel.search.TermQueryFactoryUtil;
39 import com.liferay.portal.kernel.util.GetterUtil;
40 import com.liferay.portal.kernel.util.InstancePool;
41 import com.liferay.portal.kernel.util.PropsKeys;
42 import com.liferay.portal.kernel.util.Validator;
43 import com.liferay.portal.model.Group;
44 import com.liferay.portal.model.ResourceConstants;
45 import com.liferay.portal.model.User;
46 import com.liferay.portal.service.ServiceContext;
47 import com.liferay.portal.util.PropsUtil;
48 import com.liferay.portlet.wiki.DuplicateNodeNameException;
49 import com.liferay.portlet.wiki.NodeNameException;
50 import com.liferay.portlet.wiki.importers.WikiImporter;
51 import com.liferay.portlet.wiki.model.WikiNode;
52 import com.liferay.portlet.wiki.model.WikiPage;
53 import com.liferay.portlet.wiki.service.base.WikiNodeLocalServiceBaseImpl;
54 import com.liferay.portlet.wiki.util.Indexer;
55
56 import java.io.File;
57
58 import java.util.Date;
59 import java.util.HashMap;
60 import java.util.Iterator;
61 import java.util.List;
62 import java.util.Map;
63
64
71 public class WikiNodeLocalServiceImpl extends WikiNodeLocalServiceBaseImpl {
72
73 public WikiNode addNode(
74 long userId, String name, String description,
75 ServiceContext serviceContext)
76 throws PortalException, SystemException {
77
78 return addNode(null, userId, name, description, serviceContext);
79 }
80
81 public WikiNode addNode(
82 String uuid, long userId, String name, String description,
83 ServiceContext serviceContext)
84 throws PortalException, SystemException {
85
86
88 User user = userPersistence.findByPrimaryKey(userId);
89 long groupId = serviceContext.getScopeGroupId();
90 Date now = new Date();
91
92 validate(groupId, name);
93
94 long nodeId = counterLocalService.increment();
95
96 WikiNode node = wikiNodePersistence.create(nodeId);
97
98 node.setUuid(uuid);
99 node.setGroupId(groupId);
100 node.setCompanyId(user.getCompanyId());
101 node.setUserId(user.getUserId());
102 node.setUserName(user.getFullName());
103 node.setCreateDate(now);
104 node.setModifiedDate(now);
105 node.setName(name);
106 node.setDescription(description);
107
108 try {
109 wikiNodePersistence.update(node, false);
110 }
111 catch (SystemException se) {
112 if (_log.isWarnEnabled()) {
113 _log.warn(
114 "Add failed, fetch {groupId=" + groupId + ", name=" +
115 name + "}");
116 }
117
118 node = wikiNodePersistence.fetchByG_N(groupId, name, false);
119
120 if (node == null) {
121 throw se;
122 }
123
124 return node;
125 }
126
127
129 if (serviceContext.getAddCommunityPermissions() ||
130 serviceContext.getAddGuestPermissions()) {
131
132 addNodeResources(
133 node, serviceContext.getAddCommunityPermissions(),
134 serviceContext.getAddGuestPermissions());
135 }
136 else {
137 addNodeResources(
138 node, serviceContext.getCommunityPermissions(),
139 serviceContext.getGuestPermissions());
140 }
141
142 return node;
143 }
144
145 public void addNodeResources(
146 long nodeId, boolean addCommunityPermissions,
147 boolean addGuestPermissions)
148 throws PortalException, SystemException {
149
150 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
151
152 addNodeResources(node, addCommunityPermissions, addGuestPermissions);
153 }
154
155 public void addNodeResources(
156 WikiNode node, boolean addCommunityPermissions,
157 boolean addGuestPermissions)
158 throws PortalException, SystemException {
159
160 resourceLocalService.addResources(
161 node.getCompanyId(), node.getGroupId(), node.getUserId(),
162 WikiNode.class.getName(), node.getNodeId(), false,
163 addCommunityPermissions, addGuestPermissions);
164 }
165
166 public void addNodeResources(
167 long nodeId, String[] communityPermissions,
168 String[] guestPermissions)
169 throws PortalException, SystemException {
170
171 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
172
173 addNodeResources(node, communityPermissions, guestPermissions);
174 }
175
176 public void addNodeResources(
177 WikiNode node, String[] communityPermissions,
178 String[] guestPermissions)
179 throws PortalException, SystemException {
180
181 resourceLocalService.addModelResources(
182 node.getCompanyId(), node.getGroupId(), node.getUserId(),
183 WikiNode.class.getName(), node.getNodeId(), communityPermissions,
184 guestPermissions);
185 }
186
187 public void deleteNode(long nodeId)
188 throws PortalException, SystemException {
189
190 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
191
192 deleteNode(node);
193 }
194
195 public void deleteNode(WikiNode node)
196 throws PortalException, SystemException {
197
198
200 try {
201 Indexer.deletePages(node.getCompanyId(), node.getNodeId());
202 }
203 catch (SearchException se) {
204 _log.error("Deleting index " + node.getNodeId(), se);
205 }
206
207
209 subscriptionLocalService.deleteSubscriptions(
210 node.getCompanyId(), WikiNode.class.getName(), node.getNodeId());
211
212
214 wikiPageLocalService.deletePages(node.getNodeId());
215
216
218 resourceLocalService.deleteResource(
219 node.getCompanyId(), WikiNode.class.getName(),
220 ResourceConstants.SCOPE_INDIVIDUAL, node.getNodeId());
221
222
224 wikiNodePersistence.remove(node);
225 }
226
227 public void deleteNodes(long groupId)
228 throws PortalException, SystemException {
229
230 Iterator<WikiNode> itr = wikiNodePersistence.findByGroupId(
231 groupId).iterator();
232
233 while (itr.hasNext()) {
234 WikiNode node = itr.next();
235
236 deleteNode(node);
237 }
238 }
239
240 public WikiNode getNode(long nodeId)
241 throws PortalException, SystemException {
242
243 return wikiNodePersistence.findByPrimaryKey(nodeId);
244 }
245
246 public WikiNode getNode(long groupId, String nodeName)
247 throws PortalException, SystemException {
248
249 return wikiNodePersistence.findByG_N(groupId, nodeName);
250 }
251
252 public List<WikiNode> getNodes(long groupId) throws SystemException {
253 return wikiNodePersistence.findByGroupId(groupId);
254 }
255
256 public List<WikiNode> getNodes(long groupId, int start, int end)
257 throws SystemException {
258
259 return wikiNodePersistence.findByGroupId(groupId, start, end);
260 }
261
262 public int getNodesCount(long groupId) throws SystemException {
263 return wikiNodePersistence.countByGroupId(groupId);
264 }
265
266 public void importPages(
267 long userId, long nodeId, String importer, File[] files,
268 Map<String, String[]> options)
269 throws PortalException, SystemException {
270
271 WikiNode node = getNode(nodeId);
272
273 getWikiImporter(importer).importPages(userId, node, files, options);
274 }
275
276 public void reIndex(String[] ids) throws SystemException {
277 if (SearchEngineUtil.isIndexReadOnly()) {
278 return;
279 }
280
281 long companyId = GetterUtil.getLong(ids[0]);
282
283 try {
284 reIndexNodes(companyId);
285 }
286 catch (SystemException se) {
287 throw se;
288 }
289 catch (Exception e) {
290 throw new SystemException(e);
291 }
292 }
293
294 public Hits search(
295 long companyId, long groupId, long userId, long[] nodeIds,
296 String keywords, int start, int end)
297 throws SystemException {
298
299 try {
300 BooleanQuery contextQuery = BooleanQueryFactoryUtil.create();
301
302 contextQuery.addRequiredTerm(Field.PORTLET_ID, Indexer.PORTLET_ID);
303
304 if (groupId > 0) {
305 Group group = groupLocalService.getGroup(groupId);
306
307 if (group.isLayout()) {
308 contextQuery.addRequiredTerm(Field.SCOPE_GROUP_ID, groupId);
309
310 groupId = group.getParentGroupId();
311 }
312
313 contextQuery.addRequiredTerm(Field.GROUP_ID, groupId);
314 }
315
316 if ((nodeIds != null) && (nodeIds.length > 0)) {
317 BooleanQuery nodeIdsQuery = BooleanQueryFactoryUtil.create();
318
319 for (long nodeId : nodeIds) {
320 if (userId > 0) {
321 try {
322 wikiNodeService.getNode(nodeId);
323 }
324 catch (Exception e) {
325 continue;
326 }
327 }
328
329 TermQuery termQuery = TermQueryFactoryUtil.create(
330 "nodeId", nodeId);
331
332 nodeIdsQuery.add(termQuery, BooleanClauseOccur.SHOULD);
333 }
334
335 contextQuery.add(nodeIdsQuery, BooleanClauseOccur.MUST);
336 }
337
338 BooleanQuery searchQuery = BooleanQueryFactoryUtil.create();
339
340 if (Validator.isNotNull(keywords)) {
341 searchQuery.addTerm(Field.TITLE, keywords);
342 searchQuery.addTerm(Field.CONTENT, keywords);
343 searchQuery.addTerm(Field.TAGS_ENTRIES, keywords, true);
344 }
345
346 BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
347
348 fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
349
350 if (searchQuery.clauses().size() > 0) {
351 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
352 }
353
354 return SearchEngineUtil.search(
355 companyId, groupId, userId, WikiPage.class.getName(), fullQuery,
356 start, end);
357 }
358 catch (Exception e) {
359 throw new SystemException(e);
360 }
361 }
362
363 public void subscribeNode(long userId, long nodeId)
364 throws PortalException, SystemException {
365
366 subscriptionLocalService.addSubscription(
367 userId, WikiNode.class.getName(), nodeId);
368 }
369
370 public void unsubscribeNode(long userId, long nodeId)
371 throws PortalException, SystemException {
372
373 subscriptionLocalService.deleteSubscription(
374 userId, WikiNode.class.getName(), nodeId);
375 }
376
377 public WikiNode updateNode(long nodeId, String name, String description)
378 throws PortalException, SystemException {
379
380 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
381
382 validate(nodeId, node.getGroupId(), name);
383
384 node.setModifiedDate(new Date());
385 node.setName(name);
386 node.setDescription(description);
387
388 wikiNodePersistence.update(node, false);
389
390 return node;
391 }
392
393 protected WikiImporter getWikiImporter(String importer)
394 throws SystemException {
395
396 WikiImporter wikiImporter = _wikiImporters.get(importer);
397
398 if (wikiImporter == null) {
399 String importerClass = PropsUtil.get(
400 PropsKeys.WIKI_IMPORTERS_CLASS, new Filter(importer));
401
402 if (importerClass != null) {
403 wikiImporter = (WikiImporter)InstancePool.get(importerClass);
404
405 _wikiImporters.put(importer, wikiImporter);
406 }
407
408 if (importer == null) {
409 throw new SystemException(
410 "Unable to instantiate wiki importer class " +
411 importerClass);
412 }
413 }
414
415 return wikiImporter;
416 }
417
418 protected void reIndexNodes(long companyId) throws SystemException {
419 int nodeCount = wikiNodePersistence.countByCompanyId(companyId);
420
421 int nodePages = nodeCount / Indexer.DEFAULT_INTERVAL;
422
423 for (int i = 0; i <= nodePages; i++) {
424 int nodeStart = (i * Indexer.DEFAULT_INTERVAL);
425 int nodeEnd = nodeStart + Indexer.DEFAULT_INTERVAL;
426
427 reIndexNodes(companyId, nodeStart, nodeEnd);
428 }
429 }
430
431 protected void reIndexNodes(long companyId, int nodeStart, int nodeEnd)
432 throws SystemException {
433
434 List<WikiNode> nodes = wikiNodePersistence.findByCompanyId(
435 companyId, nodeStart, nodeEnd);
436
437 for (WikiNode node : nodes) {
438 long nodeId = node.getNodeId();
439
440 int pageCount = wikiPagePersistence.countByN_H(nodeId, true);
441
442 int pagePages = pageCount / Indexer.DEFAULT_INTERVAL;
443
444 for (int i = 0; i <= pagePages; i++) {
445 int pageStart = (i * Indexer.DEFAULT_INTERVAL);
446 int pageEnd = pageStart + Indexer.DEFAULT_INTERVAL;
447
448 reIndexPages(nodeId, pageStart, pageEnd);
449 }
450 }
451 }
452
453 protected void reIndexPages(long nodeId, int pageStart, int pageEnd)
454 throws SystemException {
455
456 List<WikiPage> pages = wikiPagePersistence.findByN_H(
457 nodeId, true, pageStart, pageEnd);
458
459 for (WikiPage page : pages) {
460 wikiPageLocalService.reIndex(page);
461 }
462 }
463
464 protected void validate(long groupId, String name)
465 throws PortalException, SystemException {
466
467 validate(0, groupId, name);
468 }
469
470 protected void validate(long nodeId, long groupId, String name)
471 throws PortalException, SystemException {
472
473 if (name.equalsIgnoreCase("tag")) {
474 throw new NodeNameException(name + " is reserved");
475 }
476
477 if (!Validator.isName(name)) {
478 throw new NodeNameException();
479 }
480
481 WikiNode node = wikiNodePersistence.fetchByG_N(groupId, name);
482
483 if ((node != null) && (node.getNodeId() != nodeId)) {
484 throw new DuplicateNodeNameException();
485 }
486 }
487
488 private static Log _log =
489 LogFactoryUtil.getLog(WikiNodeLocalServiceImpl.class);
490
491 private Map<String, WikiImporter> _wikiImporters =
492 new HashMap<String, WikiImporter>();
493
494 }