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.pages.app.detail.action;
35
36 import info.magnolia.config.registry.DefinitionProvider;
37 import info.magnolia.context.Context;
38 import info.magnolia.i18nsystem.I18nizer;
39 import info.magnolia.jcr.util.NodeNameHelper;
40 import info.magnolia.jcr.util.NodeTypes;
41 import info.magnolia.jcr.util.NodeUtil;
42 import info.magnolia.jcr.wrapper.DelegateNodeWrapper;
43 import info.magnolia.pages.app.detail.PageEditorStatus;
44 import info.magnolia.rendering.template.TemplateDefinition;
45 import info.magnolia.rendering.template.registry.TemplateDefinitionRegistry;
46 import info.magnolia.ui.CloseHandler;
47 import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
48 import info.magnolia.ui.dialog.DialogDefinitionRegistry;
49 import info.magnolia.ui.editor.LocaleContext;
50 import info.magnolia.ui.datasource.optionlist.Option;
51 import info.magnolia.ui.UIComponent;
52 import info.magnolia.ui.ValueContext;
53 import info.magnolia.ui.editor.FormView;
54 import info.magnolia.ui.observation.DatasourceObservation;
55 import info.magnolia.ui.vaadin.gwt.client.shared.AbstractElement;
56 import info.magnolia.ui.vaadin.gwt.client.shared.ComponentElement;
57
58 import java.util.Optional;
59
60 import javax.inject.Inject;
61 import javax.jcr.Node;
62 import javax.jcr.Session;
63
64 import com.machinezoo.noexception.Exceptions;
65 import com.vaadin.data.BinderValidationStatus;
66 import com.vaadin.ui.Window;
67
68
69
70
71
72 public class CreateComponentAction extends EditElementAction {
73
74 static final String NEW_COMPONENT_POSITION = "mgnl:position";
75
76
77
78 static final String COMPONENT_POSITION_TOP = "top";
79
80 private AbstractElement parentElement;
81
82 private final NodeNameHelper nodeNameHelper;
83 private final FormView<Node> formView;
84 private final TemplateDefinitionRegistry templateDefinitionRegistry;
85 private final DatasourceObservation.Manual datasourceObservation;
86 private final CloseHandler closeHandler;
87
88 @Inject
89 public CreateComponentAction(CreateComponentActionDefinition definition, UIComponent parentView, LocaleContext localeContext, I18NAuthoringSupport i18NAuthoringSupport, DialogDefinitionRegistry dialogDefinitionRegistry, I18nizer i18nizer, Context context, ValueContext<Node> valueContext, PageEditorStatus pageEditorStatus, NodeNameHelper nodeNameHelper, FormView<Node> formView, TemplateDefinitionRegistry templateDefinitionRegistry, DatasourceObservation.Manual datasourceObservation, CloseHandler closeHandler) {
90 super(definition, parentView, localeContext, i18NAuthoringSupport, dialogDefinitionRegistry, i18nizer, context, valueContext, pageEditorStatus);
91 this.nodeNameHelper = nodeNameHelper;
92 this.formView = formView;
93 this.templateDefinitionRegistry = templateDefinitionRegistry;
94 this.datasourceObservation = datasourceObservation;
95 this.closeHandler = closeHandler;
96 }
97
98 @Override
99 public void execute() {
100 if (formView.validate().stream().allMatch(BinderValidationStatus::isOk)) {
101 Exceptions.wrap().run(() -> {
102 super.execute();
103 final Node parent = getValueContext().getSingleOrThrow();
104 final Session session = parent.getSession();
105 final Node component = parent.addNode(nodeNameHelper.getUniqueName(parent, "0"), NodeTypes.Component.NAME);
106 final Optional<String> dialog = formView.<String>getPropertyValue(NodeTypes.Renderable.TEMPLATE)
107 .map(templateDefinitionRegistry::getProvider)
108 .map(DefinitionProvider::get)
109 .map(TemplateDefinition::getDialog);
110
111 this.parentElement = getPageEditorStatus().getSelectedElement();
112 getPageEditorStatus().setSelectedElement(new ComponentElement(session.getWorkspace().getName(), component.getPath(), dialog.orElse(null)));
113 getValueContext().set(new NewComponentWrapper(component));
114 closeHandler.close();
115
116 if (!dialog.isPresent()) {
117 session.save();
118 datasourceObservation.trigger();
119 } else {
120 super.execute();
121 }
122 });
123 }
124 }
125
126 @Override
127 protected CloseHandler getCloseHandler(Window dialog) {
128 return () -> {
129
130 getValueContext().getSingle()
131 .filter(Node::isNew)
132 .ifPresent(any -> getPageEditorStatus().setSelectedElement(parentElement));
133
134 dialog.close();
135 };
136 }
137
138 private class NewComponentWrapper extends DelegateNodeWrapper {
139
140 private NewComponentWrapper(Node parent) {
141 super(parent);
142 }
143
144 @Override
145 public Node getWrappedNode() {
146 final Node wrappedNode = super.getWrappedNode();
147 if (Exceptions.wrap().get(() -> NodeTypes.Renderable.getTemplate(wrappedNode) == null)) {
148 Exceptions.wrap().run(() -> NodeTypes.Renderable.set(wrappedNode, formView.<String>getPropertyValue(NodeTypes.Renderable.TEMPLATE).orElseThrow(IllegalArgumentException::new)));
149
150 formView.<Option>getPropertyValue(NEW_COMPONENT_POSITION)
151 .map(Option::getValue)
152 .filter(COMPONENT_POSITION_TOP::equals)
153 .ifPresent(Exceptions.wrap().consumer(any -> NodeUtil.orderFirst(wrappedNode)));
154 }
155 return wrappedNode;
156 }
157 }
158 }