001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.journal.util;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.templateparser.BaseTransformerListener;
020    import com.liferay.portal.kernel.util.GetterUtil;
021    import com.liferay.portal.kernel.util.HtmlUtil;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portal.kernel.util.StringUtil;
024    import com.liferay.portal.kernel.util.Validator;
025    import com.liferay.portal.kernel.xml.Document;
026    import com.liferay.portal.kernel.xml.Element;
027    import com.liferay.portal.kernel.xml.Node;
028    import com.liferay.portal.kernel.xml.SAXReaderUtil;
029    import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
030    import com.liferay.portlet.journal.model.JournalArticle;
031    import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
032    
033    import java.util.List;
034    import java.util.Map;
035    
036    /**
037     * @author Brian Wing Shun Chan
038     */
039    public class ContentTransformerListener extends BaseTransformerListener {
040    
041            @Override
042            public String onOutput(String s) {
043                    if (_log.isDebugEnabled()) {
044                            _log.debug("onOutput");
045                    }
046    
047                    return s;
048            }
049    
050            @Override
051            public String onScript(String s) {
052                    if (_log.isDebugEnabled()) {
053                            _log.debug("onScript");
054                    }
055    
056                    s = injectEditInPlace(_xml, s);
057    
058                    return s;
059            }
060    
061            @Override
062            public String onXml(String s) {
063                    if (_log.isDebugEnabled()) {
064                            _log.debug("onXml");
065                    }
066    
067                    _xml = replace(s);
068    
069                    return _xml;
070            }
071    
072            protected String getDynamicContent(String xml, String elementName) {
073                    String content = null;
074    
075                    try {
076                            Document document = SAXReaderUtil.read(xml);
077    
078                            Element rootElement = document.getRootElement();
079    
080                            for (Element element : rootElement.elements()) {
081                                    String curElementName = element.attributeValue(
082                                            "name", StringPool.BLANK);
083    
084                                    if (curElementName.equals(elementName)) {
085                                            content = element.elementText("dynamic-content");
086    
087                                            break;
088                                    }
089                            }
090                    }
091                    catch (Exception e) {
092                            _log.error(e, e);
093                    }
094    
095                    return GetterUtil.getString(content);
096            }
097    
098            protected String injectEditInPlace(String xml, String script) {
099                    try {
100                            Document document = SAXReaderUtil.read(xml);
101    
102                            List<Node> nodes = document.selectNodes("//dynamic-element");
103    
104                            for (Node node : nodes) {
105                                    Element element = (Element)node;
106    
107                                    String name = GetterUtil.getString(
108                                            element.attributeValue("name"));
109                                    String type = GetterUtil.getString(
110                                            element.attributeValue("type"));
111    
112                                    if (!name.startsWith("reserved-") &&
113                                            (type.equals("text") || type.equals("text_area") ||
114                                             type.equals("text_box"))) {
115    
116                                            script = wrapEditInPlaceField(script, name, type, "data");
117                                            script = wrapEditInPlaceField(
118                                                    script, name, type, "getData()");
119                                    }
120                            }
121                    }
122                    catch (Exception e) {
123                            _log.warn(e.getMessage());
124                    }
125    
126                    return script;
127            }
128    
129            protected void replace(Element root) throws Exception {
130                    Map<String, String> tokens = getTokens();
131    
132                    long groupId = GetterUtil.getLong(tokens.get("group_id"));
133    
134                    for (Element el : root.elements()) {
135                            Element dynamicContent = el.element("dynamic-content");
136    
137                            if (dynamicContent != null) {
138                                    String text = dynamicContent.getText();
139    
140                                    text = HtmlUtil.stripComments(text);
141                                    text = HtmlUtil.stripHtml(text);
142                                    text = text.trim();
143    
144                                    // [@articleId;elementName@]
145    
146                                    if (Validator.isNotNull(text) && (text.length() >= 7) &&
147                                            text.startsWith("[@") && text.endsWith("@]")) {
148    
149                                            text = text.substring(2, text.length() - 2);
150    
151                                            int pos = text.indexOf(";");
152    
153                                            if (pos != -1) {
154                                                    String articleId = text.substring(0, pos);
155                                                    String elementName = text.substring(pos + 1);
156    
157                                                    JournalArticle article =
158                                                            JournalArticleLocalServiceUtil.getArticle(
159                                                                    groupId, articleId);
160    
161                                                    dynamicContent.clearContent();
162                                                    dynamicContent.addCDATA(
163                                                            getDynamicContent(
164                                                                    article.getContent(), elementName));
165                                            }
166                                    }
167    
168                                    // Make sure to point images to the full path
169    
170                                    else if ((text != null) &&
171                                                     text.startsWith("/image/journal/article?img_id")) {
172    
173                                            dynamicContent.setText("@cdn_host@@root_path@" + text);
174                                    }
175                            }
176    
177                            replace(el);
178                    }
179            }
180    
181            /**
182             * Fill one article with content from another approved article. See the
183             * article DOCUMENTATION-INSTALLATION-BORLAND for a sample use case.
184             *
185             * @return the processed string
186             */
187            protected String replace(String xml) {
188                    try {
189                            Document document = SAXReaderUtil.read(xml);
190    
191                            Element rootElement = document.getRootElement();
192    
193                            replace(rootElement);
194    
195                            xml = DDMXMLUtil.formatXML(document);
196                    }
197                    catch (Exception e) {
198                            _log.warn(e.getMessage());
199                    }
200    
201                    return xml;
202            }
203    
204            protected String wrapEditInPlaceField(
205                    String script, String name, String type, String call) {
206    
207                    String field = "$" + name + "." + call;
208                    String wrappedField =
209                            "<span class=\"journal-content-eip-" + type + "\" " +
210                                    "id=\"journal-content-field-name-" + name + "\">" + field +
211                                            "</span>";
212    
213                    return StringUtil.replace(
214                            script, "$editInPlace(" + field + ")", wrappedField);
215            }
216    
217            private static Log _log = LogFactoryUtil.getLog(
218                    ContentTransformerListener.class);
219    
220            private String _xml;
221    
222    }