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.RepositoryException;
50 import javax.jcr.Node;
51 import javax.jcr.NodeIterator;
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 public boolean execute(Context ctx) {
80 boolean success = false;
81 try {
82 log.debug("Will activate content from {} repository with uuid {} and path {}", new Object[] {getRepository(), getUuid(), getPath()});
83 final Content originalState = getNode(ctx);
84 Content thisState = originalState;
85 if (!recursive) {
86 if (StringUtils.isNotEmpty(getVersion())) {
87 try {
88 thisState = thisState.getVersionedContent(getVersion());
89 } catch (RepositoryException re) {
90 log.error("Failed to get version "+getVersion()+" for "+thisState.getHandle(), re);
91 }
92 }
93 success = activateUpdate(ctx, originalState);
94 } else {
95 success = activateBulkUpdate(ctx, getNode(ctx));
96 }
97 }
98 catch (Exception e) {
99 log.error("can't activate", e);
100 AlertUtil.setException(MessagesManager.get("tree.error.activate"), e, ctx);
101 }
102 return success;
103 }
104
105 private boolean activateUpdate(Context ctx, Content thisState) throws ExchangeException, RepositoryException {
106 boolean success;
107 String parentPath = StringUtils.substringBeforeLast(thisState.getHandle(), "/");
108 if (StringUtils.isEmpty(parentPath)) {
109 parentPath = "/";
110 }
111 log.debug("Activate content {} as a child of {}", new Object[] {thisState.getName(), parentPath});
112
113 List orderInfo = getOrderingInfo(thisState);
114 if (StringUtils.isNotEmpty(getVersion())) {
115 try {
116 thisState = thisState.getVersionedContent(getVersion());
117 } catch (RepositoryException re) {
118
119 log.error("Failed to get version "+getVersion()+" for "+thisState.getHandle() + ". Activating current content instead.", re);
120 }
121 }
122 getSyndicator().activate(parentPath, thisState, orderInfo);
123 log.debug("exec successfully.");
124 success = true;
125 return success;
126 }
127
128 private boolean activateBulkUpdate(Context ctx, Content thisState) throws ExchangeException, RepositoryException {
129 boolean success;
130
131 List versionMap = getVersionMap();
132 if (versionMap == null) {
133 String parentPath = StringUtils.substringBeforeLast(thisState.getHandle(), "/");
134 if (StringUtils.isEmpty(parentPath)) {
135 parentPath = "/";
136 }
137 log.debug("Activate content {} as a child of {}", new Object[] {thisState.getName(), parentPath});
138 activateRecursive(parentPath, thisState, ctx);
139 } else {
140 activateRecursive(ctx, versionMap);
141 }
142 log.debug("exec successfully.");
143 success = true;
144 return success;
145 }
146
147
148
149
150
151
152
153
154 protected void activateRecursive(String parentPath, Content node, Context ctx)
155 throws ExchangeException, RepositoryException {
156
157 getSyndicator().activate(parentPath, node, getOrderingInfo(node));
158
159 Collection children = node.getChildren(new Content.ContentFilter() {
160 public boolean accept(Content content) {
161 try {
162 return !getRule().isAllowed(content.getNodeTypeName());
163 }
164 catch (RepositoryException e) {
165 log.error("can't get nodetype", e);
166 return false;
167 }
168 }
169 });
170
171
172
173
174 Content[] childArray = (Content[]) children.toArray(new Content[children.size()]);
175 for (int i = childArray.length - 1; i >=0; i--) {
176 this.activateRecursive(node.getHandle(), childArray[i], ctx);
177 }
178 }
179
180
181
182
183
184 protected void activateRecursive(Context ctx, List versionMap)
185 throws ExchangeException, RepositoryException {
186
187 Map<String, Object>[] versions = (Map<String, Object>[]) versionMap.toArray(new Map[0]);
188
189 for (int i = 0; i < versions.length; i++) {
190 Map<String, Object> entry = versions[i];
191 String uuid = (String) entry.get("uuid");
192 if (StringUtils.equalsIgnoreCase("class", uuid)) {
193
194
195 versionMap.remove(entry);
196 }
197 try {
198 Content content = ctx.getHierarchyManager(getRepository()).getContentByUUID(uuid);
199 entry.put("handle", content.getHandle());
200 entry.put("index", i);
201 } catch (RepositoryException re) {
202 log.error("Failed to activate node with UUID : "+uuid);
203 log.error(re.getMessage());
204 versionMap.remove(entry);
205 }
206 }
207 versions = null;
208
209
210 Collections.sort((List<Map<String, Object>>) versionMap, new Comparator<Map<String, Object>>() {
211
212 public int compare(Map<String, Object> o1, Map<String, Object> o2) {
213 String handle1 = (String) o1.get("handle");
214 String handle2 = (String) o2.get("handle");
215 if (handle2.startsWith(handle1)) {
216
217 return -1;
218 }
219 String parent1 = StringUtils.substringBeforeLast(handle1, "/");
220 String parent2 = StringUtils.substringBeforeLast(handle2, "/");
221 if (parent1.equals(parent2)) {
222
223 int idx1 = (Integer) o1.get("index");
224 int idx2 = (Integer) o2.get("index");
225
226 return idx1 < idx2 ? 1 : -1;
227 }
228
229
230 int dirLevels1 = StringUtils.countMatches(handle1, "/");
231 int dirLevels2 = StringUtils.countMatches(handle2, "/");
232
233 return dirLevels1 < dirLevels2 ? -1 : 1;
234 }});
235
236
237
238
239 for (Map entry : (List<Map>) versionMap) {
240
241 String uuid = (String) entry.get("uuid");
242 String versionNumber = (String) entry.get("version");
243 if (StringUtils.equalsIgnoreCase("class", uuid)) {
244
245
246 continue;
247 }
248 try {
249 Content content = ctx.getHierarchyManager(getRepository()).getContentByUUID(uuid);
250
251
252 List orderedList = getOrderingInfo(content);
253 String parentPath = content.getParent().getHandle();
254 content = content.getVersionedContent(versionNumber);
255
256 getSyndicator().activate(parentPath, content, orderedList);
257 } catch (RepositoryException re) {
258 log.error("Failed to activate node with UUID : "+uuid);
259 log.error(re.getMessage());
260 }
261 }
262 }
263
264
265
266
267
268
269 protected List getOrderingInfo(Content node) {
270
271
272 List siblings = new ArrayList();
273 Node thisNode = node.getJCRNode();
274 try {
275 String thisNodeType = node.getNodeTypeName();
276 String thisNodeUUID = node.getUUID();
277 NodeIterator nodeIterator = thisNode.getParent().getNodes();
278 while (nodeIterator.hasNext()) {
279 Node sibling = nodeIterator.nextNode();
280
281 if (sibling.isNodeType(thisNodeType)) {
282 if (thisNodeUUID.equalsIgnoreCase(sibling.getUUID())) break;
283 }
284 }
285 while (nodeIterator.hasNext()) {
286 Node sibling = nodeIterator.nextNode();
287 if (sibling.isNodeType(thisNodeType)) {
288 siblings.add(sibling.getUUID());
289 }
290 }
291 } catch (RepositoryException re) {
292
293 log.error("Failed to get Ordering info", re);
294 }
295 return siblings;
296 }
297
298
299
300
301 public boolean isRecursive() {
302 return recursive;
303 }
304
305
306
307
308 public void setRecursive(boolean recursive) {
309 this.recursive = recursive;
310 }
311
312
313
314
315 public void setVersion(String number) {
316 this.versionNumber = number;
317 }
318
319
320
321
322 public String getVersion() {
323 return this.versionNumber;
324 }
325
326
327
328
329 public void setVersionMap(List versionMap) {
330 this.versionMap = versionMap;
331 }
332
333
334
335
336 public List getVersionMap() {
337 return this.versionMap;
338 }
339
340 @Override
341 public void release() {
342 super.release();
343 this.versionMap = null;
344 this.recursive = false;
345 this.versionNumber = null;
346 }
347
348 }