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.action;
35
36 import info.magnolia.config.registry.DefinitionProvider;
37 import info.magnolia.config.registry.Registry;
38 import info.magnolia.context.Context;
39 import info.magnolia.context.MgnlContext;
40 import info.magnolia.event.EventBus;
41 import info.magnolia.i18nsystem.SimpleTranslator;
42 import info.magnolia.jcr.util.NodeTypes;
43 import info.magnolia.jcr.util.NodeUtil;
44 import info.magnolia.objectfactory.ComponentProvider;
45 import info.magnolia.rendering.template.TemplateDefinition;
46 import info.magnolia.rendering.template.registry.TemplateDefinitionRegistry;
47 import info.magnolia.ui.api.action.AbstractAction;
48 import info.magnolia.ui.api.action.ActionExecutionException;
49 import info.magnolia.ui.api.app.SubAppContext;
50 import info.magnolia.ui.api.app.SubAppEventBus;
51 import info.magnolia.ui.api.event.ContentChangedEvent;
52 import info.magnolia.ui.dialog.formdialog.FormDialogPresenter;
53 import info.magnolia.ui.dialog.formdialog.FormDialogPresenterFactory;
54 import info.magnolia.ui.form.EditorCallback;
55 import info.magnolia.ui.vaadin.gwt.client.shared.AreaElement;
56 import info.magnolia.ui.vaadin.integration.jcr.DefaultProperty;
57 import info.magnolia.ui.vaadin.integration.jcr.JcrNewNodeAdapter;
58 import info.magnolia.ui.vaadin.integration.jcr.JcrNodeAdapter;
59 import info.magnolia.ui.vaadin.integration.jcr.ModelConstants;
60
61 import javax.inject.Inject;
62 import javax.inject.Named;
63 import javax.jcr.Node;
64 import javax.jcr.RepositoryException;
65 import javax.jcr.Session;
66
67 import org.apache.commons.lang3.StringUtils;
68 import org.slf4j.Logger;
69 import org.slf4j.LoggerFactory;
70
71 import com.vaadin.data.Property;
72
73
74
75
76
77 public class CreateComponentAction extends AbstractAction<CreateComponentActionDefinition> {
78
79 private static final Logger log = LoggerFactory.getLogger(CreateComponentAction.class);
80
81 protected static final String NEW_COMPONENT_DIALOG = "pages:newComponent";
82 protected static final String NEW_COMPONENT_POSITION = "mgnl-position";
83
84
85
86 protected static final String COMPONENT_POSITION_TOP = "top";
87 protected static final String COMPONENT_POSITION_BOTTOM = "bottom";
88
89 private final AreaElement area;
90 private final EventBus eventBus;
91 private final TemplateDefinitionRegistry templateDefinitionRegistry;
92 private final SubAppContext subAppContext;
93 private final FormDialogPresenterFactory formDialogPresenterFactory;
94 private final Context ctx;
95
96 protected String newComponentPosition = COMPONENT_POSITION_BOTTOM;
97
98 @Inject
99 public CreateComponentAction(CreateComponentActionDefinition definition, AreaElement area, @Named(SubAppEventBus.NAME) EventBus eventBus, TemplateDefinitionRegistry templateDefinitionRegistry,
100 SubAppContext subAppContext, FormDialogPresenterFactory formDialogPresenterFactory, Context ctx) {
101 super(definition);
102 this.area = area;
103 this.eventBus = eventBus;
104 this.templateDefinitionRegistry = templateDefinitionRegistry;
105 this.subAppContext = subAppContext;
106 this.formDialogPresenterFactory = formDialogPresenterFactory;
107 this.ctx = ctx;
108 }
109
110
111
112
113 @Deprecated
114 public CreateComponentAction(CreateComponentActionDefinition definition, AreaElement area, @Named(SubAppEventBus.NAME) EventBus eventBus, TemplateDefinitionRegistry templateDefinitionRegistry,
115 SubAppContext subAppContext, ComponentProvider componentProvider, FormDialogPresenterFactory formDialogPresenterFactory) {
116 this(definition, area, eventBus, templateDefinitionRegistry, subAppContext, formDialogPresenterFactory, MgnlContext.getInstance());
117 }
118
119
120
121
122
123 @Deprecated
124 public CreateComponentAction(CreateComponentActionDefinition definition, AreaElement area, @Named(SubAppEventBus.NAME) EventBus eventBus, TemplateDefinitionRegistry templateDefinitionRegistry,
125 SubAppContext subAppContext, ComponentProvider componentProvider, FormDialogPresenterFactory formDialogPresenterFactory, SimpleTranslator i18n) {
126 this(definition, area, eventBus, templateDefinitionRegistry, subAppContext, formDialogPresenterFactory, MgnlContext.getInstance());
127 }
128
129 @Override
130 public void execute() throws ActionExecutionException {
131 String workspace = area.getWorkspace();
132 String path = area.getPath();
133
134 try {
135 Session session = ctx.getJCRSession(workspace);
136 if (path == null || !session.itemExists(path)) {
137 path = "/";
138 }
139
140 if (StringUtils.isNotBlank(area.getAvailableComponents())) {
141 Node areaNode = session.getNode(path);
142
143
144 final JcrNodeAdapter item = new JcrNewNodeAdapter(areaNode, NodeTypes.Component.NAME) {
145 @Override
146 public Node applyChanges() throws RepositoryException {
147 Node node = super.applyChanges();
148
149 if (COMPONENT_POSITION_TOP.equals(newComponentPosition)) {
150 NodeUtil.orderFirst(node);
151 }
152 return node;
153 }
154 };
155 item.addItemProperty(ModelConstants.JCR_NAME, new DefaultProperty<>(String.class, "0"));
156
157
158 final FormDialogPresenter formDialogPresenter = formDialogPresenterFactory.createFormDialogPresenter(NEW_COMPONENT_DIALOG);
159 final EditorCallback callback = createTemplateSelectedCallback(item, formDialogPresenter);
160
161
162 if (area.getAvailableComponents().split(",").length > 1) {
163 formDialogPresenter.start(item, NEW_COMPONENT_DIALOG, subAppContext, callback);
164 } else {
165 item.addItemProperty(NodeTypes.Renderable.TEMPLATE, new DefaultProperty<>(String.class, area.getAvailableComponents()));
166 callback.onSuccess(getDefinition().getName());
167 }
168 } else {
169 log.warn("No available components defined for {} area.", area.getPath());
170 }
171 } catch (RepositoryException e) {
172 throw new ActionExecutionException(e);
173 }
174 }
175
176 protected TemplateSelected createTemplateSelectedCallback(JcrNodeAdapter item, FormDialogPresenter formDialogPresenter) {
177 return new TemplateSelected(item, formDialogPresenter);
178 }
179
180 private class TemplateSelected implements EditorCallback {
181
182 private final JcrNodeAdapter item;
183 private final FormDialogPresenter formDialogPresenter;
184
185 public TemplateSelected(JcrNodeAdapter item, FormDialogPresenter formDialogPresenter) {
186 this.item = item;
187 this.formDialogPresenter = formDialogPresenter;
188 }
189
190 @Override
191 public void onSuccess(String actionName) {
192
193 String templateId = String.valueOf(item.getItemProperty(NodeTypes.Renderable.TEMPLATE).getValue());
194 TemplateDefinition templateDefinition = null;
195 try {
196 DefinitionProvider<TemplateDefinition> templateProvider = templateDefinitionRegistry.getProvider(templateId);
197 if (templateProvider.isValid()) {
198 templateDefinition = templateProvider.get();
199 }
200 } catch (Registry.NoSuchDefinitionException e) {
201 log.error("Could not find template definition provider for id {}", templateId, e);
202 }
203
204
205 Property positionProperty = item.getItemProperty(NEW_COMPONENT_POSITION);
206 newComponentPosition = positionProperty != null ? (String) positionProperty.getValue() : COMPONENT_POSITION_BOTTOM;
207 item.removeItemProperty(NEW_COMPONENT_POSITION);
208
209
210 if (templateDefinition != null) {
211 String dialogId = templateDefinition.getDialog();
212 if (StringUtils.isNotEmpty(dialogId)) {
213 final FormDialogPresenter nextDialogPresenter = formDialogPresenterFactory.createFormDialogPresenter(dialogId);
214 nextDialogPresenter.start(item, dialogId, subAppContext, new ComponentSaved(item, nextDialogPresenter));
215 } else {
216
217 try {
218 final Node node = item.applyChanges();
219 node.getSession().save();
220 } catch (RepositoryException e) {
221 log.error("Exception caught: {}", e.getMessage(), e);
222 }
223 eventBus.fireEvent(new ContentChangedEvent(item.getItemId()));
224 }
225 }
226
227 if (formDialogPresenter != null) {
228 formDialogPresenter.closeDialog();
229 }
230 }
231
232 @Override
233 public void onCancel() {
234 formDialogPresenter.closeDialog();
235 }
236 }
237
238 private class ComponentSaved implements EditorCallback {
239
240 private final JcrNodeAdapter item;
241 private final FormDialogPresenter dialogPresenter;
242
243 public ComponentSaved(JcrNodeAdapter item, FormDialogPresenter dialogPresenter) {
244 this.item = item;
245 this.dialogPresenter = dialogPresenter;
246 }
247
248 @Override
249 public void onSuccess(String actionName) {
250 dialogPresenter.closeDialog();
251 eventBus.fireEvent(new ContentChangedEvent(item.getItemId()));
252 }
253
254 @Override
255 public void onCancel() {
256 dialogPresenter.closeDialog();
257 }
258 }
259 }