1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.admininterface.commands;
35
36 import info.magnolia.cms.core.Content;
37 import info.magnolia.cms.exchange.ExchangeException;
38 import info.magnolia.cms.i18n.MessagesManager;
39 import info.magnolia.cms.util.AlertUtil;
40 import info.magnolia.context.Context;
41
42 import java.util.ArrayList;
43 import java.util.Collection;
44 import java.util.Collections;
45 import java.util.Comparator;
46 import java.util.List;
47 import java.util.Map;
48
49 import javax.jcr.Node;
50 import javax.jcr.NodeIterator;
51 import javax.jcr.RepositoryException;
52
53 import org.apache.commons.lang.StringUtils;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56
57
58
59
60
61
62
63 public class ActivationCommand extends BaseActivationCommand {
64
65
66
67
68 private static Logger log = LoggerFactory.getLogger(ActivationCommand.class);
69
70 private boolean recursive;
71
72 private String versionNumber;
73
74 private List versionMap;
75
76
77
78
79 @Override
80 public boolean execute(Context ctx) {
81 boolean success = false;
82 try {
83 log.debug("Will activate content from {} repository with uuid {} and path {}", new Object[] {getRepository(), getUuid(), getPath()});
84 final Content originalState = getNode(ctx);
85 Content thisState = originalState;
86 if (!recursive) {
87 if (StringUtils.isNotEmpty(getVersion())) {
88 try {
89 thisState = thisState.getVersionedContent(getVersion());
90 } catch (RepositoryException re) {
91 log.error("Failed to get version "+getVersion()+" for "+thisState.getHandle(), re);
92 }
93 }
94 success = activateUpdate(ctx, originalState);
95 } else {
96 success = activateBulkUpdate(ctx, getNode(ctx));
97 }
98 }
99 catch (Exception e) {
100 log.error("can't activate", e);
101 AlertUtil.setException(MessagesManager.get("tree.error.activate"), e, ctx);
102 }
103 return success;
104 }
105
106 private boolean activateUpdate(Context ctx, Content thisState) throws ExchangeException, RepositoryException {
107 boolean success;
108 String parentPath = StringUtils.substringBeforeLast(thisState.getHandle(), "/");
109 if (StringUtils.isEmpty(parentPath)) {
110 parentPath = "/";
111 }
112 log.debug("Activate content {} as a child of {}", new Object[] {thisState.getName(), parentPath});
113
114 List orderInfo = getOrderingInfo(thisState);
115 if (StringUtils.isNotEmpty(getVersion())) {
116 try {
117 thisState = thisState.getVersionedContent(getVersion());
118 } catch (RepositoryException re) {
119
120 log.error("Failed to get version "+getVersion()+" for "+thisState.getHandle() + ". Activating current content instead.", re);
121 }
122 }
123 getSyndicator().activate(parentPath, thisState, orderInfo);
124 log.debug("exec successfully.");
125 success = true;
126 return success;
127 }
128
129 private boolean activateBulkUpdate(Context ctx, Content thisState) throws ExchangeException, RepositoryException {
130 boolean success;
131
132 List versionMap = getVersionMap();
133 if (versionMap == null) {
134 String parentPath = StringUtils.substringBeforeLast(thisState.getHandle(), "/");
135 if (StringUtils.isEmpty(parentPath)) {
136 parentPath = "/";
137 }
138 log.debug("Activate content {} as a child of {}", new Object[] {thisState.getName(), parentPath});
139 activateRecursive(parentPath, thisState, ctx);
140 } else {
141 activateRecursive(ctx, versionMap);
142 }
143 log.debug("exec successfully.");
144 success = true;
145 return success;
146 }
147
148
149
150
151
152
153
154
155 protected void activateRecursive(String parentPath, Content node, Context ctx)
156 throws ExchangeException, RepositoryException {
157
158 getSyndicator().activate(parentPath, node, getOrderingInfo(node));
159
160 Collection children = node.getChildren(new Content.ContentFilter() {
161 @Override
162 public boolean accept(Content content) {
163 try {
164 return !getRule().isAllowed(content.getJCRNode());
165 }
166 catch (RepositoryException e) {
167 log.error("can't get nodetype", e);
168 return false;
169 }
170 }
171 });
172
173
174
175
176 Content[] childArray = (Content[]) children.toArray(new Content[children.size()]);
177 for (int i = childArray.length - 1; i >=0; i--) {
178 this.activateRecursive(node.getHandle(), childArray[i], ctx);
179 }
180 }
181
182
183
184
185
186 protected void activateRecursive(Context ctx, List versionMap)
187 throws ExchangeException, RepositoryException {
188
189 Map<String, Object>[] versions = (Map<String, Object>[]) versionMap.toArray(new Map[0]);
190
191 for (int i = 0; i < versions.length; i++) {
192 Map<String, Object> entry = versions[i];
193 String uuid = (String) entry.get("uuid");
194 if (StringUtils.equalsIgnoreCase("class", uuid)) {
195
196
197 versionMap.remove(entry);
198 }
199 try {
200 Content content = ctx.getHierarchyManager(getRepository()).getContentByUUID(uuid);
201 entry.put("handle", content.getHandle());
202 entry.put("index", i);
203 } catch (RepositoryException re) {
204 log.error("Failed to activate node with UUID : "+uuid);
205 log.error(re.getMessage());
206 versionMap.remove(entry);
207 }
208 }
209 versions = null;
210
211
212 Collections.sort((List<Map<String, Object>>) versionMap, new Comparator<Map<String, Object>>() {
213
214 @Override
215 public int compare(Map<String, Object> o1, Map<String, Object> o2) {
216 if (o1.equals(o2)) {
217 return 0;
218 }
219
220 String handle1 = (String) o1.get("handle");
221 String handle2 = (String) o2.get("handle");
222 if (handle1.equals(handle2)) {
223 return 0;
224 }
225 if (handle2.startsWith(handle1)) {
226
227 return -1;
228 }
229 String parent1 = StringUtils.substringBeforeLast(handle1, "/");
230 String parent2 = StringUtils.substringBeforeLast(handle2, "/");
231 if (parent1.equals(parent2)) {
232
233 int idx1 = (Integer) o1.get("index");
234 int idx2 = (Integer) o2.get("index");
235
236 if (idx1 == idx2) {
237 return 0;
238 }
239 return idx1 < idx2 ? 1 : -1;
240 }
241
242
243 int dirLevels1 = StringUtils.countMatches(handle1, "/");
244 int dirLevels2 = StringUtils.countMatches(handle2, "/");
245
246 if (dirLevels1 == dirLevels2) {
247 return 0;
248 }
249 return dirLevels1 < dirLevels2 ? -1 : 1;
250 }});
251
252
253
254
255 for (Map entry : (List<Map>) versionMap) {
256
257 String uuid = (String) entry.get("uuid");
258 String versionNumber = (String) entry.get("version");
259 if (StringUtils.equalsIgnoreCase("class", uuid)) {
260
261
262 continue;
263 }
264 try {
265 Content content = ctx.getHierarchyManager(getRepository()).getContentByUUID(uuid);
266
267
268 List orderedList = getOrderingInfo(content);
269 String parentPath = content.getParent().getHandle();
270 content = content.getVersionedContent(versionNumber);
271
272 getSyndicator().activate(parentPath, content, orderedList);
273 } catch (RepositoryException re) {
274 log.error("Failed to activate node with UUID : "+uuid);
275 log.error(re.getMessage());
276 }
277 }
278 }
279
280
281
282
283
284
285 protected List getOrderingInfo(Content node) {
286
287
288 List siblings = new ArrayList();
289 Node thisNode = node.getJCRNode();
290 try {
291 String thisNodeType = node.getNodeTypeName();
292 String thisNodeUUID = node.getUUID();
293 NodeIterator nodeIterator = thisNode.getParent().getNodes();
294 while (nodeIterator.hasNext()) {
295 Node sibling = nodeIterator.nextNode();
296
297 if (sibling.isNodeType(thisNodeType)) {
298 if (thisNodeUUID.equalsIgnoreCase(sibling.getUUID())) {
299 break;
300 }
301 }
302 }
303 while (nodeIterator.hasNext()) {
304 Node sibling = nodeIterator.nextNode();
305 if (sibling.isNodeType(thisNodeType)) {
306 siblings.add(sibling.getUUID());
307 }
308 }
309 } catch (RepositoryException re) {
310
311 log.error("Failed to get Ordering info", re);
312 }
313 return siblings;
314 }
315
316
317
318
319 public boolean isRecursive() {
320 return recursive;
321 }
322
323
324
325
326 public void setRecursive(boolean recursive) {
327 this.recursive = recursive;
328 }
329
330
331
332
333 public void setVersion(String number) {
334 this.versionNumber = number;
335 }
336
337
338
339
340 public String getVersion() {
341 return this.versionNumber;
342 }
343
344
345
346
347 public void setVersionMap(List versionMap) {
348 this.versionMap = versionMap;
349 }
350
351
352
353
354 public List getVersionMap() {
355 return this.versionMap;
356 }
357
358 @Override
359 public void release() {
360 super.release();
361 this.versionMap = null;
362 this.recursive = false;
363 this.versionNumber = null;
364 }
365
366 }