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