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.module.admininterface;
35
36 import info.magnolia.cms.beans.runtime.MultipartForm;
37 import info.magnolia.cms.core.Content;
38 import info.magnolia.cms.core.HierarchyManager;
39 import info.magnolia.cms.core.ItemType;
40 import info.magnolia.cms.gui.dialog.Dialog;
41 import info.magnolia.cms.gui.dialog.DialogControlImpl;
42 import info.magnolia.cms.gui.dialog.DialogFactory;
43 import info.magnolia.cms.gui.i18n.I18nAuthoringSupport;
44 import info.magnolia.cms.gui.misc.Sources;
45 import info.magnolia.cms.i18n.Messages;
46 import info.magnolia.cms.i18n.MessagesManager;
47 import info.magnolia.cms.security.AccessDeniedException;
48 import info.magnolia.cms.servlets.MVCServletHandlerImpl;
49 import info.magnolia.cms.util.ExclusiveWrite;
50 import info.magnolia.cms.util.NodeDataUtil;
51 import info.magnolia.cms.util.RequestFormUtil;
52 import info.magnolia.context.MgnlContext;
53 import info.magnolia.objectfactory.Classes;
54 import info.magnolia.objectfactory.Components;
55 import info.magnolia.objectfactory.MgnlInstantiationException;
56 import info.magnolia.repository.RepositoryConstants;
57
58 import java.io.IOException;
59 import java.io.PrintWriter;
60
61 import javax.jcr.RepositoryException;
62 import javax.servlet.http.HttpServletRequest;
63 import javax.servlet.http.HttpServletResponse;
64 import javax.servlet.http.HttpSession;
65
66 import org.apache.commons.lang.StringUtils;
67 import org.slf4j.Logger;
68 import org.slf4j.LoggerFactory;
69
70
71
72
73
74
75
76
77 public class DialogMVCHandler extends MVCServletHandlerImpl {
78
79
80
81
82 private static Logger log = LoggerFactory.getLogger(DialogMVCHandler.class);
83
84
85
86
87 protected static final String COMMAND_SAVE = "save";
88
89 protected static final String COMMAND_SELECT_PARAGRAPH = "selectParagraph";
90
91 protected static final String COMMAND_SHOW_DIALOG = "showDialog";
92
93
94
95
96 protected static final String VIEW_CLOSE_WINDOW = "close";
97
98 protected static final String VIEW_SHOW_DIALOG = "show";
99
100
101
102
103 protected MultipartForm form;
104
105
106
107
108 protected String path = StringUtils.EMPTY;
109
110
111
112
113 private String nodeCollectionName = StringUtils.EMPTY;
114
115
116
117
118 protected String nodeName = StringUtils.EMPTY;
119
120 protected String richE = StringUtils.EMPTY;
121
122 protected String richEPaste = StringUtils.EMPTY;
123
124 protected String repository = StringUtils.EMPTY;
125
126 protected String locale;
127
128 protected HierarchyManager hm;
129
130 private Dialog dialog;
131
132 protected Messages msgs;
133
134 protected RequestFormUtil params;
135
136 protected Content storageNode;
137
138 private SaveHandler saveHandler;
139
140 private String jsExecutedAfterSaving;
141
142 private String itemType;
143
144 private final I18nAuthoringSupport i18nAuthoringSupport;
145
146
147
148
149
150
151 public DialogMVCHandler(String name, HttpServletRequest request, HttpServletResponse response) {
152 super(name, request, response);
153
154 form = MgnlContext.getPostedForm();
155 if(form != null || request != null){
156 params = new RequestFormUtil(request, form);
157
158 path = params.getParameter("mgnlPath");
159 nodeCollectionName = params.getParameter("mgnlNodeCollection");
160 nodeName = params.getParameter("mgnlNode");
161 richE = params.getParameter("mgnlRichE");
162 richEPaste = params.getParameter("mgnlRichEPaste");
163 repository = params.getParameter("mgnlRepository", getRepository());
164 locale = params.getParameter("mgnlLocale");
165 if (StringUtils.isNotEmpty(repository)) {
166 hm = MgnlContext.getHierarchyManager(repository);
167 }
168 }
169 msgs = MessagesManager.getMessages();
170
171 i18nAuthoringSupport = I18nAuthoringSupport.Factory.getInstance();
172
173 }
174
175
176
177
178 @Override
179 public String getCommand() {
180 if (form != null) {
181 return COMMAND_SAVE;
182 }
183 return COMMAND_SHOW_DIALOG;
184 }
185
186
187
188
189 public String showDialog() {
190 return VIEW_SHOW_DIALOG;
191 }
192
193 protected void configureDialog(Dialog dialog) {
194 dialog.setConfig("dialog", getName());
195 dialog.setConfig("path", path);
196 dialog.setConfig("nodeCollection", nodeCollectionName);
197 dialog.setConfig("node", nodeName);
198 dialog.setConfig("richE", richE);
199 dialog.setConfig("richEPaste", richEPaste);
200 dialog.setConfig("repository", repository);
201 if (StringUtils.isNotEmpty(locale)) {
202 dialog.setConfig("locale", locale);
203 }
204
205 i18nAuthoringSupport.i18nIze(dialog);
206 }
207
208
209
210
211
212
213
214 protected Dialog createDialog(Content configNode, Content storageNode) throws RepositoryException {
215 return DialogFactory.getDialogInstance(this.getRequest(), this.getResponse(), storageNode, configNode);
216 }
217
218
219
220
221
222
223
224 public String save() {
225 if (!validate()) {
226 return onValidationFailed();
227 }
228 SaveHandler saveHandler = getSaveHandler();
229 if (!onPreSave(saveHandler)) {
230 return onSaveFailed();
231 }
232 if (!onSave(saveHandler)) {
233 return onSaveFailed();
234 }
235 synchronized (ExclusiveWrite.getInstance()) {
236 if (!onPostSave(saveHandler)) {
237 return onSaveFailed();
238 }
239 }
240 removeSessionAttributes();
241 return VIEW_CLOSE_WINDOW;
242 }
243
244 private String onValidationFailed() {
245 return showDialog();
246 }
247
248 protected boolean validate() {
249 boolean passed = this.getDialog().validate();
250
251 SaveHandler saveHandler = this.getSaveHandler();
252 if ((passed) && (saveHandler instanceof ValidatingSaveHandler)) {
253 passed = ((ValidatingSaveHandler) saveHandler).validate();
254 }
255
256 if (!passed) {
257
258 if (StringUtils.isEmpty(this.dialog.getConfigValue("paragraph"))) {
259
260 String paragraphName = params.getParameter("mgnlParagraph");
261 this.dialog.setConfig("paragraph", paragraphName);
262 }
263 if (StringUtils.isEmpty(this.dialog.getConfigValue("collectionNodeCreationItemType"))) {
264 this.dialog.setConfig("collectionNodeCreationItemType", params.getParameter("mgnlCollectionNodeCreationItemType"));
265 }
266 if (StringUtils.isEmpty(this.dialog.getConfigValue("creationItemType"))) {
267 this.dialog.setConfig("creationItemType", params.getParameter("mgnlCreationItemType"));
268 }
269 }
270
271 return passed;
272 }
273
274
275
276
277 protected String onSaveFailed() {
278 return showDialog();
279 }
280
281
282
283
284
285 protected SaveHandler getSaveHandler() {
286 if (this.saveHandler == null) {
287 createSaveHandler();
288
289 configureSaveHandler(this.saveHandler);
290 }
291 return this.saveHandler;
292 }
293
294
295
296
297
298 protected void createSaveHandler() {
299 Content configNode = this.getConfigNode();
300 if (configNode != null) {
301 String className = NodeDataUtil.getString(configNode, "saveHandler");
302 if (StringUtils.isNotEmpty(className)) {
303 try {
304 this.saveHandler = Classes.newInstance(className);
305 }
306 catch (MgnlInstantiationException e) {
307 log.error("can't create save handler", e);
308 }
309 catch (ClassNotFoundException e) {
310 log.error("can't create save handler", e);
311 }
312 }
313 }
314
315 if (this.saveHandler == null) {
316 this.saveHandler = Components.getComponentProvider().newInstance(SaveHandler.class);
317 }
318 }
319
320
321
322
323 protected void configureSaveHandler(SaveHandler saveHandler) {
324 saveHandler.init(form);
325
326 saveHandler.setPath(form.getParameter("mgnlPath"));
327 saveHandler.setNodeCollectionName(form.getParameter("mgnlNodeCollection"));
328 saveHandler.setNodeName(form.getParameter("mgnlNode"));
329 saveHandler.setParagraph(form.getParameter("mgnlParagraph"));
330 saveHandler.setRepository(form.getParameter("mgnlRepository"));
331 if (StringUtils.isNotEmpty(form.getParameter("mgnlCollectionNodeCreationItemType"))) {
332 saveHandler.setCollectionNodeCreationItemType(new ItemType(form.getParameter("mgnlCollectionNodeCreationItemType")));
333 }
334 if (StringUtils.isNotEmpty(getItemType())) {
335 saveHandler.setCreationItemType(new ItemType(getItemType()));
336 } else if (StringUtils.isNotEmpty(form.getParameter("mgnlCreationItemType"))) {
337 saveHandler.setCreationItemType(new ItemType(form.getParameter("mgnlCreationItemType")));
338 }
339
340 if (this.saveHandler instanceof DialogAwareSaveHandler) {
341 ((DialogAwareSaveHandler) saveHandler).setDialog(this.getDialog());
342 }
343 }
344
345 protected boolean onPreSave(SaveHandler control) {
346 return true;
347 }
348
349 protected boolean onSave(SaveHandler control) {
350 boolean result = control.save();
351 if (result) {
352 this.nodeName = control.getNodeName();
353 }
354 return result;
355 }
356
357 protected boolean onPostSave(SaveHandler control) {
358 return true;
359 }
360
361
362
363
364
365 public Content getStorageNode() {
366
367 if (storageNode == null && hm != null) {
368 try {
369 if(this.path == null){
370 log.debug("No path defined for a dialog called by the url [{}]", this.getRequest().getRequestURL());
371 return null;
372 }
373 Content parentContent = hm.getContent(path);
374 if (StringUtils.isEmpty(nodeName)) {
375 if (StringUtils.isEmpty(nodeCollectionName)) {
376 storageNode = parentContent;
377 }
378 else {
379 storageNode = parentContent.getContent(nodeCollectionName);
380 }
381 }
382 else {
383 if (StringUtils.isEmpty(nodeCollectionName)) {
384 storageNode = parentContent.getContent(nodeName);
385
386 }
387 else {
388 storageNode = parentContent.getContent(nodeCollectionName).getContent(nodeName);
389
390 }
391 }
392 }
393 catch(AccessDeniedException ade){
394 log.error("can't read content to edit", ade);
395 }
396 catch (RepositoryException re) {
397
398 log.debug("can't read content or it does not exist yet", re);
399 }
400 }
401 return storageNode;
402 }
403
404
405
406
407 public Content getConfigNode() {
408 return null;
409 }
410
411
412
413
414 @Override
415 public void renderHtml(String view) throws IOException {
416 PrintWriter out = this.getResponse().getWriter();
417
418
419 if (VIEW_CLOSE_WINDOW.equals(view)) {
420
421 out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" ");
422 out.write(" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n");
423 out.println("<html>");
424 out.println(new Sources(this.getRequest().getContextPath()).getHtmlJs());
425 out.println("<script type=\"text/javascript\">");
426 out.println("var path = '" + this.path + "'");
427 out.println(StringUtils.defaultIfEmpty(getJsExecutedAfterSaving(), "mgnlDialogReloadOpener();"));
428 out.println("window.close();");
429 out.println("</script></html>");
430 }
431
432 else if (VIEW_SHOW_DIALOG.equals(view)) {
433 try {
434 getDialog().drawHtml(out);
435 }
436 catch (IOException e) {
437 log.error("Exception caught", e);
438 }
439 }
440 }
441
442
443
444
445 public String getRepository() {
446 return RepositoryConstants.WEBSITE;
447 }
448
449 public void removeSessionAttributes() {
450 String[] toRemove = form.getParameterValues(DialogControlImpl.SESSION_ATTRIBUTENAME_DIALOGOBJECT_REMOVE);
451 if (toRemove != null) {
452 for (int i = 0; i < toRemove.length; i++) {
453 HttpSession httpsession = this.getRequest().getSession(false);
454 if (httpsession != null) {
455 httpsession.removeAttribute(toRemove[i]);
456 }
457 }
458 }
459 }
460
461
462
463
464 public void setDialog(Dialog dialog) {
465 this.dialog = dialog;
466 }
467
468
469
470
471 public Dialog getDialog() {
472 if (this.dialog == null) {
473 try {
474 this.dialog = createDialog(this.getConfigNode(), this.getStorageNode());
475 }
476 catch (RepositoryException e) {
477 log.error("can't create dialog", e);
478 }
479 configureDialog(this.dialog);
480 }
481 return this.dialog;
482 }
483
484
485 public String getJsExecutedAfterSaving() {
486 return this.jsExecutedAfterSaving;
487 }
488
489
490 public void setJsExecutedAfterSaving(String jsExecutedAfterSaving) {
491 this.jsExecutedAfterSaving = jsExecutedAfterSaving;
492 }
493
494
495 public String getItemType() {
496 return this.itemType;
497 }
498
499
500 public void setItemType(String itemType) {
501 this.itemType = itemType;
502 }
503 }