<commit_before>/**
 *  Copyright 2013 <NAME> <<EMAIL>>
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package org.graphity.client.provider;

import com.hp.hpl.jena.rdf.model.Property;
import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.spi.inject.Injectable;
import com.sun.jersey.spi.inject.PerRequestTypeInjectableProvider;
import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import javax.servlet.ServletConfig;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamSource;
import org.graphity.client.vocabulary.GC;
import org.graphity.core.exception.ConfigurationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * JAX-RS provider for XSLT builder.
 * Needs to be registered in the application.
 * 
 * @author <NAME> <<EMAIL>>
 * @see org.graphity.client.util.XSLTBuilder
 */
@Provider
public class TemplatesProvider extends PerRequestTypeInjectableProvider<Context, Templates> implements ContextResolver<Templates>
{

    private static final Logger log = LoggerFactory.getLogger(TemplatesProvider.class);

    private final ServletConfig servletConfig;
    private Templates templates;
    private final boolean cacheStylesheet;

    /**
     * 
     * @param servletConfig
     */
    public TemplatesProvider(@Context ServletConfig servletConfig)
    {
	super(Templates.class);
        this.servletConfig = servletConfig;
        
        if (servletConfig.getInitParameter(GC.cacheStylesheet.getURI()) != null)
            cacheStylesheet = Boolean.parseBoolean(servletConfig.getInitParameter(GC.cacheStylesheet.getURI()).toString());
        else cacheStylesheet = false;
    }

    public ServletConfig getServletConfig()
    {
        return servletConfig;
    }
    
    public boolean cacheStylesheet()
    {
        return cacheStylesheet;
    }

    @Override
    public Injectable<Templates> getInjectable(ComponentContext cc, Context a)
    {
	return new Injectable<Templates>()
	{
	    @Override
	    public Templates getValue()
	    {
                return getTemplates();
	    }
	};
    }

    @Override
    public Templates getContext(Class<?> type)
    {
        return getTemplates();
    }

    /**
     * Returns configured XSLT stylesheet resource.
     * Uses <code>gc:stylesheet</code> context parameter value from web.xml as stylesheet location.
     * 
     * @param property
     * @return stylesheet URI
     * @throws URISyntaxException 
     */
    public URI getStylesheetURI(Property property) throws URISyntaxException
    {
        Object stylesheetURI = getServletConfig().getInitParameter(property.getURI());
        if (stylesheetURI != null) return new URI(stylesheetURI.toString());
        
        return null;
    }
    
    public URI getStylesheetURI() throws URISyntaxException
    {
        URI stylesheetURI = getStylesheetURI(GC.stylesheet);
        
        if (stylesheetURI == null)
        {
            if (log.isErrorEnabled()) log.error("XSLT stylesheet (gc:stylesheet) not configured");
            throw new ConfigurationException("XSLT stylesheet (gc:stylesheet) not configured");
        }
        
        return stylesheetURI;
    }
    
    /**
     * Constructs XSLT builder from configuration.
     * 
     * @return XSLT builder object
     */
    public Templates getTemplates()
    {
        try
        {
            if (cacheStylesheet())
            {
                if (templates == null) templates = getTemplates(getStylesheetURI());

                return templates;
            }
            else
                return getTemplates(getStylesheetURI());
        }
        /*
        catch (ConfigurationException ex)
        {
    	    if (log.isErrorEnabled()) log.error("XSLT stylesheet not configured", ex);
	    throw new WebApplicationException(ex, Response.Status.INTERNAL_SERVER_ERROR);
        }
        */
        catch (TransformerConfigurationException ex)
        {
	    if (log.isErrorEnabled()) log.error("XSLT transformer not configured property", ex);
	    throw new WebApplicationException(ex, Response.Status.INTERNAL_SERVER_ERROR);
        }
        catch (FileNotFoundException ex)
        {
	    if (log.isErrorEnabled()) log.error("XSLT stylesheet not found", ex);
	    throw new WebApplicationException(ex, Response.Status.INTERNAL_SERVER_ERROR);
        }
        catch (URISyntaxException | MalformedURLException ex)
        {
    	    if (log.isErrorEnabled()) log.error("XSLT stylesheet URL error", ex);
	    throw new WebApplicationException(ex, Response.Status.INTERNAL_SERVER_ERROR);
        }
    }
    
    public Templates getTemplates(URI stylesheetURI) throws FileNotFoundException, URISyntaxException, TransformerConfigurationException, MalformedURLException
    {
        return ((SAXTransformerFactory)TransformerFactory.newInstance()).newTemplates(getSource(stylesheetURI));
    }
    
