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 searchQuery.addTerms(_KEYWORDS_FIELDS, keywords);
333
334 searchQuery.addExactTerm(Field.TAGS_ENTRIES, keywords);
335
336 BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
337
338 fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
339
340 if (searchQuery.clauses().size() > 0) {
341 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
342 }
343
344 return SearchEngineUtil.search(
345 companyId, groupId, userId, WikiPage.class.getName(), fullQuery,
346 start, end);
347 }
348 catch (Exception e) {
349 throw new SystemException(e);
350 }
351 }
352
353 public void subscribeNode(long userId, long nodeId)
354 throws PortalException, SystemException {
355
356 subscriptionLocalService.addSubscription(
357 userId, WikiNode.class.getName(), nodeId);
358 }
359
360 public void unsubscribeNode(long userId, long nodeId)
361 throws PortalException, SystemException {
362
363 subscriptionLocalService.deleteSubscription(
364 userId, WikiNode.class.getName(), nodeId);
365 }
366
367
370 public WikiNode updateNode(
371 long nodeId, String name, String description)
372 throws PortalException, SystemException {
373
374 return updateNode(nodeId, name, description, new ServiceContext());
375 }
376
377 public WikiNode updateNode(
378 long nodeId, String name, String description,
379 ServiceContext serviceContext)
380 throws PortalException, SystemException {
381
382 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
383
384 validate(nodeId, node.getGroupId(), name);
385
386 node.setModifiedDate(serviceContext.getModifiedDate(null));
387 node.setName(name);
388 node.setDescription(description);
389
390 wikiNodePersistence.update(node, false);
391
392 return node;
393 }
394
395 protected WikiImporter getWikiImporter(String importer)
396 throws SystemException {
397
398 WikiImporter wikiImporter = _wikiImporters.get(importer);
399
400 if (wikiImporter == null) {
401 String importerClass = PropsUtil.get(
402 PropsKeys.WIKI_IMPORTERS_CLASS, new Filter(importer));
403
404 if (importerClass != null) {
405 wikiImporter = (WikiImporter)InstancePool.get(importerClass);
406
407 _wikiImporters.put(importer, wikiImporter);
408 }
409
410 if (importer == null) {
411 throw new SystemException(
412 "Unable to instantiate wiki importer class " +
413 importerClass);
414 }
415 }
416
417 return wikiImporter;
418 }
419
420 protected void reIndexNodes(long companyId) throws SystemException {
421 int nodeCount = wikiNodePersistence.countByCompanyId(companyId);
422
423 int nodePages = nodeCount / Indexer.DEFAULT_INTERVAL;
424
425 for (int i = 0; i <= nodePages; i++) {
426 int nodeStart = (i * Indexer.DEFAULT_INTERVAL);
427 int nodeEnd = nodeStart + Indexer.DEFAULT_INTERVAL;
428
429 reIndexNodes(companyId, nodeStart, nodeEnd);
430 }
431 }
432
433 protected void reIndexNodes(long companyId, int nodeStart, int nodeEnd)
434 throws SystemException {
435
436 List<WikiNode> nodes = wikiNodePersistence.findByCompanyId(
437 companyId, nodeStart, nodeEnd);
438
439 for (WikiNode node : nodes) {
440 long nodeId = node.getNodeId();
441
442 int pageCount = wikiPagePersistence.countByN_H(nodeId, true);
443
444 int pagePages = pageCount / Indexer.DEFAULT_INTERVAL;
445
446 for (int i = 0; i <= pagePages; i++) {
447 int pageStart = (i * Indexer.DEFAULT_INTERVAL);
448 int pageEnd = pageStart + Indexer.DEFAULT_INTERVAL;
449
450 reIndexPages(nodeId, pageStart, pageEnd);
451 }
452 }
453 }
454
455 protected void reIndexPages(long nodeId, int pageStart, int pageEnd)
456 throws SystemException {
457
458 List<WikiPage> pages = wikiPagePersistence.findByN_H(
459 nodeId, true, pageStart, pageEnd);
460
461 for (WikiPage page : pages) {
462 wikiPageLocalService.reIndex(page);
463 }
464 }
465
466 protected void validate(long groupId, String name)
467 throws PortalException, SystemException {
468
469 validate(0, groupId, name);
470 }
471
472 protected void validate(long nodeId, long groupId, String name)
473 throws PortalException, SystemException {
474
475 if (name.equalsIgnoreCase("tag")) {
476 throw new NodeNameException(name + " is reserved");
477 }
478
479 if (!Validator.isName(name)) {
480 throw new NodeNameException();
481 }
482
483 WikiNode node = wikiNodePersistence.fetchByG_N(groupId, name);
484
485 if ((node != null) && (node.getNodeId() != nodeId)) {
486 throw new DuplicateNodeNameException();
487 }
488 }
489
490 private static final String[] _KEYWORDS_FIELDS = {
491 Field.CONTENT, Field.TITLE
492 };
493
494 private static Log _log = LogFactoryUtil.getLog(
495 WikiNodeLocalServiceImpl.class);
496
497 private Map<String, WikiImporter> _wikiImporters =
498 new HashMap<String, WikiImporter>();
499
500 }