KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > info > magnolia > module > admininterface > SaveHandlerImpl


1 /**
2  *
3  * Magnolia and its source-code is licensed under the LGPL.
4  * You may copy, adapt, and redistribute this file for commercial or non-commercial use.
5  * When copying, adapting, or redistributing this document in keeping with the guidelines above,
6  * you are required to provide proper attribution to obinary.
7  * If you reproduce or distribute the document without making any substantive modifications to its content,
8  * please use the following attribution line:
9  *
10  * Copyright 1993-2006 obinary Ltd. (http://www.obinary.com) All rights reserved.
11  *
12  */

13 package info.magnolia.module.admininterface;
14
15 import info.magnolia.cms.beans.config.ContentRepository;
16 import info.magnolia.cms.beans.runtime.Document;
17 import info.magnolia.cms.beans.runtime.MultipartForm;
18 import info.magnolia.cms.core.Content;
19 import info.magnolia.cms.core.HierarchyManager;
20 import info.magnolia.cms.core.ItemType;
21 import info.magnolia.cms.core.NodeData;
22 import info.magnolia.cms.core.Path;
23 import info.magnolia.cms.gui.control.ControlImpl;
24 import info.magnolia.cms.gui.control.File;
25 import info.magnolia.cms.gui.fckeditor.FCKEditorTmpFiles;
26 import info.magnolia.cms.gui.misc.FileProperties;
27 import info.magnolia.cms.security.AccessDeniedException;
28 import info.magnolia.cms.security.Digester;
29 import info.magnolia.cms.util.ContentUtil;
30 import info.magnolia.cms.util.DateUtil;
31 import info.magnolia.cms.util.ExclusiveWrite;
32 import info.magnolia.cms.util.LinkUtil;
33 import info.magnolia.cms.util.NodeDataUtil;
34 import info.magnolia.context.MgnlContext;
35
36 import java.io.FileInputStream JavaDoc;
37 import java.io.FileNotFoundException JavaDoc;
38 import java.io.IOException JavaDoc;
39 import java.io.InputStream JavaDoc;
40 import java.util.Calendar JavaDoc;
41 import java.util.GregorianCalendar JavaDoc;
42 import java.util.Iterator JavaDoc;
43 import java.util.Map JavaDoc;
44 import java.util.TimeZone JavaDoc;
45 import java.util.regex.Matcher JavaDoc;
46 import java.util.regex.Pattern JavaDoc;
47
48 import javax.jcr.Node;
49 import javax.jcr.PathNotFoundException;
50 import javax.jcr.PropertyType;
51 import javax.jcr.RepositoryException;
52 import javax.jcr.Value;
53 import javax.jcr.ValueFactory;
54
55 import org.apache.commons.codec.binary.Base64;
56 import org.apache.commons.io.FileUtils;
57 import org.apache.commons.io.IOUtils;
58 import org.apache.commons.lang.StringUtils;
59 import org.apache.commons.lang.exception.NestableRuntimeException;
60 import org.devlib.schmidt.imageinfo.ImageInfo;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63
64
65 /**
66  * This class handels the saving in the dialogs. It uses the mgnlSaveInfo parameters sendend from the browser to store
67  * the data in the node.The structure of the parameter is the following: <br>
68  * <code>name, type, valueType, isRichEditValue, encoding</code> <p/> To find the consts see ControlImpl <table>
69  * <tr>
70  * <td>name</td>
71  * <td>the name of the field</td>
72  * </tr>
73  * <tr>
74  * <td>type</td>
75  * <td>string, boolean, ...</td>
76  * </tr>
77  * <tr>
78  * <td>valueType</td>
79  * <td>single, multiple</td>
80  * </tr>
81  * <tr>
82  * <td>isRichEditValue</td>
83  * <td>value from an editor</td>
84  * </tr>
85  * <tr>
86  * <td>encoding</td>
87  * <td>base64, unix, none</td>
88  * </tr>
89  * </table>
90  * @author Vinzenz Wyser
91  * @version 2.0
92  */