    /**
     * Converts stylesheet resource into XML source.
     * 
     * @param stylesheetURI stylesheet URI
     * @return stylesheet XML source<commit_msg>Refactored TemplatesProvider to cache multiple stylesheets in Map<URI, Templates><commit_after>/**
 *  Copyright 2013 <NAME> <<EMAIL>>
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package org.graphity.client.provider;

import com.hp.hpl.jena.rdf.model.Property;
import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.spi.inject.Injectable;
import com.sun.jersey.spi.inject.PerRequestTypeInjectableProvider;
import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletConfig;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamSource;
import org.graphity.client.vocabulary.GC;
import org.graphity.core.exception.ConfigurationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * JAX-RS provider for XSLT builder.
 * Needs to be registered in the application.
 * 
 * @author <NAME> <<EMAIL>>
 * @see org.graphity.client.util.XSLTBuilder
 */
@Provider
public class TemplatesProvider extends PerRequestTypeInjectableProvider<Context, Templates> implements ContextResolver<Templates>
{

    private static final Logger log = LoggerFactory.getLogger(TemplatesProvider.class);

    private final ServletConfig servletConfig;
    private final Map<URI, Templates> templatesCache = new HashMap<>();
    private final boolean cacheStylesheet;

    /**
     * 
     * @param servletConfig
     */
    public TemplatesProvider(@Context ServletConfig servletConfig)
    {
	super(Templates.class);
        this.servletConfig = servletConfig;
        
        if (servletConfig.getInitParameter(GC.cacheStylesheet.getURI()) != null)
            cacheStylesheet = Boolean.parseBoolean(servletConfig.getInitParameter(GC.cacheStylesheet.getURI()).toString());
        else cacheStylesheet = false;
    }

    public ServletConfig getServletConfig()
    {
        return servletConfig;
    }
    
    protected Map<URI, Templates> getTemplatesCache()
    {
        return templatesCache;
    }
    
    public boolean cacheStylesheet()
    {
        return cacheStylesheet;
    }

    @Override
    public Injectable<Templates> getInjectable(ComponentContext cc, Context a)
    {
	return new Injectable<Templates>()
	{
	    @Override
	    public Templates getValue()
	    {
                return getTemplates();
	    }
	};
    }

    @Override
    public Templates getContext(Class<?> type)
    {
        return getTemplates();
    }

    /**
     * Returns configured XSLT stylesheet resource.
     * Uses <code>gc:stylesheet</code> context parameter value from web.xml as stylesheet location.
     * 
     * @param property
     * @return stylesheet URI
     * @throws URISyntaxException 
     */
    public URI getStylesheetURI(Property property) throws URISyntaxException
    {
        Object stylesheetURI = getServletConfig().getInitParameter(property.getURI());
        if (stylesheetURI != null) return new URI(stylesheetURI.toString());
        
        return null;
    }
    
    public URI getStylesheetURI() throws URISyntaxException
    {
        URI stylesheetURI = getStylesheetURI(GC.stylesheet);
        
        if (stylesheetURI == null)
        {
            if (log.isErrorEnabled()) log.error("XSLT stylesheet (gc:stylesheet) not configured");
            throw new ConfigurationException("XSLT stylesheet (gc:stylesheet) not configured");
        }
        
        return stylesheetURI;
    }
    
    /**
     * Constructs XSLT builder from configuration.
     * 
     * @return XSLT builder object
     */
    public Templates getTemplates()
    {
        try
        {
            URI stylesheetURI = getStylesheetURI();
            if (cacheStylesheet())
            {
                // create cache entry if it does not exist
                if (!getTemplatesCache().containsKey(stylesheetURI))
                    getTemplatesCache().put(stylesheetURI, getTemplates(stylesheetURI));

                return getTemplatesCache().get(stylesheetURI);
            }
            else
                return getTemplates(stylesheetURI);
        }
        catch (TransformerConfigurationException ex)
        {
	    if (log.isErrorEnabled()) log.error("XSLT transformer not configured property", ex);
	    throw new WebApplicationException(ex, Response.Status.INTERNAL_SERVER_ERROR);
        }
        catch (FileNotFoundException ex)
        {
	    if (log.isErrorEnabled()) log.error("XSLT stylesheet not found", ex);
	    throw new WebApplicationException(ex, Response.Status.INTERNAL_SERVER_ERROR);
        }
        catch (URISyntaxException | MalformedURLException ex)
        {
    	    if (log.isErrorEnabled()) log.error("XSLT stylesheet URL error", ex);
	    throw new WebApplicationException(ex, Response.Status.INTERNAL_SERVER_ERROR);
        }
    }
    
    public Templates getTemplates(URI stylesheetURI) throws FileNotFoundException, URISyntaxException, TransformerConfigurationException, MalformedURLException
    {
        return ((SAXTransformerFactory)TransformerFactory.newInstance()).newTemplates(getSource(stylesheetURI));
    }
    
    /**
     * Converts stylesheet resource into XML source.
     * 
     * @param stylesheetURI stylesheet URI
     * @return stylesheet XML source
{'fraction_non_alphanumeric': 0.08983931180003246, 'fraction_numerical': 0.0016231131309852296, 'mean_word_length': 3.0994677312042582, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 14}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5012086', 'n_tokens_mistral': 3388, 'n_tokens_neox': 3351, 'n_words': 821}