001    /**
002     * Copyright (c) 2000-2012 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.portal.kernel.templateparser;
016    
017    import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
018    import com.liferay.portal.kernel.mobile.device.Device;
019    import com.liferay.portal.kernel.mobile.device.UnknownDevice;
020    import com.liferay.portal.kernel.util.GetterUtil;
021    import com.liferay.portal.kernel.util.LocaleUtil;
022    import com.liferay.portal.kernel.util.StringBundler;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.kernel.util.Validator;
025    import com.liferay.portal.kernel.xml.Document;
026    import com.liferay.portal.kernel.xml.DocumentException;
027    import com.liferay.portal.kernel.xml.Element;
028    import com.liferay.portal.kernel.xml.SAXReaderUtil;
029    import com.liferay.portal.model.Company;
030    import com.liferay.portal.security.permission.PermissionThreadLocal;
031    import com.liferay.portal.service.CompanyLocalServiceUtil;
032    import com.liferay.portal.theme.ThemeDisplay;
033    
034    import java.io.IOException;
035    
036    import java.util.ArrayList;
037    import java.util.HashMap;
038    import java.util.List;
039    import java.util.Locale;
040    import java.util.Map;
041    
042    /**
043     * @author Brian Wing Shun Chan
044     * @author Marcellus Tavares
045     */
046    public abstract class BaseTemplateParser implements TemplateParser {
047    
048            public String getLanguageId() {
049                    return _languageId;
050            }
051    
052            public String getScript() {
053                    return _script;
054            }
055    
056            public ThemeDisplay getThemeDisplay() {
057                    return _themeDisplay;
058            }
059    
060            public Map<String, String> getTokens() {
061                    return _tokens;
062            }
063    
064            public String getViewMode() {
065                    return _viewMode;
066            }
067    
068            public String getXML() {
069                    return _xml;
070            }
071    
072            public void setContextObjects(Map<String, Object> contextObjects) {
073                    _contextObjects = contextObjects;
074            }
075    
076            public void setLanguageId(String languageId) {
077                    _languageId = languageId;
078            }
079    
080            public void setScript(String script) {
081                    _script = script;
082            }
083    
084            public void setThemeDisplay(ThemeDisplay themeDisplay) {
085                    _themeDisplay = themeDisplay;
086            }
087    
088            public void setTokens(Map<String, String> tokens) {
089                    _tokens = tokens;
090            }
091    
092            public void setViewMode(String viewMode) {
093                    _viewMode = viewMode;
094            }
095    
096            public void setXML(String xml) {
097                    _xml = xml;
098            }
099    
100            public String transform() throws TransformException {
101                    UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();
102    
103                    boolean load = false;
104    
105                    try {
106                            TemplateContext templateContext = getTemplateContext();
107    
108                            if (Validator.isNotNull(_xml)) {
109                                    Document document = SAXReaderUtil.read(_xml);
110    
111                                    Element rootElement = document.getRootElement();
112    
113                                    List<TemplateNode> templateNodes = getTemplateNodes(
114                                            rootElement);
115    
116                                    if (templateNodes != null) {
117                                            for (TemplateNode templateNode : templateNodes) {
118                                                    templateContext.put(
119                                                            templateNode.getName(), templateNode);
120                                            }
121                                    }
122    
123                                    Element requestElement = rootElement.element("request");
124    
125                                    templateContext.put(
126                                            "request", insertRequestVariables(requestElement));
127    
128                                    templateContext.put("xmlRequest", requestElement.asXML());
129                            }
130    
131                            if (_contextObjects != null) {
132                                    for (String key : _contextObjects.keySet()) {
133                                            templateContext.put(key, _contextObjects.get(key));
134                                    }
135                            }
136    
137                            populateTemplateContext(templateContext);
138    
139                            load = mergeTemplate(templateContext, unsyncStringWriter);
140                    }
141                    catch (Exception e) {
142                            if (e instanceof DocumentException) {
143                                    throw new TransformException("Unable to read XML document", e);
144                            }
145                            else if (e instanceof IOException) {
146                                    throw new TransformException("Error reading template", e);
147                            }
148                            else if (e instanceof TransformException) {
149                                    throw (TransformException)e;
150                            }
151                            else {
152                                    throw new TransformException("Unhandled exception", e);
153                            }
154                    }
155    
156                    if (!load) {
157                            throw new TransformException(
158                                    "Unable to dynamically load transform script");
159                    }
160    
161                    return unsyncStringWriter.toString();
162            }
163    
164            protected Company getCompany() throws Exception {
165                    if (_themeDisplay != null) {
166                            return _themeDisplay.getCompany();
167                    }
168    
169                    return CompanyLocalServiceUtil.getCompany(getCompanyId());
170            }
171    
172            protected long getCompanyGroupId() {
173                    if (_themeDisplay != null) {
174                            return _themeDisplay.getCompanyGroupId();
175                    }
176    
177                    return GetterUtil.getLong(_tokens.get("company_group_id"));
178            }
179    
180            protected long getCompanyId() {
181                    if (_themeDisplay != null) {
182                            return _themeDisplay.getCompanyId();
183                    }
184    
185                    return GetterUtil.getLong(_tokens.get("company_id"));
186            }
187    
188            protected Device getDevice() {
189                    if (_themeDisplay != null) {
190                            return _themeDisplay.getDevice();
191                    }
192    
193                    return UnknownDevice.getInstance();
194            }
195    
196            protected long getGroupId() {
197                    if (_themeDisplay != null) {
198                            return _themeDisplay.getScopeGroupId();
199                    }
200    
201                    return GetterUtil.getLong(_tokens.get("group_id"));
202            }
203    
204            protected abstract TemplateContext getTemplateContext() throws Exception;
205    
206            protected String getTemplateId() {
207                    long companyGroupId = getCompanyGroupId();
208    
209                    String templateId = null;
210    
211                    if (_tokens != null) {
212                            templateId = _tokens.get("template_id");
213                    }
214    
215                    if (Validator.isNull(templateId)) {
216                            templateId = (String.valueOf(_contextObjects.get("template_id")));
217                    }
218    
219                    StringBundler sb = new StringBundler(5);
220    
221                    sb.append(getCompanyId());
222                    sb.append(StringPool.POUND);
223    
224                    if (companyGroupId > 0) {
225                            sb.append(companyGroupId);
226                    }
227                    else {
228                            sb.append(getGroupId());
229                    }
230    
231                    sb.append(StringPool.POUND);
232                    sb.append(templateId);
233    
234                    return sb.toString();
235            }
236    
237            protected abstract List<TemplateNode> getTemplateNodes(Element element)
238                    throws Exception;
239    
240            protected Map<String, Object> insertRequestVariables(Element element) {
241                    Map<String, Object> map = new HashMap<String, Object>();
242    
243                    if (element == null) {
244                            return map;
245                    }
246    
247                    for (Element childElement : element.elements()) {
248                            String name = childElement.getName();
249    
250                            if (name.equals("attribute")) {
251                                    Element nameElement = childElement.element("name");
252                                    Element valueElement = childElement.element("value");
253    
254                                    map.put(nameElement.getText(), valueElement.getText());
255                            }
256                            else if (name.equals("parameter")) {
257                                    Element nameElement = childElement.element("name");
258    
259                                    List<Element> valueElements = childElement.elements("value");
260    
261                                    if (valueElements.size() == 1) {
262                                            Element valueElement = valueElements.get(0);
263    
264                                            map.put(nameElement.getText(), valueElement.getText());
265                                    }
266                                    else {
267                                            List<String> values = new ArrayList<String>();
268    
269                                            for (Element valueElement : valueElements) {
270                                                    values.add(valueElement.getText());
271                                            }
272    
273                                            map.put(nameElement.getText(), values);
274                                    }
275                            }
276                            else if (childElement.elements().size() > 0) {
277                                    map.put(name, insertRequestVariables(childElement));
278                            }
279                            else {
280                                    map.put(name, childElement.getText());
281                            }
282                    }
283    
284                    return map;
285            }
286    
287            protected abstract boolean mergeTemplate(
288                            TemplateContext templateContext,
289                            UnsyncStringWriter unsyncStringWriter)
290                    throws Exception;
291    
292            protected void populateTemplateContext(TemplateContext templateContext)
293                    throws Exception {
294    
295                    templateContext.put("company", getCompany());
296                    templateContext.put("companyId", getCompanyId());
297                    templateContext.put("device", getDevice());
298                    templateContext.put("groupId", getGroupId());
299    
300                    Locale locale = LocaleUtil.fromLanguageId(_languageId);
301    
302                    templateContext.put("locale", locale);
303    
304                    templateContext.put(
305                            "permissionChecker", PermissionThreadLocal.getPermissionChecker());
306                    templateContext.put("viewMode", _viewMode);
307            }
308    
309            private Map<String, Object> _contextObjects = new HashMap<String, Object>();
310            private String _languageId;
311            private String _script;
312            private ThemeDisplay _themeDisplay;
313            private Map<String, String> _tokens;
314            private String _viewMode;
315            private String _xml;
316    
317    }