// Path: gaulois-pipe/src/main/java/fr/efl/chaine/xslt/SaxonConfigurationFactory.java
// public abstract class SaxonConfigurationFactory {
//     
//     /**
//      * Returns the Configuration. Many calls to this method <strong>must</strong>
//      * return the same instance of <tt>Configuration</tt>.
//      * 
//      * @return The Configuration to use
//      */
//     public abstract Configuration getConfiguration();
//     
// }
// 
// Path: gaulois-pipe/src/main/java/top/marchand/xml/gaulois/resolve/GauloisSAXParserFactory.java
// public class GauloisSAXParserFactory extends SAXParserFactory {
//     private final SAXParserFactory innerFactory;
//     ThreadLocal<EntityResolver2> thEntityResolver;
//     
//     public GauloisSAXParserFactory() {
//         innerFactory = new SAXParserFactoryImpl() {
//             @Override
//             public SAXParser newSAXParser() throws ParserConfigurationException {
//                 return new GauloisSAXParser(super.newSAXParser());
//             }
//         };
//     }
// 
//     @Override
//     public SAXParser newSAXParser() throws ParserConfigurationException, SAXException {
//         return innerFactory.newSAXParser();
//     }
// 
//     @Override
//     public void setFeature(String name, boolean value) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException {
//         innerFactory.setFeature(name, value);
//     }
// 
//     @Override
//     public boolean getFeature(String name) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException {
//         return innerFactory.getFeature(name);
//     }
//     
//     class GauloisSAXParser extends SAXParser {
//         private ThreadLocal<EntityResolver2> thEntityResolver;
// 
//         private final SAXParser innerParser;
//         public GauloisSAXParser(SAXParser innerParser) {
//             super();
//             this.innerParser=innerParser;
//         }
// 
//         @Override
//         public Parser getParser() throws SAXException {
//             return innerParser.getParser();
//         }
// 
//         @Override
//         public XMLReader getXMLReader() throws SAXException {
//             XMLReader reader = innerParser.getXMLReader();
//             if(thEntityResolver!=null && thEntityResolver.get()!=null) {
//                 reader.setEntityResolver(thEntityResolver.get());
//             }
//             return reader;
//         }
// 
//         @Override
//         public boolean isNamespaceAware() {
//             return innerParser.isNamespaceAware();
//         }
// 
//         @Override
//         public boolean isValidating() {
//             return innerParser.isValidating();
//         }
// 
//         @Override
//         public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
//             innerParser.setProperty(name, value);
//         }
// 
//         @Override
//         public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
//             return innerParser.getProperty(name);
//         }
//     }
//     
// }


import fr.efl.chaine.xslt.SaxonConfigurationFactory;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import javax.xml.transform.stream.StreamSource;
import net.sf.saxon.Configuration;
import net.sf.saxon.lib.ExtensionFunctionDefinition;
import net.sf.saxon.s9api.DocumentBuilder;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.XPathCompiler;
import net.sf.saxon.s9api.XPathSelector;
import net.sf.saxon.s9api.XdmNode;
import net.sf.saxon.s9api.XdmSequenceIterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import top.marchand.xml.gaulois.resolve.GauloisSAXParserFactory;
/**
 * This Source Code Form is subject to the terms of 
 * the Mozilla Public License, v. 2.0. If a copy of 
 * the MPL was not distributed with this file, You 
 * can obtain one at https://mozilla.org/MPL/2.0/.
 */
package top.marchand.xml.gaulois.impl;


/**
 * A default SaxonConfigurationFactory that loads xpath extension functions into configuration.
 * 
 * You should provide a xml file with this structure :
 * 
 * <pre>
 * &lt;gaulois-service&gt;
 *    &lt;saxon&gt;
 *       &lt;extensions&gt;
 *          &lt;function&gt;fully.qualified.classname.that.extends.net.sf.saxon.lib.ExtensionFunctionDefinition&lt;/functiongt;
 *          &lt;functiongt;another.fully.qualified.classname&gt;
 *       &lt;/extensions&gt;
 *    &lt;/saxon&gt;
 * &lt;/gaulois-service&gt;
 * </pre>
 * @author cmarchand
 */
