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 private static final String NEW_COMPONENT_DIALOG = "pages:newComponent";
82 private static final String NEW_COMPONENT_POSITION = "position";
83
84
85
86 private static final String COMPONENT_POSITION_TOP = "top";
87 private 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 private 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 = new TemplateSelected(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 private class TemplateSelected implements EditorCallback {
177
178 private final JcrNodeAdapter item;
179 private final FormDialogPresenter formDialogPresenter;
180
181 public TemplateSelected(JcrNodeAdapter item, FormDialogPresenter formDialogPresenter) {
182 this.item = item;
183 this.formDialogPresenter = formDialogPresenter;
184 }
185
186 @Override
187 public void onSuccess(String actionName) {
188
189 String templateId = String.valueOf(item.getItemProperty(NodeTypes.Renderable.TEMPLATE).getValue());
190 TemplateDefinition templateDefinition = null;
191 try {
192 DefinitionProvider<TemplateDefinition> templateProvider = templateDefinitionRegistry.getProvider(templateId);
193 if (templateProvider.isValid()) {
194 templateDefinition = templateProvider.get();
195 }
196 } catch (Registry.NoSuchDefinitionException e) {
197 log.error("Could not find template definition provider for id {}", templateId, e);
198 }
199
200
201 Property positionProperty = item.getItemProperty(NEW_COMPONENT_POSITION);
202 newComponentPosition = positionProperty != null ? (String) positionProperty.getValue() : COMPONENT_POSITION_BOTTOM;
203
204
205 if (templateDefinition != null) {
206 String dialogId = templateDefinition.getDialog();
207 if (StringUtils.isNotEmpty(dialogId)) {
208 final FormDialogPresenter nextDialogPresenter = formDialogPresenterFactory.createFormDialogPresenter(dialogId);
209 nextDialogPresenter.start(item, dialogId, subAppContext, new ComponentSaved(item, nextDialogPresenter));
210 } else {
211
212 try {
213 final Node node = item.applyChanges();
214 node.getSession().save();
215 } catch (RepositoryException e) {
216 log.error("Exception caught: {}", e.getMessage(), e);
217 }
218 eventBus.fireEvent(new ContentChangedEvent(item.getItemId()));
219 }
220 }
221
222 if (formDialogPresenter != null) {
223 formDialogPresenter.closeDialog();
224 }
225 }
226
227 @Override
228 public void onCancel() {
229 formDialogPresenter.closeDialog();
230 }
231 }
232
233 private class ComponentSaved implements EditorCallback {
234
235 private final JcrNodeAdapter item;
236 private final FormDialogPresenter dialogPresenter;
237
238 public ComponentSaved(JcrNodeAdapter item, FormDialogPresenter dialogPresenter) {
239 this.item = item;
240 this.dialogPresenter = dialogPresenter;
241 }
242
243 @Override
244 public void onSuccess(String actionName) {
245 eventBus.fireEvent(new ContentChangedEvent(item.getItemId()));
246 dialogPresenter.closeDialog();
247 }
248
249 @Override
250 public void onCancel() {
251 dialogPresenter.closeDialog();
252 }
253 }
254 }