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.resources.app.action;
35
36 import static java.util.stream.Collectors.toList;
37
38 import info.magnolia.commands.CommandsManager;
39 import info.magnolia.context.Context;
40 import info.magnolia.jcr.util.NodeTypes;
41 import info.magnolia.jcr.util.NodeUtil;
42 import info.magnolia.resourceloader.Resource;
43 import info.magnolia.ui.ValueContext;
44 import info.magnolia.ui.contentapp.async.AsyncActionExecutor;
45 import info.magnolia.ui.observation.DatasourceObservation;
46
47 import java.util.ArrayList;
48 import java.util.Collections;
49 import java.util.List;
50
51 import javax.inject.Inject;
52
53 import com.machinezoo.noexception.Exceptions;
54
55
56
57
58
59 public class PublishResourceCommandAction extends ResourceCommandAction<PublishResourceCommandActionDefinition> {
60
61 @Inject
62 public PublishResourceCommandAction(PublishResourceCommandActionDefinition definition, CommandsManager commandsManager,
63 ValueContext<Resource> valueContext, Context context, AsyncActionExecutor asyncActionExecutor, DatasourceObservation.Manual datasourceObservation
64 ) {
65 super(definition, commandsManager, valueContext, context, asyncActionExecutor, datasourceObservation);
66 }
67
68 @Override
69 public void execute() {
70 for (Resource resource : getValueContext().get().collect(toList())) {
71 if (getDefinition().isDeletion()) {
72 getValueContext().set(getRootForDeletion(resource));
73 super.execute();
74 } else {
75 for (Resource r : createPublishingChain(resource)) {
76 getValueContext().set(r);
77 super.execute();
78 }
79 }
80 }
81 }
82
83 private List<Resource> createPublishingChain(Resource resource) {
84 final List<Resource> resources = new ArrayList<>();
85 while (!"/".equals(resource.getPath())) {
86 if (isNotActivated(resource)) {
87 resources.add(resource);
88 }
89 resource = resource.getParent();
90 }
91 Collections.reverse(resources);
92 return resources;
93 }
94
95 private boolean isNotActivated(Resource resource) {
96 return !getJcrNode(resource)
97 .map((Exceptions.wrap().function(NodeTypes.Activatable::getActivationStatus)))
98 .map(status -> status == NodeTypes.Activatable.ACTIVATION_STATUS_ACTIVATED)
99 .orElse(true);
100 }
101
102 private Resource getRootForDeletion(Resource resource) {
103 Resource root = resource;
104 while (!"/".equals(resource.getPath()) && isMarkedAsDeleted(resource)) {
105 root = resource;
106 resource = resource.getParent();
107 }
108 return root;
109 }
110
111 private boolean isMarkedAsDeleted(Resource resource) {
112 return getJcrNode(resource)
113 .map(node -> Exceptions.wrap().get(() -> NodeUtil.hasMixin(node, NodeTypes.Deleted.NAME)))
114 .orElse(false);
115 }
116 }