org.acmsl.queryj.customsql.xml.SqlXmlParserImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.acmsl.queryj.customsql.xml.SqlXmlParserImpl.java

Source

/*
                    QueryJ Core
    
Copyright (C) 2002-today  Jose San Leandro Armendariz
                          chous@acm-sl.org
    
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or any later version.
    
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.
    
You should have received a copy of the GNU General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    
Thanks to ACM S.L. for distributing this library under the GPL license.
Contact info: jose.sanleandro@acm-sl.com
    
 ******************************************************************************
 *
 * Filename: SqlXmlParserImpl.java
 *
 * Author: Jose San Leandro Armendariz
 *
 * Description: Is able to read the contents contained in QueryJ's sql.xml files.
 *
 */
package org.acmsl.queryj.customsql.xml;

/*
 * Importing QueryJ Core classes.
 */
import org.acmsl.queryj.api.exceptions.CannotReadCustomSqlXmlFileException;
import org.acmsl.queryj.api.exceptions.QueryJBuildException;
import org.acmsl.queryj.customsql.AbstractCustomSqlProvider;
import org.acmsl.queryj.customsql.ConnectionFlags;
import org.acmsl.queryj.customsql.IdentifiableElement;
import org.acmsl.queryj.customsql.Parameter;
import org.acmsl.queryj.customsql.ParameterRef;
import org.acmsl.queryj.customsql.Property;
import org.acmsl.queryj.customsql.PropertyElement;
import org.acmsl.queryj.customsql.PropertyRef;
import org.acmsl.queryj.customsql.Result;
import org.acmsl.queryj.customsql.ResultSetFlags;
import org.acmsl.queryj.customsql.Sql;
import org.acmsl.queryj.customsql.SqlConnectionFlagsDAO;
import org.acmsl.queryj.customsql.SqlResultSetFlagsDAO;
import org.acmsl.queryj.customsql.SqlStatementFlagsDAO;
import org.acmsl.queryj.customsql.SqlXmlParserSqlDAO;
import org.acmsl.queryj.customsql.StatementFlags;
import org.acmsl.queryj.metadata.SqlDAO;
import org.acmsl.queryj.metadata.SqlParameterDAO;
import org.acmsl.queryj.metadata.SqlPropertyDAO;
import org.acmsl.queryj.metadata.SqlResultDAO;

/*
 * Importing some ACM-SL Java Commons classes.
 */
import org.acmsl.commons.logging.UniqueLogFactory;
import org.acmsl.commons.utils.io.FileUtils;
import org.acmsl.commons.utils.SaxUtils;

/*
 * Importing some JDK classes.
 */
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/*
 * Importing Digester classes.
 */
import org.apache.commons.digester.Digester;
import org.xml.sax.SAXParseException;

/*
 * Importing Jakarta Commons Logging classes
 */
import org.apache.commons.logging.Log;

/*
 * Importing some JetBrains annotations.
 */
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/*
 * Importing checkthread.org annotations.
 */
import org.checkthread.annotations.ThreadSafe;

/**
 * Is able to read the contents contained in QueryJ's sql.xml files.
 * @author <a href="mailto:chous@acm-sl.org">Jose San Leandro Armendariz</a>
 */
@ThreadSafe
public class SqlXmlParserImpl extends AbstractCustomSqlProvider implements SqlXmlParser {
    /**
     * The serial version id.
     */
    public static final long serialVersionUID = 4622172516611441363L;

    /**
     * The XML path for parameter-refs.
     */
    protected static final String SQL_LIST_SQL_PARAMETER_REF = "sql-list/sql/parameter-ref";

    /**
     * The XML path for result-refs.
     */
    protected static final String SQL_LIST_SQL_RESULT_REF = "sql-list/sql/result-ref";

    /**
     * The XML path for connection-flags-refs.
     */
    protected static final String SQL_LIST_SQL_CONNECTION_FLAGS_REF = "sql-list/sql/connection-flags-ref";

    /**
     * The XML path for statement-flags-refs.
     */
    protected static final String SQL_LIST_SQL_STATEMENT_FLAGS_REF = "sql-list/sql/statement-flags-ref";

    /**
     * The XML path for resultset-flags-refs.
     */
    protected static final String SQL_LIST_SQL_RESULTSET_FLAGS_REF = "sql-list/sql/resultset-flags-ref";

    /**
     * The XML path for parameters.
     */
    protected static final String SQL_LIST_PARAMETER_LIST_PARAMETER = "sql-list/parameter-list/parameter";

    /**
     * The XML path for results.
     */
    protected static final String SQL_LIST_RESULT_LIST_RESULT = "sql-list/result-list/result";

    /**
     * The XML path for property-refs.
     */
    protected static final String SQL_LIST_RESULT_LIST_RESULT_PROPERTY_REF = "sql-list/result-list/result/property-ref";

    /**
     * The XML path for property.
     */
    protected static final String SQL_LIST_PROPERTY_LIST_PROPERTY = "sql-list/property-list/property";

    /**
     * The XML path for connection-flags.
     */
    protected static final String SQL_LIST_FLAG_LIST_CONNECTION_FLAGS = "sql-list/flag-list/connection-flags";

    /**
     * The XML path for statement-flags.
     */
    protected static final String SQL_LIST_FLAG_LIST_STATEMENT_FLAGS = "sql-list/flag-list/statement-flags";

    /**
     * The XML flag for resultset-flags.
     */
    protected static final String SQL_LIST_FLAG_LIST_RESULTSET_FLAGS = "sql-list/flag-list/resultset-flags";

    /**
     * The input stream.
     */
    private transient InputStream m__isInput;

    /**
     * The class loader.
     */
    private transient ClassLoader m__ClassLoader;

    /**
     * The queries.
     */
    private List<Sql<String>> m__lQueries = new ArrayList<>();

    /**
     * The results.
     */
    private List<Result<String>> m__lResults = new ArrayList<>();

    /**
     * The parameters.
     */
    private List<Parameter<String, ?>> m__lParameters = new ArrayList<>();

    /**
     * The parameter refs.
     */
    private List<ParameterRef> m__lParameterRefs = new ArrayList<>();

    /**
     * The properties.
     */
    private List<Property<String>> m__lProperties = new ArrayList<>();

    /**
     * The property refs.
     */
    private List<PropertyRef> m__lPropertyRefs = new ArrayList<>();

    /**
     * The connection flags.
     */
    private List<ConnectionFlags> m__lConnectionFlags = new ArrayList<>();

    /**
     * The statement flags.
     */
    private List<StatementFlags> m__lStatementFlags = new ArrayList<>();

    /**
     * The result set flags.
     */
    private List<ResultSetFlags> m__lResultSetFlags = new ArrayList<>();

    /**
     * Creates a SqlXmlParserImpl with given input stream.
     * @param input the input stream.
     */
    public SqlXmlParserImpl(@NotNull final InputStream input) {
        immutableSetInput(input);
    }

    /**
     * Retrieves the {@link SqlDAO} instance.
     * @return such instance.
     */
    @NotNull
    @Override
    public SqlDAO getSqlDAO() {
        return new SqlXmlParserSqlDAO(this);
    }

    /**
     * Retrieves the {@link SqlResultDAO} instance.
     * @return such instance.
     */
    @NotNull
    @Override
    public SqlResultDAO getSqlResultDAO() {
        return new SqlXmlParserResultDAO(this);
    }

    /**
     * Retrieves the {@link SqlParameterDAO} instance.
     * @return such instance.
     */
    @NotNull
    @Override
    public SqlParameterDAO getSqlParameterDAO() {
        return new SqlXmlParserParameterDAO(this);
    }

    /**
     * Retrieves the {@link SqlPropertyDAO} instance.
     * @return such instance.
     */
    @NotNull
    @Override
    public SqlPropertyDAO getSqlPropertyDAO() {
        return new SqlXmlParserPropertyDAO(this);
    }

