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.ui.contentapp.setup.for5_3;
35
36 import info.magnolia.cms.core.Path;
37 import info.magnolia.jcr.util.NodeTypes;
38 import info.magnolia.jcr.util.NodeUtil;
39 import info.magnolia.module.InstallContext;
40 import info.magnolia.module.delta.NodeVisitorTask;
41 import info.magnolia.repository.RepositoryConstants;
42 import info.magnolia.ui.api.action.ActionDefinition;
43 import info.magnolia.ui.contentapp.detail.action.EditItemActionDefinition;
44 import info.magnolia.ui.contentapp.detail.action.RestorePreviousVersionActionDefinition;
45
46 import java.util.ArrayList;
47 import java.util.Arrays;
48 import java.util.Iterator;
49 import java.util.List;
50
51 import javax.inject.Inject;
52 import javax.jcr.Node;
53 import javax.jcr.Property;
54 import javax.jcr.RepositoryException;
55
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58
59
60
61
62
63
64
65
66 public class MoveActionNodeTypeRestrictionToAvailabilityTask extends NodeVisitorTask {
67
68 private static final Logger log = LoggerFactory.getLogger(MoveActionNodeTypeRestrictionToAvailabilityTask.class);
69
70 public static final String NODE_TYPE = "nodeType";
71 public static final String AVAILABILITY_NODE = "availability";
72 public static final String NODE_TYPES = "nodeTypes";
73
74
75
76
77
78
79 private static Class<?>[] commonActionDefinitionClasses = new Class[] {
80 EditItemActionDefinition.class,
81 RestorePreviousVersionActionDefinition.class,
82 };
83
84 private final List<Class<?>> matchingActionDefinitionClasses = new ArrayList<Class<?>>();
85
86 @Inject
87 public MoveActionNodeTypeRestrictionToAvailabilityTask(String path, Class<? extends ActionDefinition>... additionalActionDefinitionClasses) {
88 super(
89 "Move nodeType property to availability definition",
90 "Fix availability checking of actions defined with AbstractItemActionDefinition sub-class by moving the nodeType property from action definition to availability.",
91 RepositoryConstants.CONFIG, path);
92
93 matchingActionDefinitionClasses.addAll(Arrays.asList(commonActionDefinitionClasses));
94 matchingActionDefinitionClasses.addAll(Arrays.asList(additionalActionDefinitionClasses));
95 }
96
97 @Override
98 protected boolean nodeMatches(Node node) {
99 try {
100 return node.getPrimaryNodeType().getName().equals(NodeTypes.ContentNode.NAME) &&
101 (node.hasProperty("class") && containsDefinitionClass(node.getProperty("class").getString()));
102 } catch (RepositoryException e) {
103 log.error("Couldn't evaluate visited node's type or class property", e);
104 }
105 return false;
106 }
107
108 private boolean containsDefinitionClass(String className) {
109 Iterator<Class<?>> it = matchingActionDefinitionClasses.iterator();
110 while (it.hasNext()) {
111 if (className.equals(it.next().getName())) {
112 return true;
113 }
114 }
115 return false;
116 }
117
118 @Override
119 protected void operateOnNode(InstallContext installContext, Node node) {
120 try {
121 if (node.hasProperty(NODE_TYPE)) {
122 final Property nodeTypeProperty = node.getProperty(NODE_TYPE);
123
124 final Node availability = NodeUtil.createPath(node, AVAILABILITY_NODE, NodeTypes.ContentNode.NAME, true);
125 final Node nodeTypes = NodeUtil.createPath(availability, NODE_TYPES, NodeTypes.ContentNode.NAME, true);
126
127 final String nodeType = nodeTypeProperty.getString();
128 nodeTypes.setProperty(Path.getValidatedLabel(nodeType), nodeType);
129
130 nodeTypeProperty.remove();
131 }
132 } catch (RepositoryException e) {
133 log.error("Failed to move nodeType property to action availability for node {0} due to: {1}", node, e.getMessage());
134 }
135 }
136 }