93 public class SaveHandlerImpl implements SaveHandler {
94
95     /**
96      * Logger
97      */

98     public static Logger log = LoggerFactory.getLogger(SaveHandlerImpl.class);
99
100     /**
101      * The from, containing all the fields and files. This form is generated by magnolia.
102      */

103     private MultipartForm form;
104
105     /**
106      * creates the node if it is not present
107      */

108     private boolean create;
109
110     private ItemType creationItemType = ItemType.CONTENTNODE;
111
112     /**
113      * The name of the repository to store the data. Website is default.
114      */

115     private String JavaDoc repository = ContentRepository.WEBSITE;
116
117     /**
118      * Path to the page
119      */

120     private String JavaDoc path;
121
122     /**
123      * If the saved paragraph is saved to a node collection
124      */

125     private String JavaDoc nodeCollectionName;
126
127     /**
128      * The name of the node saving to. mgnlNew if a new node should get creaetd
129      */

130     private String JavaDoc nodeName;
131
132     /**
133      * The current paragraph type. This information is saved under the node to enable a proper rendering.
134      */

135     private String JavaDoc paragraph;
136
137     /**
138      * Call init to initialize the object
139      */

140     public SaveHandlerImpl() {
141     }
142
143     /**
144      * Initialize the SaveHandlerImpl control.
145      * @param form the form generated from the request due to handle multipart forms
146      */

147     public void init(MultipartForm form) {
148         this.setForm(form);
149     }
150
151     /**
152      * @see info.magnolia.module.admininterface.SaveHandler#save()
153      */

154     public boolean save() {
155
156         String JavaDoc[] saveInfos = getForm().getParameterValues("mgnlSaveInfo"); // name,type,propertyOrNode
157

158         if (saveInfos == null) {
159             log.info("Nothing to save, mgnlSaveInfo parameter not found.");
160             return true;
161         }
162
163         synchronized (ExclusiveWrite.getInstance()) {
164             // //$NON-NLS-1$
165
String JavaDoc path = this.getPath();
166
167             HierarchyManager hm = MgnlContext.getHierarchyManager(this.getRepository());
168             try {
169                 // get the node to save
170
Content page = this.getPageNode(hm);
171
172                 if (page == null) {
173                     // an error should have been logged in getPageNode() avoid NPEs!
174
return false;
175                 }
176
177                 Content node = this.getSaveNode(hm, page);
178
179                 // this value can get used later on to find this node
180
this.setNodeName(node.getName());
181                 if (StringUtils.isEmpty(node.getMetaData().getTemplate())) {
182                     node.getMetaData().setTemplate(this.getParagraph());
183                 }
184
185                 // update meta data (e.g. last modified) of this paragraph and the page
186
node.updateMetaData();
187                 page.updateMetaData();
188
189                 // loop all saveInfo controls; saveInfo format: name, type, valueType(single|multiple, )
190
for (int i = 0; i < saveInfos.length; i++) {
191                     String JavaDoc saveInfo = saveInfos[i];
192                     processSaveInfo(node, saveInfo);
193                 }
194
195                 // deleting all documents
196
try {
197                     MultipartForm form = getForm();
198                     Map JavaDoc docs = form.getDocuments();
199                     Iterator JavaDoc iter = docs.keySet().iterator();
200                     while (iter.hasNext()) {
201                         form.getDocument((String JavaDoc) iter.next()).delete();
202                     }
203                 }
204                 catch (Exception JavaDoc e) {
205                     log.error("Could not delete temp documents from form");
206                 }
207
208                 if (log.isDebugEnabled()) {
209                     log.debug("Saving {}", path); //$NON-NLS-1$
210
}
211
212                 hm.save();
213             }
214             catch (RepositoryException re) {
215                 log.error(re.getMessage(), re);
216                 return false;
217             }
218         }
219         return true;
220     }
221
222     /**
223      * This method cears about one mgnlSaveInfo. It adds the value to the node
224      * @param node node to add data
225      * @param saveInfo <code>name, type, valueType, isRichEditValue, encoding</code>
226      * @throws PathNotFoundException exception
227      * @throws RepositoryException exception
228      * @throws AccessDeniedException no access
229      */

230     protected void processSaveInfo(Content node, String JavaDoc saveInfo) throws PathNotFoundException, RepositoryException,
231         AccessDeniedException {
232
233         String JavaDoc name;
234         int type = PropertyType.STRING;
235         int valueType = ControlImpl.VALUETYPE_SINGLE;
236         int isRichEditValue = 0;
237         int encoding = ControlImpl.ENCODING_NO;
238         String JavaDoc[] values = {StringUtils.EMPTY};
239         if (StringUtils.contains(saveInfo, ',')) {
240             String JavaDoc[] info = StringUtils.split(saveInfo, ',');
241             name = info[0];
242             if (info.length >= 2) {
243                 type = PropertyType.valueFromName(info[1]);
244             }
245             if (info.length >= 3) {
246                 valueType = Integer.valueOf(info[2]).intValue();
247             }
248             if (info.length >= 4) {
249                 isRichEditValue = Integer.valueOf(info[3]).intValue();
250             }
251             if (info.length >= 5) {
252                 encoding = Integer.valueOf(info[4]).intValue();
253             }
254         }
255         else {
256             name = saveInfo;
257         }
258
259         if (type == PropertyType.BINARY) {
260             processBinary(node, name);
261         }
262         else {
263             values = getForm().getParameterValues(name);
264             if (valueType == ControlImpl.VALUETYPE_MULTIPLE) {
265                 processMultiple(node, name, type, values);
266             }
267             else if (isRichEditValue != ControlImpl.RICHEDIT_NONE) {
268                 processRichEdit(node, name, type, isRichEditValue, encoding, values);
269             }
270             else if (type == PropertyType.DATE) {
271                 processDate(node, name, type, valueType, encoding, values);
272             }
273             else {
274                 processCommon(node, name, type, valueType, encoding, values);
275             }
276         }
277     }
278
279     protected void processDate(Content node, String JavaDoc name, int type, int valueType, int encoding, String JavaDoc[] values) {
280         try {
281             if (StringUtils.isEmpty(values[0])) {
282                 if (log.isDebugEnabled()) {
283                     log.debug("Date has no value. Deleting node data" + name);
284                 }
285                 if(node.hasNodeData(name)){
286                     node.deleteNodeData(name);
287                 }
288             }
289             else {
290                 Calendar JavaDoc utc = DateUtil.getUTCCalendarFromDialogString(values[0]);
291                 NodeDataUtil.getOrCreate(node, name).setValue(utc);
292             }
293         }
294         catch (Exception JavaDoc e) {
295             log.error("Could not update date value of node:" + node.getHandle() + " of property:" + name, e);
296         }
297     }
298
299     /**
300      * Parse the value returned by a rich text editor and update the links and linebreaks.
301      * @param node
302      * @param name
303      * @param type
304      * @param isRichEditValue
305      * @param encoding
306      * @param values
307      * @throws PathNotFoundException
308      * @throws RepositoryException
309      * @throws AccessDeniedException
310      */

311     protected void processRichEdit(Content node, String JavaDoc name, int type, int isRichEditValue, int encoding,
312         String JavaDoc[] values) throws PathNotFoundException, RepositoryException, AccessDeniedException {
313         String JavaDoc valueStr = StringUtils.EMPTY;
314         if (values != null) {
315             valueStr = values[0]; // values is null when the expected field would not exis, e.g no
316
}
317
318         valueStr = cleanLineBreaks(valueStr, isRichEditValue);
319
320         if (isRichEditValue == ControlImpl.RICHEDIT_FCK) {
321             valueStr = updateLinks(node, name, valueStr);
322         }
323
324         processString(node, name, type, encoding, values, valueStr);
325     }
326
327     /**
328      * Clean up the linebreaks and
329      * <p>, <br>
330      * tags returned by the rich text editors
331      * @param valueStr
332      * @return the cleaned string
333      */

334     private String JavaDoc cleanLineBreaks(String JavaDoc valueStr, int isRichEditValue) {
335         // encode the internal links to avoid dependences from the contextpath, position of the page
336
valueStr = LinkUtil.convertAbsoluteLinksToUUIDs(valueStr);
337
338         valueStr = StringUtils.replace(valueStr, "\r\n", " "); //$NON-NLS-1$ //$NON-NLS-2$
339
valueStr = StringUtils.replace(valueStr, "\n", " "); //$NON-NLS-1$ //$NON-NLS-2$
340

341         // ie inserts some strange br...
342
valueStr = StringUtils.replace(valueStr, "</br>", StringUtils.EMPTY); //$NON-NLS-1$
343
valueStr = StringUtils.replace(valueStr, "<br>", "<br/>"); //$NON-NLS-1$ //$NON-NLS-2$
344
valueStr = StringUtils.replace(valueStr, "<BR>", "<br />"); //$NON-NLS-1$ //$NON-NLS-2$
345
valueStr = StringUtils.replace(valueStr, "<br/>", "<br />"); //$NON-NLS-1$ //$NON-NLS-2$
346
valueStr = StringUtils.replace(valueStr, "<P><br />", "<P>"); //$NON-NLS-1$ //$NON-NLS-2$
347

348         // replace <P>
349
if (isRichEditValue != ControlImpl.RICHEDIT_FCK) {
350             valueStr = replacePByBr(valueStr, "p"); //$NON-NLS-1$
351
}
352         return valueStr;
353     }
354
355     /**
356      * Update the links in a string returned by a rich text editor. If there are links to temporary files created due
357      * the fckeditor upload mechanism those filese are written to the node.
358      * @param node node saving to. used to save the files and fileinfod to
359      * @param name the name of the field. used to make a subnode for the files
360      * @param valueStr the value containing the links
361      * @return the cleaned value
362      * @throws AccessDeniedException
363      * @throws RepositoryException
364      * @throws PathNotFoundException
365      */

366     private String JavaDoc updateLinks(Content node, String JavaDoc name, String JavaDoc valueStr) throws AccessDeniedException,
367         RepositoryException, PathNotFoundException {
368
369         // process the images and uploaded files
370
HierarchyManager hm = MgnlContext.getHierarchyManager(this.getRepository());
371
372         Pattern JavaDoc imagePattern = Pattern.compile("(<(a|img)[^>]+(href|src)[ ]*=[ ]*\")([^\"]*)(\"[^>]*>)");
373         Pattern JavaDoc uuidPattern = Pattern.compile(MgnlContext.getContextPath() + "/tmp/fckeditor/([^/]*)/[^\"]*");
374
375         Content filesNode = ContentUtil.getOrCreateContent(node, name + "_files", ItemType.CONTENTNODE);
376
377         String JavaDoc pageName = StringUtils.substringAfterLast(this.getPath(), "/");
378
379         // adapt img urls
380
Matcher JavaDoc srcMatcher = imagePattern.matcher(valueStr);
381         StringBuffer JavaDoc res = new StringBuffer JavaDoc();
382         while (srcMatcher.find()) {
383             String JavaDoc src = srcMatcher.group(4);
384
385             // the editor creates relative links after moving an absolute path: ../../../ replace them
386
src = StringUtils.replace(src, "../../../", MgnlContext.getContextPath() + "/");
387
388             String JavaDoc link = src;
389
390             // process the tmporary uploaded files
391
Matcher JavaDoc uuidMatcher = uuidPattern.matcher(src);
392
393             if (uuidMatcher.find()) {
394                 String JavaDoc uuid = uuidMatcher.group(1);
395
396                 Document doc = FCKEditorTmpFiles.getDocument(uuid);
397                 String JavaDoc fileNodeName = Path.getUniqueLabel(hm, filesNode.getHandle(), "file");
398                 SaveHandlerImpl.saveDocument(filesNode, doc, fileNodeName, "", "");
399                 String JavaDoc subpath = StringUtils.removeStart(filesNode.getHandle(), this.getPath() + "/");
400                 link = pageName + "/" + subpath + "/" + fileNodeName + "/" + doc.getFileNameWithExtension();
401                 doc.delete();
402                 try {
403                     FileUtils.deleteDirectory(new java.io.File JavaDoc(Path.getTempDirectory() + "/fckeditor/" + uuid));
404                 }
405                 catch (IOException JavaDoc e) {
406                     log.error("can't delete tmp file [" + Path.getTempDirectory() + "/fckeditor/" + uuid + "]");
407                 }
408             }
409             // make internal links relative
410
// note MgnlContext.getContextPath() can be empty and url may be absolute (http:// ftp:// mailto: ...)
411
// @todo this only handles links to children pages
412
else if (src.startsWith(MgnlContext.getContextPath() + this.getPath())) {
413                 link = pageName + StringUtils.removeStart(src, MgnlContext.getContextPath() + this.getPath());
414             }
415
416             // internal uuid links have a leading $
417
link = StringUtils.replace(link, "$", "\\$");
418
419             srcMatcher.appendReplacement(res, "$1" + link + "$5"); //$NON-NLS-1$
420
}
421         srcMatcher.appendTail(res);
422         valueStr = res.toString();
423         return valueStr;
424     }
425
426     /**
427      * Process a common value
428      * @param node node where the data must be stored
429      * @param name name of the field
430      * @param type type
431      * @param valueType internal value type (according to ControlImpl)
432      * @param encoding must we encode (base64)
433      * @param values all values belonging to this field
434      * @throws PathNotFoundException exception
435      * @throws RepositoryException exception
436      * @throws AccessDeniedException exception
437      */

438     protected void processCommon(Content node, String JavaDoc name, int type, int valueType, int encoding, String JavaDoc[] values)
439         throws PathNotFoundException, RepositoryException, AccessDeniedException {
440         String JavaDoc valueStr = StringUtils.EMPTY;
441         if (values != null) {
442             valueStr = values[0]; // values is null when the expected field would not exis, e.g no
443
}
444
445         processString(node, name, type, encoding, values, valueStr);
446     }
447
448     /**
449      * Process a string. This method will encode it
450      * @param node
451      * @param name
452      * @param type
453      * @param encoding
454      * @param values
455      * @param valueStr
456      * @throws PathNotFoundException
457      * @throws RepositoryException
458      * @throws AccessDeniedException
459      */

460     protected void processString(Content node, String JavaDoc name, int type, int encoding, String JavaDoc[] values, String JavaDoc valueStr)
461         throws PathNotFoundException, RepositoryException, AccessDeniedException {
462         // actualy encoding does only work for control password
463
boolean remove = false;
464         boolean write = false;
465         if (encoding == ControlImpl.ENCODING_BASE64) {
466             if (StringUtils.isNotBlank(valueStr)) {
467                 valueStr = new String JavaDoc(Base64.encodeBase64(valueStr.getBytes()));
468                 write = true;
469             }
470         }
471         else if (encoding == ControlImpl.ENCODING_UNIX) {
472             if (StringUtils.isNotEmpty(valueStr)) {
473                 valueStr = Digester.getSHA1Hex(valueStr);
474                 write = true;
475             }
476         }
477         else {
478             // no encoding
479
if (values == null || StringUtils.isEmpty(valueStr)) {
480                 remove = true;
481             }
482             else {
483                 write = true;
484             }
485         }
486         if (remove) {
487             processRemoveCommon(node, name);
488         }
489         else if (write) {
490             processWriteCommon(node, name, valueStr, type);
491         }
492     }
493
494     /**
495      * Remove the specified property on the node.
496      */

497     protected void processRemoveCommon(Content node, String JavaDoc name) throws PathNotFoundException, RepositoryException {
498         NodeData data = node.getNodeData(name);
499
500         if (data.isExist()) {
501             node.deleteNodeData(name);
502         }
503     }
504
505     /**
506      * Writes a property value.
507      * @param node the node
508      * @param name the property name to be written
509      * @param valueStr the value of the property
510      * @throws AccessDeniedException thrown if the write access is not granted
511      * @throws RepositoryException thrown if other repository exception is thrown
512      */

513     protected void processWriteCommon(Content node, String JavaDoc name, String JavaDoc valueStr, int type)
514         throws AccessDeniedException, RepositoryException {
515         Value value = this.getValue(valueStr, type);
516         if (null != value) {
517             NodeData data = NodeDataUtil.getOrCreate(node, name);
518             data.setValue(value);
519         }
520     }
521
522     /**
523      * Process a multiple value field
524      * @param node
525      * @param name
526      * @param type
527      * @param values
528      * @throws RepositoryException
529      * @throws PathNotFoundException
530      * @throws AccessDeniedException
531      */

532     protected void processMultiple(Content node, String JavaDoc name, int type, String JavaDoc[] values) throws RepositoryException,
533         PathNotFoundException, AccessDeniedException {
534         // remove entire content node and (re-)write each
535
try {
536             node.delete(name);
537         }
538         catch (PathNotFoundException e) {
539             if (log.isDebugEnabled()) {
540                 log.debug("Exception caught: " + e.getMessage(), e); //$NON-NLS-1$
541
}
542         }
543         if (values != null && values.length != 0) {
544             Content multiNode = node.createContent(name, ItemType.CONTENTNODE);
545             try {
546                 // MetaData.CREATION_DATE has private access; no method to delete it so far...
547
multiNode.deleteNodeData("creationdate"); //$NON-NLS-1$
548
}
549             catch (RepositoryException re) {
550                 if (log.isDebugEnabled()) {
551                     log.debug("Exception caught: " + re.getMessage(), re); //$NON-NLS-1$
552
}
553             }
554             for (int j = 0; j < values.length; j++) {
555                 String JavaDoc valueStr = values[j];
556                 if (StringUtils.isNotEmpty(valueStr)) {
557                     Value value = this.getValue(valueStr, type);
558                     multiNode.createNodeData(Integer.toString(j)).setValue(value);
559                 }
560             }
561         }
562     }
563
564     /**
565      * Process binary data. File- or imageupload.
566      * @param node
567      * @param name
568      * @throws PathNotFoundException
569      * @throws RepositoryException
570      * @throws AccessDeniedException
571      */

572     protected void processBinary(Content node, String JavaDoc name) throws PathNotFoundException, RepositoryException,
573         AccessDeniedException {
574         Document doc = getForm().getDocument(name);
575         if (doc == null && getForm().getParameter(name + "_" + File.REMOVE) != null) { //$NON-NLS-1$
576
try {
577                 node.deleteNodeData(name);
578             }
579             catch (RepositoryException re) {
580                 if (log.isDebugEnabled()) {
581                     log.debug("Exception caught: " + re.getMessage(), re); //$NON-NLS-1$
582
}
583             }
584         }
585         else {
586             String JavaDoc fileName = getForm().getParameter(name + "_" + FileProperties.PROPERTY_FILENAME);
587             String JavaDoc template = getForm().getParameter(name + "_" + FileProperties.PROPERTY_TEMPLATE);
588
589             SaveHandlerImpl.saveDocument(node, doc, name, fileName, template);
590         }
591     }
592
593     /**
594      * Get a string value
595      * @param s
596      * @return the value
597      */

598     public Value getValue(String JavaDoc s) {
599         return this.getValue(s, PropertyType.STRING);
600     }
601
602     /**
603      * Get the long value
604      * @param l
605      * @return the value
606      */

607     public Value getValue(long l) {
608         HierarchyManager hm = MgnlContext.getHierarchyManager(this.getRepository());
609         ValueFactory valueFactory;
610         try {
611             valueFactory = hm.getWorkspace().getSession().getValueFactory();
612         }
613         catch (RepositoryException e) {
614             throw new NestableRuntimeException(e);
615         }
616         return valueFactory.createValue(l);
617     }
618
619     /**
620      * Get the value for saving in jcr
621      * @param valueStr string representation of the value
622      * @param type type of the value
623      * @return the value
624      */

625     public Value getValue(String JavaDoc valueStr, int type) {
626
627         ValueFactory valueFactory = null;
628
629         HierarchyManager hm = MgnlContext.getHierarchyManager(this.getRepository());
630         try {
631             valueFactory = hm.getWorkspace().getSession().getValueFactory();
632         }
633         catch (RepositoryException e) {
634             throw new NestableRuntimeException(e);
635         }
636
637         Value value = null;
638
639         if (type == PropertyType.REFERENCE) {
640             try {
641                 Node referencedNode = hm.getWorkspace().getSession().getNodeByUUID(valueStr);
642
643                 value = valueFactory.createValue(referencedNode);
644             }
645             catch (RepositoryException re) {
646                 if (log.isDebugEnabled()) {
647                     log.debug("Cannot retrieve the referenced node by UUID: " + valueStr, re);
648                 }
649             }
650         }
651         else {
652             value = NodeDataUtil.getValue(valueStr, type, valueFactory);
653         }
654
655         return value;
656     }
657
658     /**
659      * @param value
660      * @param tagName
661      */

662     protected static String JavaDoc replacePByBr(final String JavaDoc value, String JavaDoc tagName) {
663
664         if (StringUtils.isBlank(value)) {
665             return value;
666         }
667
668         String JavaDoc fixedValue = value;
669
670         String JavaDoc pre = "<" + tagName + ">"; //$NON-NLS-1$ //$NON-NLS-2$
671
String JavaDoc post = "</" + tagName + ">"; //$NON-NLS-1$ //$NON-NLS-2$
672

673         // get rid of last </p>
674
if (fixedValue.endsWith(post)) {
675             fixedValue = StringUtils.substringBeforeLast(fixedValue, post);
676         }
677
678         fixedValue = StringUtils.replace(fixedValue, pre + "&nbsp;" + post, "\n "); //$NON-NLS-1$ //$NON-NLS-2$
679
fixedValue = StringUtils.replace(fixedValue, pre, StringUtils.EMPTY);
680         fixedValue = StringUtils.replace(fixedValue, post, "\n\n "); //$NON-NLS-1$
681

682         if (!tagName.equals(tagName.toUpperCase())) {
683             fixedValue = replacePByBr(fixedValue, tagName.toUpperCase());
684         }
685         return fixedValue;
686     }
687
688     /**
689      * @see info.magnolia.module.admininterface.SaveHandler#isCreate()
690      */

691     public boolean isCreate() {
692         return create;
693     }
694
695     /**
696      * @see info.magnolia.module.admininterface.SaveHandler#setCreate(boolean)
697      */

698     public void setCreate(boolean create) {
699         this.create = create;
700     }
701
702     /**
703      * @see info.magnolia.module.admininterface.SaveHandler#getCreationItemType()
704      */

705     public ItemType getCreationItemType() {
706         return creationItemType;
707     }
708
709     /**
710      * @see info.magnolia.module.admininterface.SaveHandler#setCreationItemType(info.magnolia.cms.core.ItemType)
711      */

712     public void setCreationItemType(ItemType creationItemType) {
713         this.creationItemType = creationItemType;
714     }
715
716     /**
717      * @return the form containing the values passed
718      */

719     protected MultipartForm getForm() {
720         return form;
721     }
722
723     /**
724      * set the from
725      * @param form containing the sended values
726      */

727     protected void setForm(MultipartForm form) {
728         this.form = form;
729     }
730
731     /**
732      * set the name of the repository saving to
733      * @param repository the name of the repository
734      */

735     public void setRepository(String JavaDoc repository) {
736         this.repository = repository;
737     }
738
739     /**
740      * get the name of thre repository saving to
741      * @return name
742      */

743     public String JavaDoc getRepository() {
744         return repository;
745     }
746
747     /**
748      * Returns the page. The page is created if not yet existing depending on the property create
749      * @param hm
750      * @return the node
751      * @throws RepositoryException
752      * @throws AccessDeniedException
753      * @throws PathNotFoundException
754      */

755     protected Content getPageNode(HierarchyManager hm) throws RepositoryException, AccessDeniedException,
756         PathNotFoundException {
757         Content page = null;
758         String JavaDoc path = this.getPath();
759         try {
760             page = hm.getContent(path);
761         }
762         catch (RepositoryException e) {
763             if (this.isCreate()) {
764                 String JavaDoc parentPath = StringUtils.substringBeforeLast(path, "/"); //$NON-NLS-1$
765
String JavaDoc label = StringUtils.substringAfterLast(path, "/"); //$NON-NLS-1$
766
if (StringUtils.isEmpty(parentPath)) {
767                     page = hm.getRoot();
768                 }
769                 else {
770                     page = hm.getContent(parentPath);
771                 }
772                 page = page.createContent(label, this.getCreationItemType());
773             }
774             else {
775                 log.error("Tried to save a not existing node with path {}. use create = true to force creation", path); //$NON-NLS-1$
776
}
777         }
778         return page;
779     }
780
781     /**
782      * Gets or creates the node saving to.
783      * @param hm
784      * @param rootNode the node containing the saving node. If both the nodeCollectionName and the nodeName are empty
785      * this is the returned node.
786      * @return the node to which the content is saved
787      * @throws AccessDeniedException
788      * @throws RepositoryException
789      */

790     protected Content getSaveNode(HierarchyManager hm, Content rootNode) throws AccessDeniedException,
791         RepositoryException {
792         Content node = null;
793
794         // get or create nodeCollection
795
Content nodeCollection = null;
796         if (StringUtils.isNotEmpty(this.getNodeCollectionName())) {
797             try {
798                 nodeCollection = rootNode.getContent(this.getNodeCollectionName());
799             }
800             catch (RepositoryException re) {
801                 // nodeCollection does not exist -> create
802
nodeCollection = rootNode.createContent(this.getNodeCollectionName(), ItemType.CONTENTNODE);
803                 if (log.isDebugEnabled()) {
804                     log.debug("Create - " + nodeCollection.getHandle()); //$NON-NLS-1$
805
}
806             }
807         }
808         else {
809             nodeCollection = rootNode;
810         }
811
812         // get or create node
813
if (StringUtils.isNotEmpty(this.getNodeName())) {
814             try {
815                 node = nodeCollection.getContent(this.getNodeName());
816             }
817             catch (RepositoryException re) {
818                 // node does not exist -> create
819
if (this.getNodeName().equals("mgnlNew")) { //$NON-NLS-1$
820
this.setNodeName(Path.getUniqueLabel(hm, nodeCollection.getHandle(), "0")); //$NON-NLS-1$
821
}
822                 node = nodeCollection.createContent(this.getNodeName(), this.getCreationItemType());
823             }
824         }
825         else {
826             node = nodeCollection;
827         }
828         return node;
829     }
830
831     /**
832      * Saves a uploaded file in the magnolia way. It creates a subnode name_properties where all the information like
833      * the mime type is stored.
834      * @param node the node under which the data is stored
835      * @param name the name of the nodedata to store the data into
836      * @param fileName If empty the original filename is used
837      * @param template can be empty
838      * @throws PathNotFoundException
839      * @throws RepositoryException
840      * @throws AccessDeniedException
841      */

842     public static void saveDocument(Content node, Document doc, String JavaDoc name, String JavaDoc fileName, String JavaDoc template)
843         throws PathNotFoundException, RepositoryException, AccessDeniedException {
844
845         NodeData data = node.getNodeData(name);
846         if (doc != null) {
847             if (!data.isExist()) {
848                 data = node.createNodeData(name, PropertyType.BINARY);
849
850                 log.debug("creating under - {}", node.getHandle()); //$NON-NLS-1$
851
log.debug("creating node data for binary store - {}", name); //$NON-NLS-1$
852

853             }
854             data.setValue(doc.getStream());
855             if (log.isDebugEnabled()) {
856                 log.debug("Node data updated"); //$NON-NLS-1$
857
}
858         }
859         if (data != null) {
860             if (fileName == null || fileName.equals(StringUtils.EMPTY)) {
861                 fileName = doc.getFileName();
862             }
863             data.setAttribute(FileProperties.PROPERTY_FILENAME, fileName);
864             if (doc != null) {
865                 data.setAttribute(FileProperties.PROPERTY_CONTENTTYPE, doc.getType());
866
867                 Calendar JavaDoc value = new GregorianCalendar JavaDoc(TimeZone.getDefault());
868                 data.setAttribute(FileProperties.PROPERTY_LASTMODIFIED, value);
869
870                 data.setAttribute(FileProperties.PROPERTY_SIZE, Long.toString(doc.getLength()));
871
872                 data.setAttribute(FileProperties.PROPERTY_EXTENSION, doc.getExtension());
873
874                 data.setAttribute(FileProperties.PROPERTY_TEMPLATE, template);
875
876                 InputStream JavaDoc raf = null;
877                 try {
878                     ImageInfo ii = new ImageInfo();
879                     raf = new FileInputStream JavaDoc(doc.getFile());
880                     ii.setInput(raf);
881                     if (ii.check()) {
882                         data.setAttribute(FileProperties.PROPERTY_WIDTH, Long.toString(ii.getWidth()));
883                         data.setAttribute(FileProperties.PROPERTY_HEIGHT, Long.toString(ii.getHeight()));
884                         // data.setAttribute(FileProperties.x, Long.toString(ii.getBitsPerPixel()));
885
}
886                 }
887                 catch (FileNotFoundException JavaDoc e) {
888                     log.error("FileNotFoundException caught when parsing {}, image data will not be available", doc
889                         .getFile()
890                         .getAbsolutePath());
891                 }
892                 finally {
893                     IOUtils.closeQuietly(raf);
894                 }
895
896                 // TODO: check this
897
// deleting all the documents in the form AFTER the complete save is done, since some other field save
898
// could need the same file.
899
// doc.delete();
900
}
901         }
902
903     }
904
905     /**
906      * @see info.magnolia.module.admininterface.SaveHandler#getNodeCollectionName()
907      */

908     public String JavaDoc getNodeCollectionName() {
909         return this.nodeCollectionName;
910     }
911
912     /**
913      * @see info.magnolia.module.admininterface.SaveHandler#setNodeCollectionName(java.lang.String)
914      */

915     public void setNodeCollectionName(String JavaDoc nodeCollectionName) {
916         this.nodeCollectionName = nodeCollectionName;
917     }
918
919     /**
920      * @see info.magnolia.module.admininterface.SaveHandler#getNodeName()
921      */

922     public String JavaDoc getNodeName() {
923         return this.nodeName;
924     }
925
926     /**
927      * @see info.magnolia.module.admininterface.SaveHandler#setNodeName(java.lang.String)
928      */

929     public void setNodeName(String JavaDoc nodeName) {
930         this.nodeName = nodeName;
931     }
932
933     /**
934      * @see info.magnolia.module.admininterface.SaveHandler#getParagraph()
935      */

936     public String JavaDoc getParagraph() {
937         return this.paragraph;
938     }
939
940     /**
941      * @see info.magnolia.module.admininterface.SaveHandler#setParagraph(java.lang.String)
942      */

943     public void setParagraph(String JavaDoc paragraph) {
944         this.paragraph = paragraph;
945     }
946
947     /**
948      * @see info.magnolia.module.admininterface.SaveHandler#getPath()
949      */

950     public String JavaDoc getPath() {
951         return this.path;
952     }
953
954     /**
955      * @see info.magnolia.module.admininterface.SaveHandler#setPath(java.lang.String)
956      */

957     public void setPath(String JavaDoc path) {
958         this.path = path;
959     }
960
961 }
Popular Tags