    /**
     * Processes given collection.
     * @param collection the collection to process.
     */
    @SuppressWarnings("unchecked")
    protected void processCollection(@NotNull final List<? extends IdentifiableElement<String>> collection) {
        for (@Nullable
        final IdentifiableElement<String> t_Item : collection) {
            if (t_Item instanceof Sql<?>) {
                addQuery((Sql<String>) t_Item);
            } else if (t_Item instanceof Result<?>) {
                addResult((Result<String>) t_Item);
            } else if (t_Item instanceof Property<?>) {
                addProperty((Property<String>) t_Item);
            } else if (t_Item instanceof PropertyRef) {
                addPropertyRef((PropertyRef) t_Item);
            } else if (t_Item instanceof Parameter<?, ?>) {
                addParameter((Parameter<String, ?>) t_Item);
            } else if (t_Item instanceof ParameterRef) {
                addParameterRef((ParameterRef) t_Item);
            } else if (t_Item instanceof ConnectionFlags) {
                addConnectionFlags((ConnectionFlags) t_Item);
            } else if (t_Item instanceof StatementFlags) {
                addStatementFlags((StatementFlags) t_Item);
            } else if (t_Item instanceof ResultSetFlags) {
                addResultSetFlags((ResultSetFlags) t_Item);
            } else {
                @Nullable
                final Log t_Log = UniqueLogFactory.getLog(SqlXmlParserImpl.class);

                if (t_Log != null) {
                    t_Log.fatal("Unexpected element : " + t_Item);
                }
            }
        }
    }

    /**
     * Adds given query, if not already annotated.
     * @param sql the query.
     */
    protected void addQuery(@NotNull final Sql<String> sql) {
        this.add(sql, getQueries());
    }

    /**
     * Adds given result, if not already annotated.
     * @param result the result.
     */
    protected void addResult(@NotNull final Result<String> result) {
        add(result, getResults());
    }

    /**
     * Adds given parameter, if not already annotated.
     * @param parameter the parameter.
     */
    protected void addParameter(@NotNull final Parameter<String, ?> parameter) {
        add(parameter, getParameters());
    }

    /**
     * Adds given parameter reference, if not already annotated.
     * @param parameterRef the parameter reference.
     */
    protected void addParameterRef(@NotNull final ParameterRef parameterRef) {
        add(parameterRef, getParameterRefs());
    }

    /**
     * Adds given property, if not already annotated.
     * @param property the property.
     */
    protected void addProperty(@NotNull final Property<String> property) {
        add(property, getProperties());
    }

    /**
     * Adds given property reference, if not already annotated.
     * @param propertyRef the property reference.
     */
    protected void addPropertyRef(@NotNull final PropertyRef propertyRef) {
        add(propertyRef, getPropertyRefs());
    }

    /**
     * Adds given connection flags, if not already annotated.
     * @param connectionFlags the connection flags reference.
     */
    protected void addConnectionFlags(@NotNull final ConnectionFlags connectionFlags) {
        add(connectionFlags, getConnectionFlagList());
    }

    /**
     * Adds given statement flags, if not already annotated.
     * @param statementFlags the statement flags reference.
     */
    protected void addStatementFlags(@NotNull final StatementFlags statementFlags) {
        add(statementFlags, getStatementFlagList());
    }

    /**
     * Adds given result-set flags, if not already annotated.
     * @param resultSetFlags the result-set flags reference.
     */
    protected void addResultSetFlags(@NotNull final ResultSetFlags resultSetFlags) {
        add(resultSetFlags, getResultSetFlagList());
    }

    /**
     * Adds given item, if not already annotated.
     * @param item the item.
     * @param items the item list.
     * @param <C> the item type.
     */
    protected <C> void add(@NotNull final C item, @NotNull final List<C> items) {
        if (!items.contains(item)) {
            items.add(item);
        }
    }

    /**
     * Specifies the queries.
     * @param queries such information.
     */
    protected final void immutableSetQueries(@NotNull final List<Sql<String>> queries) {
        m__lQueries = queries;
    }

