
com.liferay.journal.transformer.JournalTransformer Maven / Gradle / Ivy
/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.journal.transformer;
import com.liferay.dynamic.data.mapping.model.DDMForm;
import com.liferay.dynamic.data.mapping.model.DDMFormField;
import com.liferay.dynamic.data.mapping.model.DDMFormFieldOptions;
import com.liferay.dynamic.data.mapping.model.DDMStructure;
import com.liferay.dynamic.data.mapping.model.LocalizedValue;
import com.liferay.dynamic.data.mapping.service.DDMStructureLocalServiceUtil;
import com.liferay.portal.kernel.configuration.Configuration;
import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil;
import com.liferay.portal.kernel.configuration.Filter;
import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.mobile.device.Device;
import com.liferay.portal.kernel.mobile.device.UnknownDevice;
import com.liferay.portal.kernel.model.Company;
import com.liferay.portal.kernel.portlet.PortletRequestModel;
import com.liferay.portal.kernel.security.permission.PermissionThreadLocal;
import com.liferay.portal.kernel.service.CompanyLocalServiceUtil;
import com.liferay.portal.kernel.template.StringTemplateResource;
import com.liferay.portal.kernel.template.Template;
import com.liferay.portal.kernel.template.TemplateConstants;
import com.liferay.portal.kernel.template.TemplateManager;
import com.liferay.portal.kernel.template.TemplateManagerUtil;
import com.liferay.portal.kernel.template.TemplateResource;
import com.liferay.portal.kernel.template.URLTemplateResource;
import com.liferay.portal.kernel.templateparser.TemplateNode;
import com.liferay.portal.kernel.templateparser.TransformException;
import com.liferay.portal.kernel.templateparser.TransformerListener;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.util.Constants;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.InstanceFactory;
import com.liferay.portal.kernel.util.LocaleUtil;
import com.liferay.portal.kernel.util.LocalizationUtil;
import com.liferay.portal.kernel.util.PropertiesUtil;
import com.liferay.portal.kernel.util.SetUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.xml.Attribute;
import com.liferay.portal.kernel.xml.Document;
import com.liferay.portal.kernel.xml.DocumentException;
import com.liferay.portal.kernel.xml.Element;
import com.liferay.portal.kernel.xml.SAXReaderUtil;
import com.liferay.portal.xsl.XSLTemplateResource;
import com.liferay.portal.xsl.XSLURIResolver;
import com.liferay.taglib.servlet.PipingServletResponse;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
/**
* @author Brian Wing Shun Chan
* @author Raymond Augé
* @author Wesley Gong
* @author Angelo Jefferson
* @author Hugo Huijser
* @author Marcellus Tavares
* @author Juan Fernández
* @author Eduardo Garcia
*/
public class JournalTransformer {
public JournalTransformer(
String errorTemplatePropertyKey, boolean restricted) {
ClassLoader classLoader = getClassLoader();
Configuration configuration = ConfigurationFactoryUtil.getConfiguration(
classLoader, "portlet");
Set langTypes = TemplateManagerUtil.getSupportedLanguageTypes(
errorTemplatePropertyKey);
for (String langType : langTypes) {
String errorTemplateId = configuration.get(
errorTemplatePropertyKey, new Filter(langType));
if (Validator.isNotNull(errorTemplateId)) {
_errorTemplateIds.put(langType, errorTemplateId);
}
}
_restricted = restricted;
}
public JournalTransformer(
String transformerListenerPropertyKey, String errorTemplatePropertyKey,
boolean restricted) {
this(errorTemplatePropertyKey, restricted);
ClassLoader classLoader = getClassLoader();
Configuration configuration = ConfigurationFactoryUtil.getConfiguration(
classLoader, "portlet");
Set transformerListenerClassNames = SetUtil.fromArray(
configuration.getArray(transformerListenerPropertyKey));
for (String transformerListenerClassName :
transformerListenerClassNames) {
try {
if (_log.isDebugEnabled()) {
_log.debug(
"Instantiating transformer listener " +
transformerListenerClassName);
}
TransformerListener transformerListener =
(TransformerListener)InstanceFactory.newInstance(
classLoader, transformerListenerClassName);
_transformerListeners.add(transformerListener);
}
catch (Exception e) {
_log.error(e, e);
}
}
}
public String transform(
ThemeDisplay themeDisplay, Map contextObjects,
Map tokens, String viewMode, String languageId,
Document document, PortletRequestModel portletRequestModel,
String script, String langType, boolean propagateException)
throws Exception {
return doTransform(
themeDisplay, contextObjects, tokens, viewMode, languageId,
document, portletRequestModel, script, langType,
propagateException);
}
public String transform(
ThemeDisplay themeDisplay, Map tokens,
String viewMode, String languageId, Document document,
PortletRequestModel portletRequestModel, String script,
String langType)
throws Exception {
return doTransform(
themeDisplay, null, tokens, viewMode, languageId, document,
portletRequestModel, script, langType, false);
}
public String transform(
ThemeDisplay themeDisplay, Map tokens,
String viewMode, String languageId, Document document,
PortletRequestModel portletRequestModel, String script,
String langType, boolean propagateException)
throws Exception {
return doTransform(
themeDisplay, null, tokens, viewMode, languageId, document,
portletRequestModel, script, langType, propagateException);
}
protected String doTransform(
ThemeDisplay themeDisplay, Map contextObjects,
Map tokens, String viewMode, String languageId,
Document document, PortletRequestModel portletRequestModel,
String script, String langType, boolean propagateException)
throws Exception {
// Setup listeners
if (_log.isDebugEnabled()) {
_log.debug("Language " + languageId);
}
if (Validator.isNull(viewMode)) {
viewMode = Constants.VIEW;
}
if (_logTokens.isDebugEnabled()) {
String tokensString = PropertiesUtil.list(tokens);
_logTokens.debug(tokensString);
}
if (_logTransformBefore.isDebugEnabled()) {
_logTransformBefore.debug(document);
}
for (TransformerListener transformerListener : _transformerListeners) {
// Modify XML
if (_logXmlBeforeListener.isDebugEnabled()) {
_logXmlBeforeListener.debug(document);
}
if (transformerListener != null) {
document = transformerListener.onXml(
document, languageId, tokens);
if (_logXmlAfterListener.isDebugEnabled()) {
_logXmlAfterListener.debug(document);
}
}
// Modify script
if (_logScriptBeforeListener.isDebugEnabled()) {
_logScriptBeforeListener.debug(script);
}
if (transformerListener != null) {
script = transformerListener.onScript(
script, document, languageId, tokens);
if (_logScriptAfterListener.isDebugEnabled()) {
_logScriptAfterListener.debug(script);
}
}
}
// Transform
String output = null;
if (Validator.isNull(langType)) {
output = LocalizationUtil.getLocalization(
document.asXML(), languageId);
}
else {
long companyId = 0;
long companyGroupId = 0;
long articleGroupId = 0;
long classNameId = 0;
if (tokens != null) {
companyId = GetterUtil.getLong(tokens.get("company_id"));
companyGroupId = GetterUtil.getLong(
tokens.get("company_group_id"));
articleGroupId = GetterUtil.getLong(
tokens.get("article_group_id"));
classNameId = GetterUtil.getLong(
tokens.get(TemplateConstants.CLASS_NAME_ID));
}
long scopeGroupId = 0;
long siteGroupId = 0;
if (themeDisplay != null) {
companyId = themeDisplay.getCompanyId();
companyGroupId = themeDisplay.getCompanyGroupId();
scopeGroupId = themeDisplay.getScopeGroupId();
siteGroupId = themeDisplay.getSiteGroupId();
}
String templateId = tokens.get("template_id");
templateId = getTemplateId(
templateId, companyId, companyGroupId, articleGroupId);
Template template = getTemplate(
templateId, tokens, languageId, document, script, langType);
if (contextObjects != null) {
template.putAll(contextObjects);
}
UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();
try {
if (document != null) {
Element rootElement = document.getRootElement();
List templateNodes = getTemplateNodes(
themeDisplay, rootElement,
Long.valueOf(tokens.get("ddm_structure_id")));
if (templateNodes != null) {
for (TemplateNode templateNode : templateNodes) {
template.put(templateNode.getName(), templateNode);
}
}
if (portletRequestModel != null) {
template.put("request", portletRequestModel.toMap());
if (langType.equals(TemplateConstants.LANG_TYPE_XSL)) {
Document requestDocument = SAXReaderUtil.read(
portletRequestModel.toXML());
Element requestElement =
requestDocument.getRootElement();
template.put("xmlRequest", requestElement.asXML());
}
}
else {
Element requestElement = rootElement.element("request");
template.put(
"request", insertRequestVariables(requestElement));
if (langType.equals(TemplateConstants.LANG_TYPE_XSL)) {
template.put("xmlRequest", requestElement.asXML());
}
}
}
template.put("articleGroupId", articleGroupId);
template.put("company", getCompany(themeDisplay, companyId));
template.put("companyId", companyId);
template.put("device", getDevice(themeDisplay));
String templatesPath = getTemplatesPath(
companyId, articleGroupId, classNameId);
Locale locale = LocaleUtil.fromLanguageId(languageId);
template.put("locale", locale);
template.put(
"permissionChecker",
PermissionThreadLocal.getPermissionChecker());
template.put(
"randomNamespace",
StringUtil.randomId() + StringPool.UNDERLINE);
template.put("scopeGroupId", scopeGroupId);
template.put("siteGroupId", siteGroupId);
template.put("templatesPath", templatesPath);
template.put("viewMode", viewMode);
if (themeDisplay != null) {
TemplateManager templateManager =
TemplateManagerUtil.getTemplateManager(langType);
HttpServletRequest request = themeDisplay.getRequest();
templateManager.addTaglibSupport(
template, request, themeDisplay.getResponse());
templateManager.addTaglibTheme(
template, "taglibLiferay", request,
new PipingServletResponse(
themeDisplay.getResponse(), unsyncStringWriter));
}
// Deprecated variables
template.put("groupId", articleGroupId);
template.put("journalTemplatesPath", templatesPath);
mergeTemplate(template, unsyncStringWriter, propagateException);
}
catch (Exception e) {
if (e instanceof DocumentException) {
throw new TransformException(
"Unable to read XML document", e);
}
else if (e instanceof IOException) {
throw new TransformException("Error reading template", e);
}
else if (e instanceof TransformException) {
throw (TransformException)e;
}
else {
throw new TransformException("Unhandled exception", e);
}
}
output = unsyncStringWriter.toString();
}
// Postprocess output
for (TransformerListener transformerListener : _transformerListeners) {
// Modify output
if (_logOutputBeforeListener.isDebugEnabled()) {
_logOutputBeforeListener.debug(output);
}
output = transformerListener.onOutput(output, languageId, tokens);
if (_logOutputAfterListener.isDebugEnabled()) {
_logOutputAfterListener.debug(output);
}
}
if (_logTransfromAfter.isDebugEnabled()) {
_logTransfromAfter.debug(output);
}
return output;
}
protected ClassLoader getClassLoader() {
Class> clazz = getClass();
return clazz.getClassLoader();
}
protected Company getCompany(ThemeDisplay themeDisplay, long companyId)
throws Exception {
if (themeDisplay != null) {
return themeDisplay.getCompany();
}
return CompanyLocalServiceUtil.getCompany(companyId);
}
protected Device getDevice(ThemeDisplay themeDisplay) {
if (themeDisplay != null) {
return themeDisplay.getDevice();
}
return UnknownDevice.getInstance();
}
protected TemplateResource getErrorTemplateResource(String langType) {
try {
Class> clazz = getClass();
ClassLoader classLoader = clazz.getClassLoader();
String errorTemplateId = _errorTemplateIds.get(langType);
URL url = classLoader.getResource(errorTemplateId);
return new URLTemplateResource(errorTemplateId, url);
}
catch (Exception e) {
}
return null;
}
protected Template getTemplate(
String templateId, Map tokens, String languageId,
Document document, String script, String langType)
throws Exception {
TemplateResource templateResource = null;
if (langType.equals(TemplateConstants.LANG_TYPE_XSL)) {
XSLURIResolver xslURIResolver = new JournalXSLURIResolver(
tokens, languageId);
templateResource = new XSLTemplateResource(
templateId, script, xslURIResolver, document.asXML());
}
else {
templateResource = new StringTemplateResource(templateId, script);
}
TemplateResource errorTemplateResource = getErrorTemplateResource(
langType);
return TemplateManagerUtil.getTemplate(
langType, templateResource, errorTemplateResource, _restricted);
}
protected String getTemplateId(
String templateId, long companyId, long companyGroupId, long groupId) {
StringBundler sb = new StringBundler(5);
sb.append(companyId);
sb.append(StringPool.POUND);
if (companyGroupId > 0) {
sb.append(companyGroupId);
}
else {
sb.append(groupId);
}
sb.append(StringPool.POUND);
sb.append(templateId);
return sb.toString();
}
protected List getTemplateNodes(
ThemeDisplay themeDisplay, Element element, long ddmStructureId)
throws Exception {
DDMStructure ddmStructure = DDMStructureLocalServiceUtil.getStructure(
ddmStructureId);
DDMForm ddmForm = ddmStructure.getDDMForm();
Map ddmFormFieldsMap =
ddmForm.getDDMFormFieldsMap(true);
List templateNodes = new ArrayList<>();
Map prototypeTemplateNodes = new HashMap<>();
List dynamicElementElements = element.elements(
"dynamic-element");
for (Element dynamicElementElement : dynamicElementElements) {
Element dynamicContentElement = dynamicElementElement.element(
"dynamic-content");
String data = StringPool.BLANK;
if (dynamicContentElement != null) {
data = dynamicContentElement.getText();
}
String name = dynamicElementElement.attributeValue(
"name", StringPool.BLANK);
if (name.length() == 0) {
throw new TransformException(
"Element missing \"name\" attribute");
}
String type = dynamicElementElement.attributeValue(
"type", StringPool.BLANK);
Map attributes = new HashMap<>();
if (dynamicContentElement != null) {
for (Attribute attribute : dynamicContentElement.attributes()) {
attributes.put(attribute.getName(), attribute.getValue());
}
}
TemplateNode templateNode = new TemplateNode(
themeDisplay, name, StringUtil.stripCDATA(data), type,
attributes);
if (dynamicElementElement.element("dynamic-element") != null) {
templateNode.appendChildren(
getTemplateNodes(
themeDisplay, dynamicElementElement, ddmStructureId));
}
else if ((dynamicContentElement != null) &&
(dynamicContentElement.element("option") != null)) {
List optionElements = dynamicContentElement.elements(
"option");
for (Element optionElement : optionElements) {
templateNode.appendOption(
StringUtil.stripCDATA(optionElement.getText()));
}
}
DDMFormField ddmFormField = ddmFormFieldsMap.get(name);
if (ddmFormField != null) {
DDMFormFieldOptions ddmFormFieldOptions =
ddmFormField.getDDMFormFieldOptions();
Map options =
ddmFormFieldOptions.getOptions();
for (Entry entry : options.entrySet()) {
String optionValue = StringUtil.stripCDATA(entry.getKey());
LocalizedValue localizedLabel = entry.getValue();
String optionLabel = localizedLabel.getString(
themeDisplay.getLocale());
templateNode.appendOptionMap(optionValue, optionLabel);
}
}
TemplateNode prototypeTemplateNode = prototypeTemplateNodes.get(
name);
if (prototypeTemplateNode == null) {
prototypeTemplateNode = templateNode;
prototypeTemplateNodes.put(name, prototypeTemplateNode);
templateNodes.add(templateNode);
}
prototypeTemplateNode.appendSibling(templateNode);
}
return templateNodes;
}
protected String getTemplatesPath(
long companyId, long groupId, long classNameId) {
StringBundler sb = new StringBundler(7);
sb.append(TemplateConstants.TEMPLATE_SEPARATOR);
sb.append(StringPool.SLASH);
sb.append(companyId);
sb.append(StringPool.SLASH);
sb.append(groupId);
sb.append(StringPool.SLASH);
sb.append(classNameId);
return sb.toString();
}
protected Map insertRequestVariables(Element element) {
Map map = new HashMap<>();
if (element == null) {
return map;
}
for (Element childElement : element.elements()) {
String name = childElement.getName();
if (name.equals("attribute")) {
Element nameElement = childElement.element("name");
Element valueElement = childElement.element("value");
map.put(nameElement.getText(), valueElement.getText());
}
else if (name.equals("parameter")) {
Element nameElement = childElement.element("name");
List valueElements = childElement.elements("value");
if (valueElements.size() == 1) {
Element valueElement = valueElements.get(0);
map.put(nameElement.getText(), valueElement.getText());
}
else {
List values = new ArrayList<>();
for (Element valueElement : valueElements) {
values.add(valueElement.getText());
}
map.put(nameElement.getText(), values);
}
}
else {
List elements = childElement.elements();
if (!elements.isEmpty()) {
map.put(name, insertRequestVariables(childElement));
}
else {
map.put(name, childElement.getText());
}
}
}
return map;
}
protected void mergeTemplate(
Template template, UnsyncStringWriter unsyncStringWriter,
boolean propagateException)
throws Exception {
if (propagateException) {
template.doProcessTemplate(unsyncStringWriter);
}
else {
template.processTemplate(unsyncStringWriter);
}
}
private static final Log _log = LogFactoryUtil.getLog(
JournalTransformer.class);
private static final Log _logOutputAfterListener = LogFactoryUtil.getLog(
JournalTransformer.class.getName() + ".OutputAfterListener");
private static final Log _logOutputBeforeListener = LogFactoryUtil.getLog(
JournalTransformer.class.getName() + ".OutputBeforeListener");
private static final Log _logScriptAfterListener = LogFactoryUtil.getLog(
JournalTransformer.class.getName() + ".ScriptAfterListener");
private static final Log _logScriptBeforeListener = LogFactoryUtil.getLog(
JournalTransformer.class.getName() + ".ScriptBeforeListener");
private static final Log _logTokens = LogFactoryUtil.getLog(
JournalTransformer.class.getName() + ".Tokens");
private static final Log _logTransformBefore = LogFactoryUtil.getLog(
JournalTransformer.class.getName() + ".TransformBefore");
private static final Log _logTransfromAfter = LogFactoryUtil.getLog(
JournalTransformer.class.getName() + ".TransformAfter");
private static final Log _logXmlAfterListener = LogFactoryUtil.getLog(
JournalTransformer.class.getName() + ".XmlAfterListener");
private static final Log _logXmlBeforeListener = LogFactoryUtil.getLog(
JournalTransformer.class.getName() + ".XmlBeforeListener");
private final Map _errorTemplateIds = new HashMap<>();
private final boolean _restricted;
private final Set _transformerListeners =
new HashSet<>();
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy