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 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 params = new RequestFormUtil(request, form);
156
157 path = params.getParameter("mgnlPath");
158 nodeCollectionName = params.getParameter("mgnlNodeCollection");
159 nodeName = params.getParameter("mgnlNode");
160 richE = params.getParameter("mgnlRichE");
161 richEPaste = params.getParameter("mgnlRichEPaste");
162 repository = params.getParameter("mgnlRepository", getRepository());
163 locale = params.getParameter("mgnlLocale");
164 if (StringUtils.isNotEmpty(repository)) {
165 hm = MgnlContext.getHierarchyManager(repository);
166 }
167 msgs = MessagesManager.getMessages();
168
169 i18nAuthoringSupport = I18nAuthoringSupport.Factory.getInstance();
170
171 }
172
173
174
175
176 @Override
177 public String getCommand() {
178 if (form != null) {
179 return COMMAND_SAVE;
180 }
181 return COMMAND_SHOW_DIALOG;
182 }
183
184
185
186
187 public String showDialog() {
188 return VIEW_SHOW_DIALOG;
189 }
190
191 protected void configureDialog(Dialog dialog) {
192 dialog.setConfig("dialog", getName());
193 dialog.setConfig("path", path);
194 dialog.setConfig("nodeCollection", nodeCollectionName);
195 dialog.setConfig("node", nodeName);
196 dialog.setConfig("richE", richE);
197 dialog.setConfig("richEPaste", richEPaste);
198 dialog.setConfig("repository", repository);
199 if (StringUtils.isNotEmpty(locale)) {
200 dialog.setConfig("locale", locale);
201 }
202
203 i18nAuthoringSupport.i18nIze(dialog);
204 }
205
206
207
208
209
210
211
212 protected Dialog createDialog(Content configNode, Content storageNode) throws RepositoryException {
213 return DialogFactory.getDialogInstance(this.getRequest(), this.getResponse(), storageNode, configNode);
214 }
215
216
217
218
219
220
221
222 public String save() {
223 if (!validate()) {
224 return onValidationFailed();
225 }
226 SaveHandler saveHandler = getSaveHandler();
227 if (!onPreSave(saveHandler)) {
228 return onSaveFailed();
229 }
230 if (!onSave(saveHandler)) {
231 return onSaveFailed();
232 }
233 synchronized (ExclusiveWrite.getInstance()) {
234 if (!onPostSave(saveHandler)) {
235 return onSaveFailed();
236 }
237 }
238 removeSessionAttributes();
239 return VIEW_CLOSE_WINDOW;
240 }
241
242 private String onValidationFailed() {
243 return showDialog();
244 }
245
246 protected boolean validate() {
247 boolean passed = this.getDialog().validate();
248
249 SaveHandler saveHandler = this.getSaveHandler();
250 if ((passed) && (saveHandler instanceof ValidatingSaveHandler)) {
251 passed = ((ValidatingSaveHandler) saveHandler).validate();
252 }
253
254 if (!passed) {
255
256 if (StringUtils.isEmpty(this.dialog.getConfigValue("paragraph"))) {
257
258 String paragraphName = params.getParameter("mgnlParagraph");
259 this.dialog.setConfig("paragraph", paragraphName);
260 }
261 if (StringUtils.isEmpty(this.dialog.getConfigValue("collectionNodeCreationItemType"))) {
262 this.dialog.setConfig("collectionNodeCreationItemType", params.getParameter("mgnlCollectionNodeCreationItemType"));
263 }
264 if (StringUtils.isEmpty(this.dialog.getConfigValue("creationItemType"))) {
265 this.dialog.setConfig("creationItemType", params.getParameter("mgnlCreationItemType"));
266 }
267 }
268
269 return passed;
270 }
271
272
273
274
275 protected String onSaveFailed() {
276 return showDialog();
277 }
278
279
280
281
282
283 protected SaveHandler getSaveHandler() {
284 if (this.saveHandler == null) {
285 createSaveHandler();
286
287 configureSaveHandler(this.saveHandler);
288 }
289 return this.saveHandler;
290 }
291
292
293
294
295
296 protected void createSaveHandler() {
297 Content configNode = this.getConfigNode();
298 if (configNode != null) {
299 String className = NodeDataUtil.getString(configNode, "saveHandler");
300 if (StringUtils.isNotEmpty(className)) {
301 try {
302 this.saveHandler = Classes.newInstance(className);
303 }
304 catch (MgnlInstantiationException e) {
305 log.error("can't create save handler", e);
306 }
307 catch (ClassNotFoundException e) {
308 log.error("can't create save handler", e);
309 }
310 }
311 }
312
313 if (this.saveHandler == null) {
314 this.saveHandler = Components.getComponentProvider().newInstance(SaveHandler.class);
315 }
316 }
317
318
319
320
321 protected void configureSaveHandler(SaveHandler saveHandler) {
322 saveHandler.init(form);
323
324 saveHandler.setPath(form.getParameter("mgnlPath"));
325 saveHandler.setNodeCollectionName(form.getParameter("mgnlNodeCollection"));
326 saveHandler.setNodeName(form.getParameter("mgnlNode"));
327 saveHandler.setParagraph(form.getParameter("mgnlParagraph"));
328 saveHandler.setRepository(form.getParameter("mgnlRepository"));
329 if (StringUtils.isNotEmpty(form.getParameter("mgnlCollectionNodeCreationItemType"))) {
330 saveHandler.setCollectionNodeCreationItemType(new ItemType(form.getParameter("mgnlCollectionNodeCreationItemType")));
331 }
332 if (StringUtils.isNotEmpty(getItemType())) {
333 saveHandler.setCreationItemType(new ItemType(getItemType()));
334 } else if (StringUtils.isNotEmpty(form.getParameter("mgnlCreationItemType"))) {
335 saveHandler.setCreationItemType(new ItemType(form.getParameter("mgnlCreationItemType")));
336 }
337
338 if (this.saveHandler instanceof DialogAwareSaveHandler) {
339 ((DialogAwareSaveHandler) saveHandler).setDialog(this.getDialog());
340 }
341 }
342
343 protected boolean onPreSave(SaveHandler control) {
344 return true;
345 }
346
347 protected boolean onSave(SaveHandler control) {
348 boolean result = control.save();
349 if (result) {
350 this.nodeName = control.getNodeName();
351 }
352 return result;
353 }
354
355 protected boolean onPostSave(SaveHandler control) {
356 return true;
357 }
358
359
360
361
362
363 public Content getStorageNode() {
364
365 if (storageNode == null && hm != null) {
366 try {
367 if(this.path == null){
368 log.debug("No path defined for a dialog called by the url [{}]", this.getRequest().getRequestURL());
369 return null;
370 }
371 Content parentContent = hm.getContent(path);
372 if (StringUtils.isEmpty(nodeName)) {
373 if (StringUtils.isEmpty(nodeCollectionName)) {
374 storageNode = parentContent;
375 }
376 else {
377 storageNode = parentContent.getContent(nodeCollectionName);
378 }
379 }
380 else {
381 if (StringUtils.isEmpty(nodeCollectionName)) {
382 storageNode = parentContent.getContent(nodeName);
383
384 }
385 else {
386 storageNode = parentContent.getContent(nodeCollectionName).getContent(nodeName);
387
388 }
389 }
390 }
391 catch(AccessDeniedException ade){
392 log.error("can't read content to edit", ade);
393 }
394 catch (RepositoryException re) {
395
396 log.debug("can't read content or it does not exist yet", re);
397 }
398 }
399 return storageNode;
400 }
401
402
403
404
405 public Content getConfigNode() {
406 return null;
407 }
408
409
410
411
412 @Override
413 public void renderHtml(String view) throws IOException {
414 PrintWriter out = this.getResponse().getWriter();
415
416
417 if (VIEW_CLOSE_WINDOW.equals(view)) {
418
419 out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" ");
420 out.write(" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n");
421 out.println("<html>");
422 out.println(new Sources(this.getRequest().getContextPath()).getHtmlJs());
423 out.println("<script type=\"text/javascript\">");
424 out.println("var path = '" + this.path + "'");
425 out.println(StringUtils.defaultIfEmpty(getJsExecutedAfterSaving(), "mgnlDialogReloadOpener();"));
426 out.println("window.close();");
427 out.println("</script></html>");
428 }
429
430 else if (VIEW_SHOW_DIALOG.equals(view)) {
431 try {
432 getDialog().drawHtml(out);
433 }
434 catch (IOException e) {
435 log.error("Exception caught", e);
436 }
437 }
438 }
439
440
441
442
443 public String getRepository() {
444 return RepositoryConstants.WEBSITE;
445 }
446
447 public void removeSessionAttributes() {
448 String[] toRemove = form.getParameterValues(DialogControlImpl.SESSION_ATTRIBUTENAME_DIALOGOBJECT_REMOVE);
449 if (toRemove != null) {
450 for (int i = 0; i < toRemove.length; i++) {
451 HttpSession httpsession = this.getRequest().getSession(false);
452 if (httpsession != null) {
453 httpsession.removeAttribute(toRemove[i]);
454 }
455 }
456 }
457 }
458
459
460
461
462 public void setDialog(Dialog dialog) {
463 this.dialog = dialog;
464 }
465
466
467
468
469 public Dialog getDialog() {
470 if (this.dialog == null) {
471 try {
472 this.dialog = createDialog(this.getConfigNode(), this.getStorageNode());
473 }
474 catch (RepositoryException e) {
475 log.error("can't create dialog", e);
476 }
477 configureDialog(this.dialog);
478 }
479 return this.dialog;
480 }
481
482
483 public String getJsExecutedAfterSaving() {
484 return this.jsExecutedAfterSaving;
485 }
486
487
488 public void setJsExecutedAfterSaving(String jsExecutedAfterSaving) {
489 this.jsExecutedAfterSaving = jsExecutedAfterSaving;
490 }
491
492
493 public String getItemType() {
494 return this.itemType;
495 }
496
497
498 public void setItemType(String itemType) {
499 this.itemType = itemType;
500 }
501 }