    /**
     * Specifies the queries.
     * @param queries such information.
     */
    protected void setQueries(@NotNull final List<Sql<String>> queries) {
        immutableSetQueries(queries);
    }

    /**
     * {@inheritDoc}
     */
    @NotNull
    @Override
    public List<Sql<String>> getQueries() {
        return m__lQueries;
    }

    /**
     * Specifies the {@link Result}s.
     * @param results the results.
     */
    protected final void immutableSetResults(@NotNull final List<Result<String>> results) {
        this.m__lResults = results;
    }

    /**
     * Specifies the {@link Result}s.
     * @param results the results.
     */
    protected void setResults(@NotNull final List<Result<String>> results) {
        immutableSetResults(results);
    }

    /**
     * {@inheritDoc}
     */
    @NotNull
    @Override
    public List<Result<String>> getResults() {
        return m__lResults;
    }

    /**
     * Specifies the {@link Parameter}s.
     * @param parameters such information.
     */
    protected final void immutableSetParameters(@NotNull final List<Parameter<String, ?>> parameters) {
        this.m__lParameters = parameters;
    }

    /**
     * Specifies the {@link Parameter}s.
     * @param parameters such information.
     */
    protected void setParameters(@NotNull final List<Parameter<String, ?>> parameters) {
        immutableSetParameters(parameters);
    }

    /**
     * {@inheritDoc}
     */
    @NotNull
    @Override
    public List<Parameter<String, ?>> getParameters() {
        return m__lParameters;
    }

    /**
     * {@inheritDoc}
     */
    @NotNull
    @Override
    public List<ParameterRef> getParameterRefs() {
        return m__lParameterRefs;
    }

    /**
     * Specifies the {@link Property properties}.
     * @param properties the properties.
     */
    protected final void immutableSetProperties(@NotNull final List<Property<String>> properties) {
        this.m__lProperties = properties;
    }

    /**
     * Specifies the {@link Property properties}.
     * @param properties the properties.
     */
    protected void setProperties(@NotNull final List<Property<String>> properties) {
        immutableSetProperties(properties);
    }

    /**
     * {@inheritDoc}
     */
    @NotNull
    @Override
    public List<Property<String>> getProperties() {
        return m__lProperties;
    }

    /**
     * {@inheritDoc}
     */
    @NotNull
    @Override
    public List<PropertyRef> getPropertyRefs() {
        return m__lPropertyRefs;
    }

    /**
     * Specifies the list of {@link ConnectionFlags}.
     * @param list such list.
     */
    protected final void immutableSetConnectionFlagList(@NotNull final List<ConnectionFlags> list) {
        this.m__lConnectionFlags = list;
    }

    /**
     * Specifies the list of {@link ConnectionFlags}.
     * @param list such list.
     */
    protected void setConnectionFlagList(@NotNull final List<ConnectionFlags> list) {
        immutableSetConnectionFlagList(list);
    }

    /**
     * {@inheritDoc}
     */
    @NotNull
    @Override
    public List<ConnectionFlags> getConnectionFlagList() {
        return m__lConnectionFlags;
    }

    /**
     * Specifies the list of {@link StatementFlags}.
     * @param list such list.
     */
    protected final void immutableSetStatementFlagList(@NotNull final List<StatementFlags> list) {
        this.m__lStatementFlags = list;
    }

    /**
     * Specifies the list of {@link StatementFlags}.
     * @param list such list.
     */
    protected void setStatementFlagList(@NotNull final List<StatementFlags> list) {
        immutableSetStatementFlagList(list);
    }

    /**
     * {@inheritDoc}
     */
    @NotNull
    @Override
    public List<StatementFlags> getStatementFlagList() {
        return m__lStatementFlags;
    }

    /**
     * Specifies the list of {@link ResultSetFlags}.
     * @param list such list.
     */
    protected final void immutableSetResultSetFlagList(@NotNull final List<ResultSetFlags> list) {
        this.m__lResultSetFlags = list;
    }

