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.resources.setup;
35
36 import info.magnolia.jcr.RuntimeRepositoryException;
37 import info.magnolia.jcr.predicate.AbstractPredicate;
38 import info.magnolia.jcr.util.NodeTypes;
39 import info.magnolia.jcr.util.NodeUtil;
40 import info.magnolia.jcr.util.PropertyUtil;
41 import info.magnolia.module.InstallContext;
42 import info.magnolia.module.delta.AbstractRepositoryTask;
43 import info.magnolia.module.delta.TaskExecutionException;
44 import info.magnolia.resourceloader.jcr.JcrResourceOrigin;
45
46 import java.util.HashMap;
47 import java.util.Iterator;
48 import java.util.Map;
49
50 import javax.jcr.Node;
51 import javax.jcr.RepositoryException;
52 import javax.jcr.Session;
53
54 import org.apache.commons.lang3.StringUtils;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57
58 import com.google.common.collect.ArrayListMultimap;
59 import com.google.common.collect.ListMultimap;
60
61
62
63
64
65
66
67
68
69
70 public class UpdateResourceReferencesTask extends AbstractRepositoryTask {
71
72 private static final Logger log = LoggerFactory.getLogger(UpdateResourceReferencesTask.class);
73
74 private final String[] workspaces;
75
76 private Map<String, String> changedPaths = new HashMap<>();
77
78 public UpdateResourceReferencesTask(String name, String description, String... workspaces) {
79 super(name, description);
80 this.workspaces = workspaces;
81 }
82
83 public UpdateResourceReferencesTask(String name) {
84 this(name, String.format("Update 'reference' property for resource with template 'resource:reference' in workspace '%s'", JcrResourceOrigin.RESOURCES_WORKSPACE), JcrResourceOrigin.RESOURCES_WORKSPACE);
85 }
86
87 public void setChangedPaths(Map<String, String> changedPaths) {
88 this.changedPaths = changedPaths;
89 }
90
91 @Override
92 protected void doExecute(InstallContext installContext) throws RepositoryException, TaskExecutionException {
93 if (workspaces != null) {
94 final ListMultimap<UpdateResourceMessage, String[]> messages = ArrayListMultimap.create();
95
96 for (String workspace : workspaces) {
97 try {
98 Session workspaceSession = installContext.getJCRSession(workspace);
99
100 final Iterator<Node> nodeIterator = NodeUtil.collectAllChildren(workspaceSession.getRootNode(), new JCRResourceReferencesPredicate()).iterator();
101
102
103 while (nodeIterator.hasNext()) {
104 Node resource = nodeIterator.next();
105 String referencePath = PropertyUtil.getString(resource, ResourceCleanUpTask.PROPERTY_REFERENCE);
106 if (changedPaths.containsKey(referencePath)) {
107 resource.setProperty(ResourceCleanUpTask.PROPERTY_REFERENCE, changedPaths.get(referencePath));
108 messages.put(UpdateResourceMessage.REFERENCE_UPDATED, new String[] { resource.getPath(), referencePath, changedPaths.get(referencePath) });
109 }
110 }
111 } catch (RepositoryException e) {
112 messages.put(UpdateResourceMessage.CANNOT_GET_SESSION, new String[] { workspace });
113 }
114 }
115
116 UpdateResourceMessage.logMessages(installContext, log, messages);
117 }
118 }
119
120
121
122
123 protected class JCRResourceReferencesPredicate extends AbstractPredicate<Node> {
124
125 @Override
126 public boolean evaluateTyped(Node resource) {
127 try {
128 return NodeUtil.isNodeType(resource, NodeTypes.Content.NAME)
129 && resource.hasProperty(ResourceCleanUpTask.PROPERTY_TEMPLATE)
130 && resource.hasProperty(ResourceCleanUpTask.PROPERTY_REFERENCE)
131 && StringUtils.equals(ResourceCleanUpTask.REFERENCES_RESOURCES_TEMPLATE, PropertyUtil.getString(resource, ResourceCleanUpTask.PROPERTY_TEMPLATE));
132 } catch (RepositoryException e) {
133 throw new RuntimeRepositoryException(e);
134 }
135 }
136 }
137
138 }