public class DefaultSaxonConfigurationFactory extends SaxonConfigurationFactory {
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultSaxonConfigurationFactory.class);
    protected Configuration configuration;
    
    public DefaultSaxonConfigurationFactory() {
        super();
        __initConfiguration();
    }
    
    /**
     * To be overriden, if required
     */
    protected void createConfigurationObject() {
        configuration = Configuration.newConfiguration();
    }

    @Override
    public Configuration getConfiguration() {
        return configuration;
    }
    
    private void __initConfiguration() {
        // default construct
        createConfigurationObject();
        LOGGER.debug("configuration is a "+configuration.getClass().getName());
        // issue 39
// Path: gaulois-pipe/src/main/java/fr/efl/chaine/xslt/SaxonConfigurationFactory.java
// public abstract class SaxonConfigurationFactory {
//     
//     /**
//      * Returns the Configuration. Many calls to this method <strong>must</strong>
//      * return the same instance of <tt>Configuration</tt>.
//      * 
//      * @return The Configuration to use
//      */
//     public abstract Configuration getConfiguration();
//     
// }
// 
// Path: gaulois-pipe/src/main/java/top/marchand/xml/gaulois/resolve/GauloisSAXParserFactory.java
// public class GauloisSAXParserFactory extends SAXParserFactory {
//     private final SAXParserFactory innerFactory;
//     ThreadLocal<EntityResolver2> thEntityResolver;
//     
//     public GauloisSAXParserFactory() {
//         innerFactory = new SAXParserFactoryImpl() {
//             @Override
//             public SAXParser newSAXParser() throws ParserConfigurationException {
//                 return new GauloisSAXParser(super.newSAXParser());
//             }
//         };
//     }
// 
//     @Override
//     public SAXParser newSAXParser() throws ParserConfigurationException, SAXException {
//         return innerFactory.newSAXParser();
//     }
// 
//     @Override
//     public void setFeature(String name, boolean value) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException {
//         innerFactory.setFeature(name, value);
//     }
// 
//     @Override
//     public boolean getFeature(String name) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException {
//         return innerFactory.getFeature(name);
//     }
//     
//     class GauloisSAXParser extends SAXParser {
//         private ThreadLocal<EntityResolver2> thEntityResolver;
// 
//         private final SAXParser innerParser;
//         public GauloisSAXParser(SAXParser innerParser) {
//             super();
//             this.innerParser=innerParser;
//         }
// 
//         @Override
//         public Parser getParser() throws SAXException {
//             return innerParser.getParser();
//         }
// 
//         @Override
//         public XMLReader getXMLReader() throws SAXException {
//             XMLReader reader = innerParser.getXMLReader();
//             if(thEntityResolver!=null && thEntityResolver.get()!=null) {
//                 reader.setEntityResolver(thEntityResolver.get());
//             }
//             return reader;
//         }
// 
//         @Override
//         public boolean isNamespaceAware() {
//             return innerParser.isNamespaceAware();
//         }
// 
//         @Override
//         public boolean isValidating() {
//             return innerParser.isValidating();
//         }
// 
//         @Override
//         public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
//             innerParser.setProperty(name, value);
//         }
// 
//         @Override
//         public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
//             return innerParser.getProperty(name);
//         }
//     }
//     
// }


// Path: gaulois-pipe/src/main/java/top/marchand/xml/gaulois/impl/DefaultSaxonConfigurationFactory.java
import fr.efl.chaine.xslt.SaxonConfigurationFactory;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import javax.xml.transform.stream.StreamSource;
import net.sf.saxon.Configuration;
import net.sf.saxon.lib.ExtensionFunctionDefinition;
import net.sf.saxon.s9api.DocumentBuilder;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.XPathCompiler;
import net.sf.saxon.s9api.XPathSelector;
import net.sf.saxon.s9api.XdmNode;
import net.sf.saxon.s9api.XdmSequenceIterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import top.marchand.xml.gaulois.resolve.GauloisSAXParserFactory;

/**
 * This Source Code Form is subject to the terms of 
 * the Mozilla Public License, v. 2.0. If a copy of 
 * the MPL was not distributed with this file, You 
 * can obtain one at https://mozilla.org/MPL/2.0/.
 */
package top.marchand.xml.gaulois.impl;


/**
 * A default SaxonConfigurationFactory that loads xpath extension functions into configuration.
 * 
 * You should provide a xml file with this structure :
 * 
 * <pre>
 * &lt;gaulois-service&gt;
 *    &lt;saxon&gt;
 *       &lt;extensions&gt;
 *          &lt;function&gt;fully.qualified.classname.that.extends.net.sf.saxon.lib.ExtensionFunctionDefinition&lt;/functiongt;
 *          &lt;functiongt;another.fully.qualified.classname&gt;
 *       &lt;/extensions&gt;
 *    &lt;/saxon&gt;
 * &lt;/gaulois-service&gt;
 * </pre>
 * @author cmarchand
 */
public class DefaultSaxonConfigurationFactory extends SaxonConfigurationFactory {
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultSaxonConfigurationFactory.class);
    protected Configuration configuration;
    
    public DefaultSaxonConfigurationFactory() {
        super();
        __initConfiguration();
    }
    
    /**
     * To be overriden, if required
     */
    protected void createConfigurationObject() {
        configuration = Configuration.newConfiguration();
    }

    @Override
    public Configuration getConfiguration() {
        return configuration;
    }
    
    private void __initConfiguration() {
        // default construct
        createConfigurationObject();
        LOGGER.debug("configuration is a "+configuration.getClass().getName());
        // issue 39
        configuration.setSourceParserClass(GauloisSAXParserFactory.class.getName());