    /**
     * Specifies the list of {@link ResultSetFlags}.
     * @param list such list.
     */
    protected void setResultSetFlagList(@NotNull final List<ResultSetFlags> list) {
        immutableSetResultSetFlagList(list);
    }

    /**
     * {@inheritDoc}
     */
    @NotNull
    @Override
    public List<ResultSetFlags> getResultSetFlagList() {
        return m__lResultSetFlags;
    }

    /**
     * Specifies the class loader (to give it to Digester).
     * @param classLoader the class loader.
     */
    protected final void immutableSetClassLoader(@NotNull final ClassLoader classLoader) {
        m__ClassLoader = classLoader;
    }

    /**
     * Specifies the class loader (to give it to Digester).
     * @param classLoader the class loader.
     */
    @SuppressWarnings("unused")
    public void setClassLoader(@NotNull final ClassLoader classLoader) {
        immutableSetClassLoader(classLoader);
    }

    /**
     * Retrieves the class loader.
     * @return such instance.
     */
    @Nullable
    public ClassLoader getClassLoader() {
        return m__ClassLoader;
    }

    /**
     * Specifies the input stream.
     * @param input the input stream.
     */
    protected final void immutableSetInput(@NotNull final InputStream input) {
        m__isInput = input;
    }

    /**
     * Specifies the input stream.
     * @param input the input stream.
     */
    @SuppressWarnings("unused")
    protected void setInput(@NotNull final InputStream input) {
        immutableSetInput(input);
    }

    /**
     * Retrieves the input stream.
     * @return such stream.
     */
    @Nullable
    protected InputStream getInput() {
        return m__isInput;
    }

    /**
     * Loads the information from the XML resource.
     * @throws QueryJBuildException if the parsing operation fails.
     */
    protected void load() throws QueryJBuildException {
        load(configureDigester(getClassLoader()), getInput());
    }

    /**
     * Loads the information from the XML resource.
     * @param digester the Digester instance.
     * @param input the input stream.
     * @throws QueryJBuildException if the parsing operation fails.
     */
    protected synchronized void load(@Nullable final Digester digester, @Nullable final InputStream input)
            throws QueryJBuildException {
        if (digester != null) {
            @NotNull
            final List<? extends IdentifiableElement<String>> collection = new ArrayList<>();

            digester.push(collection);

            try {
                if (input != null) {
                    digester.parse(input);

                    processCollection(collection);
                }
            } catch (@NotNull final RuntimeException exception) {
                throw exception;
            } catch (@NotNull final Exception exception) {
                try {
                    @Nullable
                    final Log t_Log = UniqueLogFactory.getLog(SqlXmlParser.class);

                    if (t_Log != null) {
                        t_Log.error("Cannot read sql.xml information.", exception);
                    }
                } catch (@NotNull final Throwable throwable) {
                    // class-loading problem.
                }

                @Nullable
                final File t_File;

                if (exception instanceof SAXParseException) {
                    t_File = SaxUtils.getInstance().retrieveFailingFile((SAXParseException) exception);
                } else if (input instanceof FileInputStream) {
                    t_File = FileUtils.getInstance().retrieveFile((FileInputStream) input);
                } else {
                    t_File = null;
                }

                throw new CannotReadCustomSqlXmlFileException(t_File, exception);
            }
        }
    }

