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.dialog.action;
35
36 import info.magnolia.cms.beans.runtime.FileProperties;
37 import info.magnolia.commands.CommandsManager;
38 import info.magnolia.commands.chain.Command;
39 import info.magnolia.commands.impl.ImportCommand;
40 import info.magnolia.event.EventBus;
41 import info.magnolia.jcr.util.NodeUtil;
42 import info.magnolia.ui.api.action.AbstractAction;
43 import info.magnolia.ui.api.action.ActionExecutionException;
44 import info.magnolia.ui.api.event.AdmincentralEventBus;
45 import info.magnolia.ui.api.event.ContentChangedEvent;
46 import info.magnolia.ui.form.EditorCallback;
47 import info.magnolia.ui.form.EditorValidator;
48 import info.magnolia.ui.vaadin.integration.jcr.JcrNodeAdapter;
49 import info.magnolia.ui.vaadin.integration.jcr.JcrNodeItemId;
50
51 import java.util.HashMap;
52 import java.util.HashSet;
53 import java.util.List;
54 import java.util.Map;
55 import java.util.Set;
56
57 import javax.inject.Inject;
58 import javax.inject.Named;
59 import javax.jcr.ImportUUIDBehavior;
60 import javax.jcr.Node;
61 import javax.jcr.RepositoryException;
62
63 import org.apache.jackrabbit.JcrConstants;
64 import org.apache.jackrabbit.value.BinaryImpl;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
67
68 import com.vaadin.data.Item;
69 import com.vaadin.data.Property;
70
71
72
73
74 public class SaveImportDialogAction extends AbstractAction<SaveImportDialogActionDefinition> {
75
76 private static final Logger log = LoggerFactory.getLogger(SaveImportDialogAction.class);
77
78 private final Item item;
79 private final CommandsManager commandsManager;
80 private final EditorValidator validator;
81 private final EditorCallback callback;
82 private final EventBus eventBus;
83
84 private Map<String, Object> params;
85
86 @Inject
87 public SaveImportDialogAction(SaveImportDialogActionDefinition definition, Item item, CommandsManager commandsManager, EditorValidator validator, EditorCallback callback, @Named(AdmincentralEventBus.NAME) EventBus eventBus) {
88 super(definition);
89 this.item = item;
90 this.commandsManager = commandsManager;
91 this.validator = validator;
92 this.callback = callback;
93 this.eventBus = eventBus;
94 }
95
96
97
98
99 @Deprecated
100 public SaveImportDialogAction(SaveImportDialogActionDefinition definition, Item item, CommandsManager commandsManager, EditorValidator validator, EditorCallback callback) {
101 this(definition, item, commandsManager, validator, callback, null);
102 }
103
104 @Override
105 public void execute() throws ActionExecutionException {
106
107 validator.showValidation(true);
108 if (validator.isValid()) {
109 try {
110 JcrNodeAdapter parent = (JcrNodeAdapter) item;
111 JcrNodeAdapter importXml = (JcrNodeAdapter) parent.getChild("import");
112 if (importXml == null) {
113 throw new IllegalArgumentException("Nothing to import, given item does not contain any child named 'import'.");
114 }
115
116 if (eventBus != null) {
117 List<Node> nodesBeforeImport = NodeUtil.asList(NodeUtil.asIterable(parent.getJcrItem().getNodes()));
118 executeCommand(parent);
119
120 List<Node> nodesAfterImport = NodeUtil.asList(NodeUtil.asIterable(parent.getJcrItem().getNodes()));
121 Set<JcrNodeItemId> importedNodeItemIds = getImportedNodeItemIds(nodesBeforeImport, nodesAfterImport);
122
123
124
125
126
127
128
129
130 eventBus.fireEvent(new ContentChangedEvent(importedNodeItemIds));
131 callback.onCancel();
132
133 } else {
134 executeCommand(parent);
135 callback.onSuccess(getDefinition().getName());
136 }
137
138 } catch (RepositoryException e) {
139 throw new ActionExecutionException(e);
140 }
141 } else {
142 log.info("Validation error(s) occurred. No Import performed.");
143 }
144 }
145
146 private Set<JcrNodeItemId> getImportedNodeItemIds(List<Node> nodesBeforeImport, List<Node> nodesAfterImport) throws RepositoryException {
147 Set<JcrNodeItemId> importedNodeItemIds = new HashSet<>();
148 for (Node nodeAfterImport : nodesAfterImport) {
149 boolean existedBeforeImport = false;
150 for (Node nodeBeforeImport : nodesBeforeImport) {
151 if (NodeUtil.isSame(nodeAfterImport, nodeBeforeImport)) {
152 existedBeforeImport = true;
153 break;
154 }
155 }
156 if (!existedBeforeImport) {
157 importedNodeItemIds.add(new JcrNodeItemId(nodeAfterImport.getIdentifier(), nodeAfterImport.getSession().getWorkspace().getName()));
158 }
159 }
160 return importedNodeItemIds;
161 }
162
163 public final void executeCommand(JcrNodeAdapter itemChanged) throws ActionExecutionException {
164
165 String commandName = getDefinition().getCommand();
166 String catalog = getDefinition().getCatalog();
167 Command command = this.commandsManager.getCommand(catalog, commandName);
168
169 if (command == null) {
170 throw new ActionExecutionException(String.format("Could not find command [%s] in any catalog", commandName));
171 }
172
173 long start = System.currentTimeMillis();
174 try {
175
176 setParams(itemChanged);
177 log.debug("Executing command [{}] from catalog [{}] with the following parameters [{}]...", new Object[] { commandName, catalog, params });
178 commandsManager.executeCommand(command, params);
179 log.debug("Command executed successfully in {} ms ", System.currentTimeMillis() - start);
180 } catch (Exception e) {
181 log.debug("Command execution failed after {} ms ", System.currentTimeMillis() - start);
182 throw new ActionExecutionException(e);
183 }
184 }
185
186 private void setParams(JcrNodeAdapter itemChanged) throws RepositoryException {
187 params = new HashMap<>();
188 JcrNodeAdapter importXml = (JcrNodeAdapter) itemChanged.getChild("import");
189
190 params.put(ImportCommand.IMPORT_XML_STREAM, ((Property<BinaryImpl>) importXml.getItemProperty(JcrConstants.JCR_DATA)).getValue().getStream());
191 params.put(ImportCommand.IMPORT_IDENTIFIER_BEHAVIOR, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
192 params.put(ImportCommand.IMPORT_XML_FILE_NAME, importXml.getItemProperty(FileProperties.PROPERTY_FILENAME).getValue());
193 params.put("repository", itemChanged.getWorkspace());
194 params.put("path", itemChanged.getJcrItem().getPath());
195 }
196 }