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.framework.action;
35
36 import info.magnolia.ui.api.action.AbstractAction;
37 import info.magnolia.ui.api.action.ActionDefinition;
38 import info.magnolia.ui.api.action.ActionExecutionException;
39 import info.magnolia.ui.api.context.UiContext;
40 import info.magnolia.ui.vaadin.integration.jcr.JcrItemAdapter;
41 import info.magnolia.ui.vaadin.integration.jcr.JcrItemUtil;
42 import info.magnolia.ui.vaadin.overlay.MessageStyleTypeEnum;
43
44 import java.util.Comparator;
45 import java.util.LinkedHashMap;
46 import java.util.List;
47 import java.util.Map;
48
49 import javax.jcr.RepositoryException;
50
51 import org.apache.commons.lang3.StringUtils;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 import com.google.common.collect.Lists;
56 import com.google.common.collect.Ordering;
57
58
59
60
61
62
63 public abstract class AbstractMultiItemAction<D extends ActionDefinition> extends AbstractAction<D> {
64
65 private final Logger log = LoggerFactory.getLogger(getClass());
66
67 private final List<JcrItemAdapter> items;
68 private Map<JcrItemAdapter, Exception> failedItems;
69 private final UiContext uiContext;
70
71 private JcrItemAdapter currentItem;
72
73 protected AbstractMultiItemAction(D definition, JcrItemAdapter item, UiContext uiContext) {
74 this(definition, Lists.newArrayList(item), uiContext);
75 }
76
77 protected AbstractMultiItemAction(D definition, List<JcrItemAdapter> items, UiContext uiContext) {
78 super(definition);
79 this.items = items;
80 this.uiContext = uiContext;
81 }
82
83
84
85
86 protected abstract void executeOnItem(JcrItemAdapter item) throws Exception;
87
88
89
90
91
92 protected abstract String getSuccessMessage();
93
94
95
96
97
98 protected abstract String getFailureMessage();
99
100 @Override
101 public void execute() throws ActionExecutionException {
102 failedItems = new LinkedHashMap<JcrItemAdapter, Exception>();
103
104 for (JcrItemAdapter item : getSortedItems(getItemComparator())) {
105 this.currentItem = item;
106 try {
107 executeOnItem(item);
108 } catch (Exception ex) {
109 failedItems.put(item, ex);
110 }
111 }
112 this.currentItem = null;
113
114 if (failedItems.isEmpty()) {
115 String message = getSuccessMessage();
116 if (StringUtils.isNotBlank(message)) {
117 uiContext.openNotification(MessageStyleTypeEnum.INFO, true, message);
118 }
119 } else {
120 String message = getErrorNotification();
121 if (StringUtils.isNotBlank(message)) {
122 uiContext.openNotification(MessageStyleTypeEnum.ERROR, false, message);
123 }
124 }
125 }
126
127 protected String getErrorNotification() {
128 String failureMessage = getFailureMessage();
129 if (failureMessage != null) {
130 StringBuilder notification = new StringBuilder(failureMessage);
131 notification.append("<ul>");
132 for (JcrItemAdapter item : failedItems.keySet()) {
133 Exception ex = failedItems.get(item);
134 notification.append("<li>").append("<b>");
135 notification.append(JcrItemUtil.getItemPath(item.getJcrItem())).append("</b>: ").append(ex.getMessage());
136 notification.append("</li>");
137 }
138 notification.append("</ul>");
139 return notification.toString();
140 }
141 return null;
142 }
143
144 protected List<JcrItemAdapter> getItems() {
145 return this.items;
146 }
147
148
149
150
151 protected List<JcrItemAdapter> getSortedItems(Comparator<JcrItemAdapter> comparator) {
152 return Ordering.from(comparator).sortedCopy(this.items);
153 }
154
155 protected UiContext getUiContext() {
156 return this.uiContext;
157 }
158
159 protected Map<JcrItemAdapter, Exception> getFailedItems() {
160 return this.failedItems;
161 }
162
163
164
165
166 protected JcrItemAdapter getCurrentItem() {
167 return this.currentItem;
168 }
169
170
171
172
173 protected void setCurrentItem(JcrItemAdapter item) {
174 this.currentItem = item;
175 }
176
177
178
179
180
181
182
183
184
185 protected Comparator<JcrItemAdapter> getItemComparator() {
186 return new Comparator<JcrItemAdapter>() {
187 @Override
188 public int compare(JcrItemAdapter o1, JcrItemAdapter o2) {
189 try {
190 int res = o2.getJcrItem().getDepth() - o1.getJcrItem().getDepth();
191 return res;
192 } catch (RepositoryException e) {
193 return 0;
194 }
195 }
196 };
197 }
198 }