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