    /**
     * Creates and configures a digester instance.
     * @param classLoader <i>optional</i> the class loader.
     * @return a configured digester instance.
     */
    @NotNull
    protected Digester configureDigester(@Nullable final ClassLoader classLoader) {
        @NotNull
        final Digester result = new Digester();

        if (classLoader != null) {
            result.setClassLoader(classLoader);
        }

        // <sql-list>

        //   <sql>
        result.addFactoryCreate("sql-list/sql", new SqlElementFactory());

        //     <description>
        result.addRule("sql-list/sql/description", new UntrimmedCallMethodRule("setDescription", 0));
        //     </description>

        //     <value>
        result.addRule("sql-list/sql/value", new UntrimmedCallMethodRule("setValue", 0));
        //     </value>

        //     <parameter-ref>
        result.addFactoryCreate(SQL_LIST_SQL_PARAMETER_REF, new ParameterRefElementFactory());
        result.addSetNext(SQL_LIST_SQL_PARAMETER_REF, "add");
        //     </parameter-ref>

        //     <result-ref>
        result.addFactoryCreate(SQL_LIST_SQL_RESULT_REF, new ResultRefElementFactory());
        result.addSetNext(SQL_LIST_SQL_RESULT_REF, "setResultRef");
        //     </result-ref>

        //     <connection-flags-ref>
        result.addFactoryCreate(SQL_LIST_SQL_CONNECTION_FLAGS_REF, new ConnectionFlagsRefElementFactory());
        result.addSetNext(SQL_LIST_SQL_CONNECTION_FLAGS_REF, "setConnectionFlagsRef");
        //     </connection-flags-ref>

        //     <statement-flags-ref>
        result.addFactoryCreate(SQL_LIST_SQL_STATEMENT_FLAGS_REF, new StatementFlagsRefElementFactory());
        result.addSetNext(SQL_LIST_SQL_STATEMENT_FLAGS_REF, "setStatementFlagsRef");
        //     </statement-flags-ref>

        //     <resultset-flags-ref>
        result.addFactoryCreate(SQL_LIST_SQL_RESULTSET_FLAGS_REF, new ResultSetFlagsRefElementFactory());
        result.addSetNext(SQL_LIST_SQL_RESULTSET_FLAGS_REF, "setResultSetFlagsRef");
        //     </resultset-flags-ref>

        result.addSetNext("sql-list/sql", "add");

        //   </sql>

        //   <parameter-list>

        /*
        result.addObjectCreate(
        "sql-list/parameter-list",
        "java.util.ArrayList");
        */

        //     <parameter>
        result.addFactoryCreate(SQL_LIST_PARAMETER_LIST_PARAMETER, new ParameterElementFactory());
        result.addSetRoot(SQL_LIST_PARAMETER_LIST_PARAMETER, "add");
        //     </parameter>
        //   </parameter-list>

        //   <result-list>
        //     <result>
        result.addFactoryCreate(SQL_LIST_RESULT_LIST_RESULT, new ResultElementFactory());
        result.addSetRoot(SQL_LIST_RESULT_LIST_RESULT, "add");

        //       <property-ref>
        result.addFactoryCreate(SQL_LIST_RESULT_LIST_RESULT_PROPERTY_REF, new PropertyRefElementFactory());
        result.addSetNext(SQL_LIST_RESULT_LIST_RESULT_PROPERTY_REF, "add");
        //       </property-ref>
        //     </result>
        //   </result-list>

        //   <property-list>
        //     <property>
        result.addFactoryCreate(SQL_LIST_PROPERTY_LIST_PROPERTY, new PropertyElementFactory());
        result.addSetRoot(SQL_LIST_PROPERTY_LIST_PROPERTY, "add");
        //     </property>
        //   </property-list>

        //   <flag-list>
        //     <connection-flags>
        result.addFactoryCreate(SQL_LIST_FLAG_LIST_CONNECTION_FLAGS, new ConnectionFlagsElementFactory());
        result.addSetRoot(SQL_LIST_FLAG_LIST_CONNECTION_FLAGS, "add");
        //     </connection-flags>
        //     <statement-flags>
        result.addFactoryCreate(SQL_LIST_FLAG_LIST_STATEMENT_FLAGS, new StatementFlagsElementFactory());
        result.addSetRoot(SQL_LIST_FLAG_LIST_STATEMENT_FLAGS, "add");
        //     </statement-flags>
        //     <resultset-flags>
        result.addFactoryCreate(SQL_LIST_FLAG_LIST_RESULTSET_FLAGS, new ResultSetFlagsElementFactory());
        result.addSetRoot(SQL_LIST_FLAG_LIST_RESULTSET_FLAGS, "add");
        //     </resultset-flags>
        //   </flag-list>

        // <sql-list>

        return result;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void parse() throws QueryJBuildException {
        @Nullable
        final List<Sql<String>> queries = getQueries();

        if (queries.size() == 0) {
            load();

            postProcess();
        }
    }

    /**
     * Post processes the parsed contents.
     */
    protected void postProcess() {
        setQueries(postProcess(getQueries()));
        setResults(postProcess(getResults()));
        setParameters(postProcess(getParameters()));
        setProperties(postProcess(getProperties()));
        setConnectionFlagList(postProcess(getConnectionFlagList()));
        setStatementFlagList(postProcess(getStatementFlagList()));
        setResultSetFlagList(postProcess(getResultSetFlagList()));
    }

    /**
     * Post-processes given items.
     * @param items the items.
     * @param <T> the type of the items.
     * @return the processed items.
     */
    @NotNull
    protected <T extends IdentifiableElement<String>> List<T> postProcess(@NotNull final List<T> items) {
        final List<T> result;

        final HashSet<T> aux = new HashSet<>(items.size());
        aux.addAll(items);

        result = new ArrayList<>(aux.size());
        result.addAll(aux);

        return result;
    }

    /**
     * Adds a new result.
     * @param id the result id.
     * @param result the <code>Result</code> instance.
     */
    @Override
    public void addResult(@NotNull final String id, @NotNull final Result<String> result) {
        addResult(id, result, getResults());
    }

    /**
     * Adds a new result.
     * @param id the result id.
     * @param result the <code>Result</code> instance.
     * @param results the results.
     */
    protected void addResult(@NotNull final String id, @NotNull final Result<String> result,
            @NotNull final List<Result<String>> results) {
        if (!results.contains(result)) {
            results.add(result);
        } else {
            @Nullable
            final Log t_Log = UniqueLogFactory.getLog(SqlXmlParserImpl.class);

            if (t_Log != null) {
                t_Log.fatal(id + " is defined more than once");
            }
        }
    }

    /**
     * Adds a new property.
     * @param id the property id.
     * @param columnName the column name.
     * @param index the property index.
     * @param type the property type.
     * @param nullable whether it allows null or not.
     */
    @Override
    public void addProperty(@NotNull final String id, @NotNull final String columnName, final int index,
            @NotNull final String type, final boolean nullable) {
        getProperties().add(new PropertyElement<>(id, columnName, index, type, nullable));
    }

    /**
     * Retrieves the {@link SqlConnectionFlagsDAO} instance.
     * @return such instance.
     */
    @NotNull
    @Override
    public SqlConnectionFlagsDAO getSqlConnectionFlagsDAO() {
        return new SqlXmlParserConnectionFlagsDAO(this);
    }

    /**
     * Retrieves the {@link SqlStatementFlagsDAO} instance.
     * @return such instance.
     */
    @NotNull
    @Override
    public SqlStatementFlagsDAO getSqlStatementFlagsDAO() {
        return new SqlXmlParserStatementFlagsDAO(this);
    }

    /**
     * Retrieves the {@link SqlResultSetFlagsDAO} instance.
     * @return such instance.
     */
    @NotNull
    @Override
    public SqlResultSetFlagsDAO getSqlResultSetFlagsDAO() {
        return new SqlXmlParserResultSetFlagsDAO(this);
    }

    /**
     * {@inheritDoc}
     */
    @NotNull
    @Override
    public String toString() {
        return "SqlXmlParserImpl{" + "m__ClassLoader=" + m__ClassLoader + ", m__isInput=" + m__isInput
                + ", m__lQueries=" + m__lQueries + ", m__lResults=" + m__lResults + ", m__lParameters="
                + m__lParameters + ", m__lParameterRefs=" + m__lParameterRefs + ", m__lProperties=" + m__lProperties
                + ", m__lPropertyRefs=" + m__lPropertyRefs + ", m__lConnectionFlags=" + m__lConnectionFlags
                + ", m__lStatementFlags=" + m__lStatementFlags + ", m__lResultSetFlags=" + m__lResultSetFlags + '}';
    }
}