1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.exoplatform.services.wcm.extensions.publication;
18
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.TreeSet;
23
24 import javax.jcr.Node;
25 import javax.jcr.lock.Lock;
26
27 import org.apache.commons.lang.StringUtils;
28 import org.exoplatform.container.xml.InitParams;
29 import org.exoplatform.ecm.utils.lock.LockUtil;
30 import org.exoplatform.ecm.webui.utils.Utils;
31 import org.exoplatform.services.ecm.publication.PublicationPlugin;
32 import org.exoplatform.services.ecm.publication.PublicationService;
33 import org.exoplatform.services.jcr.core.ManageableRepository;
34 import org.exoplatform.services.log.ExoLogger;
35 import org.exoplatform.services.log.Log;
36 import org.exoplatform.services.security.Identity;
37 import org.exoplatform.services.security.IdentityRegistry;
38 import org.exoplatform.services.wcm.core.NodeLocation;
39 import org.exoplatform.services.wcm.core.NodetypeConstant;
40 import org.exoplatform.services.wcm.extensions.publication.context.impl.ContextConfig.Context;
41 import org.exoplatform.services.wcm.extensions.publication.impl.PublicationManagerImpl;
42 import org.exoplatform.services.wcm.extensions.publication.lifecycle.authoring.AuthoringPublicationConstant;
43 import org.exoplatform.services.wcm.extensions.publication.lifecycle.impl.LifecyclesConfig.Lifecycle;
44 import org.exoplatform.services.wcm.extensions.publication.lifecycle.impl.LifecyclesConfig.State;
45 import org.exoplatform.services.wcm.extensions.utils.ContextComparator;
46 import org.exoplatform.services.wcm.publication.WebpagePublicationPlugin;
47 import org.exoplatform.services.wcm.utils.WCMCoreUtils;
48
49 public class WCMPublicationServiceImpl
50 extends
51 org.exoplatform.services.wcm.publication.WCMPublicationServiceImpl {
52
53 private static final Log LOG = ExoLogger.getLogger(WCMPublicationServiceImpl.class.getName());
54
55 private String publicationLocation = "collaboration:/";
56
57 private String[] notAllowChildNodeEnrollInPubliction = new String[] { NodetypeConstant.EXO_WEBCONTENT };
58
59
60
61
62
63 public WCMPublicationServiceImpl(InitParams initParams) {
64 super();
65 this.publicationService = WCMCoreUtils.getService(PublicationService.class);
66 if(initParams.getValueParam("publicationLocation") != null) {
67 publicationLocation = initParams.getValueParam("publicationLocation").getValue();
68 }
69 if(initParams.getValueParam("notAllowChildNodeEnrollInPubliction") != null) {
70 if(initParams.getValueParam("notAllowChildNodeEnrollInPubliction").getValue().indexOf(";") > -1) {
71 notAllowChildNodeEnrollInPubliction =
72 initParams.getValueParam("notAllowChildNodeEnrollInPubliction").getValue().split(";");
73 }
74
75 }
76 }
77
78
79
80
81
82
83 public void enrollNodeInLifecycle(Node node, String siteName, String remoteUser) {
84 try {
85 if (LOG.isInfoEnabled()) LOG.info(node.getPath() + "::" + siteName + "::"+remoteUser);
86
87 PublicationManagerImpl publicationManagerImpl = WCMCoreUtils.getService(PublicationManagerImpl.class);
88
89 ContextComparator comparator = new ContextComparator();
90 TreeSet<Context> treeSetContext = new TreeSet<Context>(comparator);
91 treeSetContext.addAll(publicationManagerImpl.getContexts());
92 for (Context context : treeSetContext) {
93 boolean pathVerified = true;
94 boolean nodetypeVerified = true;
95 boolean siteVerified = true;
96 boolean membershipVerified = true;
97 String path = context.getPath();
98 String nodetype = context.getNodetype();
99 String site = context.getSite();
100 List<String> memberships = new ArrayList<String>();
101 if (context.getMembership() != null) {
102 memberships.add(context.getMembership());
103 }
104 if (context.getMemberships() != null) {
105 memberships.addAll(context.getMemberships());
106 }
107 if (path != null) {
108 String workspace = node.getSession().getWorkspace().getName();
109 ManageableRepository manaRepository = (ManageableRepository) node.getSession()
110 .getRepository();
111 String repository = manaRepository.getConfiguration().getName();
112 String[] pathTab = path.split(":");
113 pathVerified = node.getPath().contains(pathTab[2]) && (repository.equals(pathTab[0]))
114 && (workspace.equals(pathTab[1]));
115 }
116 if (nodetype != null)
117 nodetypeVerified = nodetype.equals(node.getPrimaryNodeType().getName());
118 if (site != null)
119 siteVerified = site.equals(siteName);
120 if (memberships.size() > 0) {
121 for (String membership : memberships) {
122 String[] membershipTab = membership.split(":");
123 IdentityRegistry identityRegistry = WCMCoreUtils.getService(IdentityRegistry.class);
124 Identity identity = identityRegistry.getIdentity(remoteUser);
125 membershipVerified = identity.isMemberOf(membershipTab[1], membershipTab[0]);
126 if (membershipVerified)
127 break;
128 }
129 }
130 if (pathVerified && nodetypeVerified && siteVerified && membershipVerified) {
131 Lifecycle lifecycle = publicationManagerImpl.getLifecycle(context.getLifecycle());
132 String lifecycleName = this.getWebpagePublicationPlugins()
133 .get(lifecycle.getPublicationPlugin())
134 .getLifecycleName();
135 if (node.canAddMixin("publication:authoring")) {
136 node.addMixin("publication:authoring");
137 node.setProperty("publication:lastUser", remoteUser);
138 node.setProperty("publication:lifecycle", lifecycle.getName());
139
140 }
141 enrollNodeInLifecycle(node, lifecycleName);
142 setInitialState(node, lifecycle, remoteUser);
143 break;
144 }
145 }
146 } catch (Exception ex) {
147 if (LOG.isErrorEnabled()) {
148 LOG.error("Couldn't complete the enrollement : ", ex);
149 }
150 }
151 }
152
153
154
155
156
157
158
159
160 private void setInitialState(Node node, Lifecycle lifecycle, String remoteUser) throws Exception {
161 List<State> states = lifecycle.getStates();
162 if (states == null || states.size() <= 0) {
163 if (LOG.isWarnEnabled()) {
164 LOG.warn("could not find an initial state in lifecycle " + lifecycle.getName());
165 }
166 } else {
167 String initialState = states.get(0).getState();
168 PublicationPlugin publicationPlugin = publicationService.getPublicationPlugins()
169 .get(AuthoringPublicationConstant.LIFECYCLE_NAME);
170 HashMap<String, String> context = new HashMap<String, String>();
171
172 NodeLocation currentRevisionLocation = NodeLocation.getNodeLocationByNode(node);
173
174 Node currentRevision = getCurrentRevision(currentRevisionLocation);
175 if (currentRevision != null) {
176 context.put(AuthoringPublicationConstant.CURRENT_REVISION_NAME, currentRevision.getName());
177 }
178 try {
179 if (node.isLocked()) {
180 Lock lock = node.getLock();
181 String owner = lock.getLockOwner();
182 if (LOG.isInfoEnabled())
183 LOG.info("node is locked by owner, unlocking it for enrollement");
184 if (node.holdsLock() && remoteUser.equals(owner)) {
185 String lockToken = LockUtil.getLockToken(node);
186 if (lockToken != null) {
187 node.getSession().addLockToken(lockToken);
188 }
189 node.unlock();
190 node.removeMixin(Utils.MIX_LOCKABLE);
191
192 LockUtil.removeLock(node);
193 }
194 }
195
196 context.put(AuthoringPublicationConstant.IS_INITIAL_PHASE, "true");
197 node.setProperty("publication:lastUser", remoteUser);
198 publicationPlugin.changeState(node, initialState, context);
199 } catch (Exception e) {
200 if (LOG.isErrorEnabled()) {
201 LOG.error("Error setting staged state : ", e);
202 }
203 }
204 }
205
206 }
207
208 public Node getCurrentRevision(NodeLocation currentRevisionLocation) {
209 return NodeLocation.getNodeByLocation(currentRevisionLocation);
210 }
211
212
213
214
215
216 public void updateLifecyleOnChangeContent(Node node,
217 String siteName,
218 String remoteUser,
219 String newState) throws Exception {
220 if(!node.getPath().startsWith(publicationLocation.split(":")[1])
221 && !publicationService.isNodeEnrolledInLifecycle(node)) return;
222 if(node.getPrimaryNodeType().getName().equals(NodetypeConstant.NT_FILE)) {
223 for(String nodeType : notAllowChildNodeEnrollInPubliction) {
224 if(!allowEnrollInPublication(node, nodeType)) return;
225 }
226 }
227 if (!publicationService.isNodeEnrolledInLifecycle(node)) {
228 enrollNodeInLifecycle(node, siteName, remoteUser);
229 }
230 String lifecycleName = publicationService.getNodeLifecycleName(node);
231 WebpagePublicationPlugin publicationPlugin = this.getWebpagePublicationPlugins()
232 .get(lifecycleName);
233
234 publicationPlugin.updateLifecyleOnChangeContent(node, remoteUser, newState);
235
236 listenerService.broadcast(UPDATE_EVENT, cmsService, node);
237 }
238
239 private boolean allowEnrollInPublication(Node node, String nodeType) throws Exception {
240 String path = node.getPath();
241 Node parentNode = node.getParent();
242 while(!path.equals("/") && path.length() > 0) {
243 parentNode = (Node)node.getSession().getItem(path);
244 if(parentNode.isNodeType(nodeType)) return false;
245 path = path.substring(0, path.lastIndexOf("/"));
246 }
247 return true;
248 }
249 }