package org.apache.commons.digester3.xmlrules;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

import static java.util.Collections.unmodifiableSet;
import static org.apache.commons.digester3.binder.DigesterLoader.newLoader;

import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.digester3.Digester;
import org.apache.commons.digester3.binder.AbstractRulesModule;
import org.xml.sax.InputSource;

/**
 * {@link org.apache.commons.digester3.binder.RulesModule} implementation that allows loading rules from
 * XML files.
 *
 * @since 3.0
 */
public abstract class FromXmlRulesModule
    extends AbstractRulesModule
{

    private static final String DIGESTER_PUBLIC_ID = "-//Apache Commons //DTD digester-rules XML V1.0//EN";

    private static final String DIGESTER_DTD_PATH = "digester-rules.dtd";

    private final URL xmlRulesDtdUrl = FromXmlRulesModule.class.getResource( DIGESTER_DTD_PATH );

    private final List<InputSource> inputSource = new ArrayList<InputSource>();

    private final Set<String> systemIds = new HashSet<String>();

    private String rootPath;

    /**
     * {@inheritDoc}
     */
    @Override
    protected void configure()
    {
        if ( !inputSource.isEmpty() )
        {
            throw new IllegalStateException( "Re-entry is not allowed." );
        }

        try
        {
            loadRules();

            XmlRulesModule xmlRulesModule = new XmlRulesModule( new NameSpaceURIRulesBinder( rulesBinder() ),
                                                                getSystemIds(), rootPath );
            Digester digester = newLoader( xmlRulesModule )
                    .register( DIGESTER_PUBLIC_ID, xmlRulesDtdUrl.toString() )
                    .setXIncludeAware( true )
                    .setValidating( true )
                    .newDigester();

            for ( InputSource source : inputSource )
            {
                try
                {
                    digester.parse( source );
                }
                catch ( Exception e )
                {
                    addError( "Impossible to load XML defined in the InputSource '%s': %s", source.getSystemId(),
                              e.getMessage() );
                }
            }
        }
        finally
        {
            inputSource.clear();
        }
    }

    /**
     * 
     */
    protected abstract void loadRules();

    /**
     * Reads the XML rules from the given {@code org.xml.sax.InputSource}.
     *
     * @param inputSource The {@code org.xml.sax.InputSource} where reading the XML rules from.
     */
    protected final void loadXMLRules( InputSource inputSource )
    {
        if ( inputSource == null )
        {
            throw new IllegalArgumentException( "Argument 'inputSource' must be not null" );
        }

        this.inputSource.add( inputSource );

        String systemId = inputSource.getSystemId();
        if ( systemId != null )
        {
            if ( !systemIds.add( systemId ) )
            {
                addError( "XML rules file '%s' already bound", systemId );
            }
        }
    }

    /**
     * Opens a new {@code org.xml.sax.InputSource} given a {@code java.io.InputStream}.
     *
     * @param input The {@code java.io.InputStream} where reading the XML rules from.
     */
    protected final void loadXMLRules( InputStream input )
    {
        if ( input == null )
        {
            throw new IllegalArgumentException( "Argument 'input' must be not null" );
        }

        loadXMLRules( new InputSource( input ) );
    }

    /**
     * Opens a new {@code org.xml.sax.InputSource} given a {@code java.io.Reader}.
     *
     * @param reader The {@code java.io.Reader} where reading the XML rules from.
     */
    protected final void loadXMLRules( Reader reader )
    {
        if ( reader == null )
        {
            throw new IllegalArgumentException( "Argument 'input' must be not null" );
        }

        loadXMLRules( new InputSource( reader ) );
    }

    /**
     * Opens a new {@code org.xml.sax.InputSource} given a {@code java.io.File}.
     *
     * @param file The {@code java.io.File} where reading the XML rules from.
     */
    protected final void loadXMLRules( File file )
    {
        if ( file == null )
        {
            throw new IllegalArgumentException( "Argument 'input' must be not null" );
        }

        try
        {
            loadXMLRules( file.toURI().toURL() );
        }
        catch ( MalformedURLException e )
        {
            rulesBinder().addError( e );
        }
    }

    /**
     * Opens a new {@code org.xml.sax.InputSource} given a URI in String representation.
     *
     * @param uri The URI in String representation where reading the XML rules from.
     */
    protected final void loadXMLRules( String uri )
    {
        if ( uri == null )
        {
            throw new IllegalArgumentException( "Argument 'uri' must be not null" );
        }

        try
        {
            loadXMLRules( new URL( uri ) );
        }
        catch ( MalformedURLException e )
        {
            rulesBinder().addError( e );
        }
    }

    /**
     * Opens a new {@code org.xml.sax.InputSource} given a {@code java.net.URL}.
     *
     * @param url The {@code java.net.URL} where reading the XML rules from.
     */
    protected final void loadXMLRules( URL url )
    {
        if ( url == null )
        {
            throw new IllegalArgumentException( "Argument 'url' must be not null" );
        }

        try
        {
            URLConnection connection = url.openConnection();
            connection.setUseCaches( false );
            InputStream stream = connection.getInputStream();
            InputSource source = new InputSource( stream );
            source.setSystemId( url.toExternalForm() );

            loadXMLRules( source );
        }
        catch ( Exception e )
        {
            rulesBinder().addError( e );
        }
    }

    /**
     * Opens a new {@code org.xml.sax.InputSource} given an XML document in textual form.
     *
     * @param xmlText The XML document in textual form where reading the XML rules from.
     */
    protected final void loadXMLRulesFromText( String xmlText )
    {
        if ( xmlText == null )
        {
            throw new IllegalArgumentException( "Argument 'xmlText' must be not null" );
        }

        loadXMLRules( new StringReader( xmlText ) );
    }

    /**
     * Set the root path (will be used when composing modules).
     *
     * @param rootPath The root path
     */
    protected final void useRootPath( String rootPath )
    {
        this.rootPath = rootPath;
    }

    /**
     * Returns the XML source SystemIds load by this module.
     *
     * @return The XML source SystemIds load by this module
     */
    public final Set<String> getSystemIds()
    {
        return unmodifiableSet( systemIds );
    }

}
