1 package org.exoplatform.services.wcm.search.connector;
2
3 import org.apache.commons.chain.Context;
4 import org.exoplatform.commons.search.index.IndexingService;
5 import org.exoplatform.commons.utils.CommonsUtils;
6 import org.exoplatform.services.cms.documents.TrashService;
7 import org.exoplatform.services.ext.action.InvocationContext;
8 import org.exoplatform.services.jcr.impl.core.NodeImpl;
9 import org.exoplatform.services.jcr.impl.core.PropertyImpl;
10 import org.exoplatform.services.jcr.impl.ext.action.AdvancedAction;
11 import org.exoplatform.services.jcr.impl.ext.action.AdvancedActionException;
12 import org.exoplatform.services.jcr.observation.ExtendedEvent;
13 import org.exoplatform.services.log.ExoLogger;
14 import org.exoplatform.services.log.Log;
15 import org.exoplatform.services.wcm.core.NodeLocation;
16 import org.exoplatform.services.wcm.core.NodetypeConstant;
17 import org.exoplatform.services.wcm.utils.WCMCoreUtils;
18
19 import javax.jcr.Node;
20 import javax.jcr.NodeIterator;
21 import javax.jcr.RepositoryException;
22 import javax.jcr.observation.Event;
23 import java.util.function.Consumer;
24 import java.util.function.Predicate;
25
26
27
28
29 public class FileIndexerAction implements AdvancedAction {
30 private static final Log LOGGER = ExoLogger.getExoLogger(FileIndexerAction.class);
31
32 private IndexingService indexingService;
33
34 private TrashService trashService;
35
36 public FileIndexerAction() {
37 this.indexingService = CommonsUtils.getService(IndexingService.class);
38 this.trashService = CommonsUtils.getService(TrashService.class);
39 }
40
41 @Override
42 public boolean execute(Context context) throws Exception {
43 NodeImpl node;
44
45 int eventType = (Integer) context.get(InvocationContext.EVENT);
46
47 switch(eventType) {
48 case Event.NODE_ADDED:
49 node = (NodeImpl)context.get(InvocationContext.CURRENT_ITEM);
50 if(node != null) {
51 if (trashService.isInTrash(node)) {
52 applyIndexingOperationOnNodes(node, n -> indexingService.unindex(FileindexingConnector.TYPE, n.getInternalIdentifier()), n -> true);
53 } else {
54 applyIndexingOperationOnNodes(node, n -> indexingService.index(FileindexingConnector.TYPE, n.getInternalIdentifier()), n -> true);
55 }
56 }
57 break;
58 case Event.NODE_REMOVED:
59 node = (NodeImpl)context.get(InvocationContext.CURRENT_ITEM);
60 if(node != null) {
61 applyIndexingOperationOnNodes(node, n -> indexingService.unindex(FileindexingConnector.TYPE, n.getInternalIdentifier()), n -> true);
62 }
63 break;
64 case Event.PROPERTY_ADDED:
65 case Event.PROPERTY_CHANGED:
66 case Event.PROPERTY_REMOVED:
67 PropertyImpl property = (PropertyImpl) context.get(InvocationContext.CURRENT_ITEM);
68 if(property != null) {
69 node = property.getParent();
70 if (node != null && !trashService.isInTrash(node)) {
71 if (node.isNodeType(NodetypeConstant.NT_RESOURCE)) {
72 node = node.getParent();
73 }
74 if (node.isNodeType(NodetypeConstant.NT_FILE)) {
75 indexingService.reindex(FileindexingConnector.TYPE, node.getInternalIdentifier());
76 }
77 }
78 }
79 break;
80 case ExtendedEvent.PERMISSION_CHANGED:
81 node = (NodeImpl)context.get(InvocationContext.CURRENT_ITEM);
82 if (node != null && !trashService.isInTrash(node)) {
83
84
85 applyIndexingOperationOnNodes(node, n -> indexingService.reindex(FileindexingConnector.TYPE, n.getInternalIdentifier()), n -> hasNotPrivilegeableMixin(n));
86 }
87 break;
88 }
89
90 return true;
91 }
92
93 @Override
94 public void onError(Exception e, Context context) throws AdvancedActionException {
95 LOGGER.error("Error while indexing file", e);
96 }
97
98 protected Node getNodeByPath(String path) {
99 return NodeLocation.getNodeByLocation(new NodeLocation(WCMCoreUtils.getRepository().getConfiguration().getName(), "collaboration", path));
100 }
101
102
103
104
105
106
107
108 protected void applyIndexingOperationOnNodes(NodeImpl node, Consumer<NodeImpl> indexingOperation, Predicate<NodeImpl> filter) {
109 if (node == null) {
110 return;
111 }
112
113 try {
114 if (node.isNodeType(NodetypeConstant.NT_FILE)) {
115 indexingOperation.accept(node);
116 }
117 } catch (RepositoryException e) {
118 LOGGER.error("Cannot get primary type of node " + node.getInternalIdentifier(), e);
119 }
120
121 try {
122 NodeIterator nodeIterator = node.getNodes();
123 while(nodeIterator.hasNext()) {
124 NodeImpl childNode = (NodeImpl) nodeIterator.nextNode();
125 if(! filter.test(childNode))
126 continue;
127 applyIndexingOperationOnNodes(childNode, indexingOperation, filter);
128 }
129 } catch (RepositoryException e) {
130 LOGGER.error("Cannot get child nodes of node " + node.getInternalIdentifier(), e);
131 }
132 }
133
134 private boolean hasNotPrivilegeableMixin(NodeImpl node) {
135 try {
136 return ! node.isNodeType(NodetypeConstant.EXO_PRIVILEGEABLE);
137 } catch (RepositoryException e) {
138 LOGGER.error("Error while check privilegeable mixin ", e);
139 }
140 return true;
141 }
142 }