001    /**
002     * Copyright (c) 2000-present 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.templateparser;
016    
017    import com.liferay.portal.kernel.configuration.Filter;
018    import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.mobile.device.Device;
022    import com.liferay.portal.kernel.mobile.device.UnknownDevice;
023    import com.liferay.portal.kernel.portlet.PortletRequestModel;
024    import com.liferay.portal.kernel.template.StringTemplateResource;
025    import com.liferay.portal.kernel.template.Template;
026    import com.liferay.portal.kernel.template.TemplateConstants;
027    import com.liferay.portal.kernel.template.TemplateManagerUtil;
028    import com.liferay.portal.kernel.template.TemplateResource;
029    import com.liferay.portal.kernel.template.URLTemplateResource;
030    import com.liferay.portal.kernel.templateparser.TemplateNode;
031    import com.liferay.portal.kernel.templateparser.TransformException;
032    import com.liferay.portal.kernel.templateparser.TransformerListener;
033    import com.liferay.portal.kernel.util.Constants;
034    import com.liferay.portal.kernel.util.GetterUtil;
035    import com.liferay.portal.kernel.util.InstanceFactory;
036    import com.liferay.portal.kernel.util.LocaleUtil;
037    import com.liferay.portal.kernel.util.LocalizationUtil;
038    import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
039    import com.liferay.portal.kernel.util.PropertiesUtil;
040    import com.liferay.portal.kernel.util.SetUtil;
041    import com.liferay.portal.kernel.util.StringBundler;
042    import com.liferay.portal.kernel.util.StringPool;
043    import com.liferay.portal.kernel.util.StringUtil;
044    import com.liferay.portal.kernel.util.Validator;
045    import com.liferay.portal.kernel.xml.Attribute;
046    import com.liferay.portal.kernel.xml.Document;
047    import com.liferay.portal.kernel.xml.DocumentException;
048    import com.liferay.portal.kernel.xml.Element;
049    import com.liferay.portal.kernel.xml.SAXReaderUtil;
050    import com.liferay.portal.model.Company;
051    import com.liferay.portal.security.permission.PermissionThreadLocal;
052    import com.liferay.portal.service.CompanyLocalServiceUtil;
053    import com.liferay.portal.theme.ThemeDisplay;
054    import com.liferay.portal.util.PropsUtil;
055    import com.liferay.portal.xsl.XSLTemplateResource;
056    import com.liferay.portal.xsl.XSLURIResolver;
057    import com.liferay.portlet.journal.util.JournalXSLURIResolver;
058    import com.liferay.portlet.portletdisplaytemplate.util.PortletDisplayTemplateConstants;
059    import com.liferay.taglib.util.VelocityTaglib;
060    
061    import java.io.IOException;
062    
063    import java.net.URL;
064    
065    import java.util.ArrayList;
066    import java.util.HashMap;
067    import java.util.HashSet;
068    import java.util.List;
069    import java.util.Locale;
070    import java.util.Map;
071    import java.util.Set;
072    
073    /**
074     * @author Brian Wing Shun Chan
075     * @author Raymond Aug??
076     * @author Wesley Gong
077     * @author Angelo Jefferson
078     * @author Hugo Huijser
079     * @author Marcellus Tavares
080     * @author Juan Fern??ndez
081     */
082    public class Transformer {
083    
084            public Transformer(String errorTemplatePropertyKey, boolean restricted) {
085                    Set<String> langTypes = TemplateManagerUtil.getSupportedLanguageTypes(
086                            errorTemplatePropertyKey);
087    
088                    for (String langType : langTypes) {
089                            String errorTemplateId = PropsUtil.get(
090                                    errorTemplatePropertyKey, new Filter(langType));
091    
092                            if (Validator.isNotNull(errorTemplateId)) {
093                                    _errorTemplateIds.put(langType, errorTemplateId);
094                            }
095                    }
096    
097                    _restricted = restricted;
098            }
099    
100            public Transformer(
101                    String transformerListenerPropertyKey, String errorTemplatePropertyKey,
102                    boolean restricted) {
103    
104                    this(errorTemplatePropertyKey, restricted);
105    
106                    ClassLoader classLoader = PortalClassLoaderUtil.getClassLoader();
107    
108                    Set<String> transformerListenerClassNames = SetUtil.fromArray(
109                            PropsUtil.getArray(transformerListenerPropertyKey));
110    
111                    for (String transformerListenerClassName :
112                                    transformerListenerClassNames) {
113    
114                            try {
115                                    if (_log.isDebugEnabled()) {
116                                            _log.debug(
117                                                    "Instantiating transformer listener " +
118                                                            transformerListenerClassName);
119                                    }
120    
121                                    TransformerListener transformerListener =
122                                            (TransformerListener)InstanceFactory.newInstance(
123                                                    classLoader, transformerListenerClassName);
124    
125                                    _transformerListeners.add(transformerListener);
126                            }
127                            catch (Exception e) {
128                                    _log.error(e, e);
129                            }
130                    }
131            }
132    
133            public String doTransform(
134                            ThemeDisplay themeDisplay, Map<String, String> tokens,
135                            String viewMode, String languageId, Document document,
136                            PortletRequestModel portletRequestModel, String script,
137                            String langType)
138                    throws Exception {
139    
140                    return transform(
141                            themeDisplay, tokens, viewMode, languageId, document,
142                            portletRequestModel, script, langType, true);
143            }
144    
145            public String transform(
146                            ThemeDisplay themeDisplay, Map<String, Object> contextObjects,
147                            String script, String langType)
148                    throws Exception {
149    
150                    if (Validator.isNull(langType)) {
151                            return null;
152                    }
153    
154                    long companyId = 0;
155                    long companyGroupId = 0;
156                    long scopeGroupId = 0;
157                    long siteGroupId = 0;
158    
159                    if (themeDisplay != null) {
160                            companyId = themeDisplay.getCompanyId();
161                            companyGroupId = themeDisplay.getCompanyGroupId();
162                            scopeGroupId = themeDisplay.getScopeGroupId();
163                            siteGroupId = themeDisplay.getSiteGroupId();
164                    }
165    
166                    String templateId = String.valueOf(contextObjects.get("template_id"));
167    
168                    templateId = getTemplateId(
169                            templateId, companyId, companyGroupId, scopeGroupId);
170    
171                    Template template = getTemplate(templateId, script, langType);
172    
173                    UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();
174    
175                    try {
176                            prepareTemplate(themeDisplay, template);
177    
178                            if (contextObjects != null) {
179                                    for (String key : contextObjects.keySet()) {
180                                            template.put(key, contextObjects.get(key));
181                                    }
182                            }
183    
184                            template.put("company", getCompany(themeDisplay, companyId));
185                            template.put("companyId", companyId);
186                            template.put("device", getDevice(themeDisplay));
187    
188                            String templatesPath = getTemplatesPath(companyId, scopeGroupId);
189    
190                            template.put(
191                                    "permissionChecker",
192                                    PermissionThreadLocal.getPermissionChecker());
193                            template.put(
194                                    "randomNamespace",
195                                    StringUtil.randomId() + StringPool.UNDERLINE);
196                            template.put("scopeGroupId", scopeGroupId);
197                            template.put("siteGroupId", siteGroupId);
198                            template.put("templatesPath", templatesPath);
199    
200                            // Deprecated variables
201    
202                            template.put("groupId", scopeGroupId);
203                            template.put("journalTemplatesPath", templatesPath);
204    
205                            mergeTemplate(template, unsyncStringWriter, false);
206                    }
207                    catch (Exception e) {
208                            throw new TransformException("Unhandled exception", e);
209                    }
210    
211                    return unsyncStringWriter.toString();
212            }
213    
214            public String transform(
215                            ThemeDisplay themeDisplay, Map<String, String> tokens,
216                            String viewMode, String languageId, Document document,
217                            PortletRequestModel portletRequestModel, String script,
218                            String langType)
219                    throws Exception {
220    
221                    return transform(
222                            themeDisplay, tokens, viewMode, languageId, document,
223                            portletRequestModel, script, langType, false);
224            }
225    
226            protected Company getCompany(ThemeDisplay themeDisplay, long companyId)
227                    throws Exception {
228    
229                    if (themeDisplay != null) {
230                            return themeDisplay.getCompany();
231                    }
232    
233                    return CompanyLocalServiceUtil.getCompany(companyId);
234            }
235    
236            protected Device getDevice(ThemeDisplay themeDisplay) {
237                    if (themeDisplay != null) {
238                            return themeDisplay.getDevice();
239                    }
240    
241                    return UnknownDevice.getInstance();
242            }
243    
244            protected TemplateResource getErrorTemplateResource(String langType) {
245                    try {
246                            Class<?> clazz = getClass();
247    
248                            ClassLoader classLoader = clazz.getClassLoader();
249    
250                            String errorTemplateId = _errorTemplateIds.get(langType);
251    
252                            URL url = classLoader.getResource(errorTemplateId);
253    
254                            return new URLTemplateResource(errorTemplateId, url);
255                    }
256                    catch (Exception e) {
257                    }
258    
259                    return null;
260            }
261    
262            protected Template getTemplate(
263                            String templateId, Map<String, String> tokens, String languageId,
264                            Document document, String script, String langType)
265                    throws Exception {
266    
267                    TemplateResource templateResource = null;
268    
269                    if (langType.equals(TemplateConstants.LANG_TYPE_XSL)) {
270                            XSLURIResolver xslURIResolver = new JournalXSLURIResolver(
271                                    tokens, languageId);
272    
273                            templateResource = new XSLTemplateResource(
274                                    templateId, script, xslURIResolver, document.asXML());
275                    }
276                    else {
277                            templateResource = new StringTemplateResource(templateId, script);
278                    }
279    
280                    TemplateResource errorTemplateResource = getErrorTemplateResource(
281                            langType);
282    
283                    return TemplateManagerUtil.getTemplate(
284                            langType, templateResource, errorTemplateResource, _restricted);
285            }
286    
287            protected Template getTemplate(
288                            String templateId, String script, String langType)
289                    throws Exception {
290    
291                    TemplateResource templateResource = new StringTemplateResource(
292                            templateId, script);
293    
294                    TemplateResource errorTemplateResource = getErrorTemplateResource(
295                            langType);
296    
297                    return TemplateManagerUtil.getTemplate(
298                            langType, templateResource, errorTemplateResource, _restricted);
299            }
300    
301            protected String getTemplateId(
302                    String templateId, long companyId, long companyGroupId, long groupId) {
303    
304                    StringBundler sb = new StringBundler(5);
305    
306                    sb.append(companyId);
307                    sb.append(StringPool.POUND);
308    
309                    if (companyGroupId > 0) {
310                            sb.append(companyGroupId);
311                    }
312                    else {
313                            sb.append(groupId);
314                    }
315    
316                    sb.append(StringPool.POUND);
317                    sb.append(templateId);
318    
319                    return sb.toString();
320            }
321    
322            protected List<TemplateNode> getTemplateNodes(
323                            ThemeDisplay themeDisplay, Element element)
324                    throws Exception {
325    
326                    List<TemplateNode> templateNodes = new ArrayList<TemplateNode>();
327    
328                    Map<String, TemplateNode> prototypeTemplateNodes =
329                            new HashMap<String, TemplateNode>();
330    
331                    List<Element> dynamicElementElements = element.elements(
332                            "dynamic-element");
333    
334                    for (Element dynamicElementElement : dynamicElementElements) {
335                            Element dynamicContentElement = dynamicElementElement.element(
336                                    "dynamic-content");
337    
338                            String data = StringPool.BLANK;
339    
340                            if (dynamicContentElement != null) {
341                                    data = dynamicContentElement.getText();
342                            }
343    
344                            String name = dynamicElementElement.attributeValue(
345                                    "name", StringPool.BLANK);
346    
347                            if (name.length() == 0) {
348                                    throw new TransformException(
349                                            "Element missing \"name\" attribute");
350                            }
351    
352                            String type = dynamicElementElement.attributeValue(
353                                    "type", StringPool.BLANK);
354    
355                            Map<String, String> attributes = new HashMap<String, String>();
356    
357                            if (dynamicContentElement != null) {
358                                    for (Attribute attribute : dynamicContentElement.attributes()) {
359                                            attributes.put(attribute.getName(), attribute.getValue());
360                                    }
361                            }
362    
363                            TemplateNode templateNode = new TemplateNode(
364                                    themeDisplay, name, StringUtil.stripCDATA(data), type,
365                                    attributes);
366    
367                            if (dynamicElementElement.element("dynamic-element") != null) {
368                                    templateNode.appendChildren(
369                                            getTemplateNodes(themeDisplay, dynamicElementElement));
370                            }
371                            else if ((dynamicContentElement != null) &&
372                                             (dynamicContentElement.element("option") != null)) {
373    
374                                    List<Element> optionElements = dynamicContentElement.elements(
375                                            "option");
376    
377                                    for (Element optionElement : optionElements) {
378                                            templateNode.appendOption(
379                                                    StringUtil.stripCDATA(optionElement.getText()));
380                                    }
381                            }
382    
383                            TemplateNode prototypeTemplateNode = prototypeTemplateNodes.get(
384                                    name);
385    
386                            if (prototypeTemplateNode == null) {
387                                    prototypeTemplateNode = templateNode;
388    
389                                    prototypeTemplateNodes.put(name, prototypeTemplateNode);
390    
391                                    templateNodes.add(templateNode);
392                            }
393    
394                            prototypeTemplateNode.appendSibling(templateNode);
395                    }
396    
397                    return templateNodes;
398            }
399    
400            protected String getTemplatesPath(long companyId, long groupId) {
401                    StringBundler sb = new StringBundler(5);
402    
403                    sb.append(TemplateConstants.TEMPLATE_SEPARATOR);
404                    sb.append(StringPool.SLASH);
405                    sb.append(companyId);
406                    sb.append(StringPool.SLASH);
407                    sb.append(groupId);
408    
409                    return sb.toString();
410            }
411    
412            protected Map<String, Object> insertRequestVariables(Element element) {
413                    Map<String, Object> map = new HashMap<String, Object>();
414    
415                    if (element == null) {
416                            return map;
417                    }
418    
419                    for (Element childElement : element.elements()) {
420                            String name = childElement.getName();
421    
422                            if (name.equals("attribute")) {
423                                    Element nameElement = childElement.element("name");
424                                    Element valueElement = childElement.element("value");
425    
426                                    map.put(nameElement.getText(), valueElement.getText());
427                            }
428                            else if (name.equals("parameter")) {
429                                    Element nameElement = childElement.element("name");
430    
431                                    List<Element> valueElements = childElement.elements("value");
432    
433                                    if (valueElements.size() == 1) {
434                                            Element valueElement = valueElements.get(0);
435    
436                                            map.put(nameElement.getText(), valueElement.getText());
437                                    }
438                                    else {
439                                            List<String> values = new ArrayList<String>();
440    
441                                            for (Element valueElement : valueElements) {
442                                                    values.add(valueElement.getText());
443                                            }
444    
445                                            map.put(nameElement.getText(), values);
446                                    }
447                            }
448                            else {
449                                    List<Element> elements = childElement.elements();
450    
451                                    if (!elements.isEmpty()) {
452                                            map.put(name, insertRequestVariables(childElement));
453                                    }
454                                    else {
455                                            map.put(name, childElement.getText());
456                                    }
457                            }
458                    }
459    
460                    return map;
461            }
462    
463            protected void mergeTemplate(
464                            Template template, UnsyncStringWriter unsyncStringWriter,
465                            boolean propagateException)
466                    throws Exception {
467    
468                    VelocityTaglib velocityTaglib = (VelocityTaglib)template.get(
469                            PortletDisplayTemplateConstants.TAGLIB_LIFERAY);
470    
471                    if (velocityTaglib != null) {
472                            velocityTaglib.setTemplate(template);
473                    }
474    
475                    if (propagateException) {
476                            template.doProcessTemplate(unsyncStringWriter);
477                    }
478                    else {
479                            template.processTemplate(unsyncStringWriter);
480                    }
481            }
482    
483            protected void prepareTemplate(ThemeDisplay themeDisplay, Template template)
484                    throws Exception {
485    
486                    if (themeDisplay == null) {
487                            return;
488                    }
489    
490                    template.prepare(themeDisplay.getRequest());
491            }
492    
493            protected String transform(
494                            ThemeDisplay themeDisplay, Map<String, String> tokens,
495                            String viewMode, String languageId, Document document,
496                            PortletRequestModel portletRequestModel, String script,
497                            String langType, boolean propagateException)
498                    throws Exception {
499    
500                    // Setup listeners
501    
502                    if (_log.isDebugEnabled()) {
503                            _log.debug("Language " + languageId);
504                    }
505    
506                    if (Validator.isNull(viewMode)) {
507                            viewMode = Constants.VIEW;
508                    }
509    
510                    if (_logTokens.isDebugEnabled()) {
511                            String tokensString = PropertiesUtil.list(tokens);
512    
513                            _logTokens.debug(tokensString);
514                    }
515    
516                    if (_logTransformBefore.isDebugEnabled()) {
517                            _logTransformBefore.debug(document);
518                    }
519    
520                    for (TransformerListener transformerListener : _transformerListeners) {
521    
522                            // Modify XML
523    
524                            if (_logXmlBeforeListener.isDebugEnabled()) {
525                                    _logXmlBeforeListener.debug(document);
526                            }
527    
528                            if (transformerListener != null) {
529                                    document = transformerListener.onXml(
530                                            document, languageId, tokens);
531    
532                                    if (_logXmlAfterListener.isDebugEnabled()) {
533                                            _logXmlAfterListener.debug(document);
534                                    }
535                            }
536    
537                            // Modify script
538    
539                            if (_logScriptBeforeListener.isDebugEnabled()) {
540                                    _logScriptBeforeListener.debug(script);
541                            }
542    
543                            if (transformerListener != null) {
544                                    script = transformerListener.onScript(
545                                            script, document, languageId, tokens);
546    
547                                    if (_logScriptAfterListener.isDebugEnabled()) {
548                                            _logScriptAfterListener.debug(script);
549                                    }
550                            }
551                    }
552    
553                    // Transform
554    
555                    String output = null;
556    
557                    if (Validator.isNull(langType)) {
558                            output = LocalizationUtil.getLocalization(
559                                    document.asXML(), languageId);
560                    }
561                    else {
562                            long companyId = 0;
563                            long companyGroupId = 0;
564                            long articleGroupId = 0;
565    
566                            if (tokens != null) {
567                                    companyId = GetterUtil.getLong(tokens.get("company_id"));
568                                    companyGroupId = GetterUtil.getLong(
569                                            tokens.get("company_group_id"));
570                                    articleGroupId = GetterUtil.getLong(
571                                            tokens.get("article_group_id"));
572                            }
573    
574                            long scopeGroupId = 0;
575                            long siteGroupId = 0;
576    
577                            if (themeDisplay != null) {
578                                    companyId = themeDisplay.getCompanyId();
579                                    companyGroupId = themeDisplay.getCompanyGroupId();
580                                    scopeGroupId = themeDisplay.getScopeGroupId();
581                                    siteGroupId = themeDisplay.getSiteGroupId();
582                            }
583    
584                            String templateId = tokens.get("template_id");
585    
586                            templateId = getTemplateId(
587                                    templateId, companyId, companyGroupId, articleGroupId);
588    
589                            Template template = getTemplate(
590                                    templateId, tokens, languageId, document, script, langType);
591    
592                            UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();
593    
594                            try {
595                                    if (document != null) {
596                                            Element rootElement = document.getRootElement();
597    
598                                            List<TemplateNode> templateNodes = getTemplateNodes(
599                                                    themeDisplay, rootElement);
600    
601                                            if (templateNodes != null) {
602                                                    for (TemplateNode templateNode : templateNodes) {
603                                                            template.put(templateNode.getName(), templateNode);
604                                                    }
605                                            }
606    
607                                            if (portletRequestModel != null) {
608                                                    template.put("request", portletRequestModel.toMap());
609    
610                                                    if (langType.equals(TemplateConstants.LANG_TYPE_XSL)) {
611                                                            Document requestDocument = SAXReaderUtil.read(
612                                                                    portletRequestModel.toXML());
613    
614                                                            Element requestElement =
615                                                                    requestDocument.getRootElement();
616    
617                                                            template.put("xmlRequest", requestElement.asXML());
618                                                    }
619                                            }
620                                            else {
621                                                    Element requestElement = rootElement.element("request");
622    
623                                                    template.put(
624                                                            "request", insertRequestVariables(requestElement));
625    
626                                                    if (langType.equals(TemplateConstants.LANG_TYPE_XSL)) {
627                                                            template.put("xmlRequest", requestElement.asXML());
628                                                    }
629                                            }
630                                    }
631    
632                                    template.put("articleGroupId", articleGroupId);
633                                    template.put("company", getCompany(themeDisplay, companyId));
634                                    template.put("companyId", companyId);
635                                    template.put("device", getDevice(themeDisplay));
636    
637                                    String templatesPath = getTemplatesPath(
638                                            companyId, articleGroupId);
639    
640                                    Locale locale = LocaleUtil.fromLanguageId(languageId);
641    
642                                    template.put("locale", locale);
643    
644                                    template.put(
645                                            "permissionChecker",
646                                            PermissionThreadLocal.getPermissionChecker());
647                                    template.put(
648                                            "randomNamespace",
649                                            StringUtil.randomId() + StringPool.UNDERLINE);
650                                    template.put("scopeGroupId", scopeGroupId);
651                                    template.put("siteGroupId", siteGroupId);
652                                    template.put("templatesPath", templatesPath);
653                                    template.put("viewMode", viewMode);
654    
655                                    // Deprecated variables
656    
657                                    template.put("groupId", articleGroupId);
658                                    template.put("journalTemplatesPath", templatesPath);
659    
660                                    mergeTemplate(template, unsyncStringWriter, propagateException);
661                            }
662                            catch (Exception e) {
663                                    if (e instanceof DocumentException) {
664                                            throw new TransformException(
665                                                    "Unable to read XML document", e);
666                                    }
667                                    else if (e instanceof IOException) {
668                                            throw new TransformException("Error reading template", e);
669                                    }
670                                    else if (e instanceof TransformException) {
671                                            throw (TransformException)e;
672                                    }
673                                    else {
674                                            throw new TransformException("Unhandled exception", e);
675                                    }
676                            }
677    
678                            output = unsyncStringWriter.toString();
679                    }
680    
681                    // Postprocess output
682    
683                    for (TransformerListener transformerListener : _transformerListeners) {
684    
685                            // Modify output
686    
687                            if (_logOutputBeforeListener.isDebugEnabled()) {
688                                    _logOutputBeforeListener.debug(output);
689                            }
690    
691                            output = transformerListener.onOutput(output, languageId, tokens);
692    
693                            if (_logOutputAfterListener.isDebugEnabled()) {
694                                    _logOutputAfterListener.debug(output);
695                            }
696                    }
697    
698                    if (_logTransfromAfter.isDebugEnabled()) {
699                            _logTransfromAfter.debug(output);
700                    }
701    
702                    return output;
703            }
704    
705            private static final Log _log = LogFactoryUtil.getLog(Transformer.class);
706    
707            private static final Log _logOutputAfterListener = LogFactoryUtil.getLog(
708                    Transformer.class.getName() + ".OutputAfterListener");
709            private static final Log _logOutputBeforeListener = LogFactoryUtil.getLog(
710                    Transformer.class.getName() + ".OutputBeforeListener");
711            private static final Log _logScriptAfterListener = LogFactoryUtil.getLog(
712                    Transformer.class.getName() + ".ScriptAfterListener");
713            private static final Log _logScriptBeforeListener = LogFactoryUtil.getLog(
714                    Transformer.class.getName() + ".ScriptBeforeListener");
715            private static final Log _logTokens = LogFactoryUtil.getLog(
716                    Transformer.class.getName() + ".Tokens");
717            private static final Log _logTransformBefore = LogFactoryUtil.getLog(
718                    Transformer.class.getName() + ".TransformBefore");
719            private static final Log _logTransfromAfter = LogFactoryUtil.getLog(
720                    Transformer.class.getName() + ".TransformAfter");
721            private static final Log _logXmlAfterListener = LogFactoryUtil.getLog(
722                    Transformer.class.getName() + ".XmlAfterListener");
723            private static final Log _logXmlBeforeListener = LogFactoryUtil.getLog(
724                    Transformer.class.getName() + ".XmlBeforeListener");
725    
726            private final Map<String, String> _errorTemplateIds =
727                    new HashMap<String, String>();
728            private final boolean _restricted;
729            private final Set<TransformerListener> _transformerListeners =
730                    new HashSet<TransformerListener>();
731    
732    }