001/*
002 * jPOS Project [http://jpos.org]
003 * Copyright (C) 2000-2023 jPOS Software SRL
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018
019package org.jpos.iso.filter;
020
021import org.jpos.core.Configurable;
022import org.jpos.core.Configuration;
023import org.jpos.core.ConfigurationException;
024import org.jpos.iso.ISOChannel;
025import org.jpos.iso.ISOException;
026import org.jpos.iso.ISOFilter;
027import org.jpos.iso.ISOMsg;
028import org.jpos.iso.packager.XMLPackager;
029import org.jpos.util.LogEvent;
030
031import javax.xml.transform.Transformer;
032import javax.xml.transform.TransformerConfigurationException;
033import javax.xml.transform.TransformerFactory;
034import javax.xml.transform.stream.StreamResult;
035import javax.xml.transform.stream.StreamSource;
036import java.io.ByteArrayInputStream;
037import java.io.ByteArrayOutputStream;
038
039/**
040 * Implements ISOFilter by means of XSL-Transformations
041 * @author <a href="mailto:[email protected]">Alejandro P. Revilla</a>
042 * @version $Revision$ $Date$
043 */
044public class XSLTFilter implements ISOFilter, Configurable {
045    boolean reread;
046    String xsltfile;
047    TransformerFactory tfactory;
048    Transformer transformer;
049    XMLPackager packager;
050
051    /**
052     * Default noargs constructor
053     * @throws ISOException
054     */
055    public XSLTFilter () throws ISOException {
056        super();
057        packager    = new XMLPackager();
058        tfactory    = TransformerFactory.newInstance();
059        transformer = null;
060        reread      = true;
061    }
062
063    /**
064     * @param xsltfile XSL Transformation file
065     * @param reread true if you want XSLT file re-read from disk
066     * @throws ISOException
067     */
068    public XSLTFilter (String xsltfile, boolean reread) 
069        throws ISOException
070    {
071        this();
072        try {
073            this.xsltfile    = xsltfile;
074            this.reread      = reread;
075            this.transformer = 
076                tfactory.newTransformer(new StreamSource(xsltfile));
077        } catch (TransformerConfigurationException e) {
078            throw new ISOException (e);
079        }
080
081    }
082
083   /**
084    * configure filter.
085    *
086    * <ul>
087    *  <li>xsltfile - source XSL-T file
088    *  <li>reread   - something != "no" will re-read source file
089    * </ul>
090    *
091    * @param cfg new ConfigurationFile
092    */
093    public void setConfiguration (Configuration cfg) 
094        throws ConfigurationException
095    {
096        try {
097            transformer = tfactory.newTransformer(
098                new StreamSource(cfg.get("xsltfile"))
099            );
100            String s = cfg.get ("reread");
101            reread   = s == null || s.equals ("no");
102        } catch (Exception e) {
103            throw new ConfigurationException (e);
104        }
105    }
106
107    /**
108     * @param channel current ISOChannel instance
109     * @param m ISOMsg to filter
110     * @param evt LogEvent
111     * @return an ISOMsg (possibly parameter m)
112     * @throws VetoException
113     */
114    public ISOMsg filter (ISOChannel channel, ISOMsg m, LogEvent evt) 
115        throws VetoException
116    {
117        try {
118            m.setPackager (packager);
119            ByteArrayOutputStream os = new ByteArrayOutputStream();
120
121            if (reread || transformer == null)
122                transformer = tfactory.newTransformer(
123                    new StreamSource(xsltfile)
124                );
125            transformer.transform (
126                new StreamSource(new ByteArrayInputStream (m.pack())),
127                new StreamResult(os)
128            );
129            m.unpack (os.toByteArray());
130        } catch (Exception e) {
131            throw new VetoException(e);
132        }
133        return m;
134    }
135}