⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dumpmetadatatask.java

📁 OBPM是一个开源
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
package org.apache.ddlutils.task;

/*
 * 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 java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;

import org.apache.commons.collections.set.ListOrderedSet;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.dom4j.Document;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

/**
 * A simple helper task that dumps information about a database using JDBC.
 * 
 * @version $Revision: 289996 $
 * @ant.task name="dumpMetadata"
 */
public class DumpMetadataTask extends Task
{
    /** Methods that are filtered when enumerating the properties. */
    private static final String[] IGNORED_PROPERTY_METHODS = { "getConnection", "getCatalogs", "getSchemas" };

    /** The data source to use for accessing the database. */
    private BasicDataSource _dataSource;
    /** The file to write the dump to. */
    private File _outputFile = null;
    /** The encoding of the XML output file. */
    private String _outputEncoding = "UTF-8";
    /** The database catalog(s) to read. */
    private String _catalogPattern = "%";
    /** The database schema(s) to read. */
    private String _schemaPattern = "%";
    /** The pattern for reading all tables. */
    private String _tablePattern = "%";
    /** The pattern for reading all procedures. */
    private String _procedurePattern = "%";
    /** The pattern for reading all columns. */
    private String _columnPattern = "%";
    /** The tables types to read; <code>null</code> or an empty list means that we shall read every type. */
    private String[] _tableTypes = null;
    /** Whether to read tables. */
    private boolean _dumpTables = true;
    /** Whether to read procedures. */
    private boolean _dumpProcedures = true;

    /**
     * Adds the data source to use for accessing the database.
     * 
     * @param dataSource The data source
     */
    public void addConfiguredDatabase(BasicDataSource dataSource)
    {
        _dataSource = dataSource;
    }

    /**
     * Specifies the output file to which the database metadata is written to.
     *
     * @param outputFile The output file
     * @ant.required
     */
    public void setOutputFile(File outputFile)
    {
        _outputFile = outputFile;
    }

    /**
     * Specifies the encoding of the output file.
     *
     * @param encoding The encoding
     * @ant.not-required Per default, <code>UTF-8</code> is used.
     */
    public void setOutputEncoding(String encoding)
    {
        _outputEncoding = encoding;
    }

    /**
     * Sets the catalog pattern used when accessing the database.
     *
     * @param catalogPattern The catalog pattern
     * @ant.not-required Per default, no specific catalog is used (value <code>%</code>).
     */
    public void setCatalogPattern(String catalogPattern)
    {
        _catalogPattern = ((catalogPattern == null) || (catalogPattern.length() == 0) ? null : catalogPattern);
    }

    /**
     * Sets the schema pattern used when accessing the database.
     *
     * @param schemaPattern The schema pattern
     * @ant.not-required Per default, no specific schema is used (value <code>%</code>).
     */
    public void setSchemaPattern(String schemaPattern)
    {
        _schemaPattern = ((schemaPattern == null) || (schemaPattern.length() == 0) ? null : schemaPattern);
    }

    /**
     * Specifies the table to be processed. For details see
     * <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/sql/DatabaseMetaData.html#getTables(java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String[])">java.sql.DatabaseMetaData#getTables</a>.
     *
     * @param tablePattern The table pattern
     * @ant.not-required By default, all tables are read (value <code>%</code>).
     */
    public void setTablePattern(String tablePattern)
    {
        _tablePattern = ((tablePattern == null) || (tablePattern.length() == 0) ? null : tablePattern);
    }

    /**
     * Specifies the procedures to be processed. For details and typical table types see
     * <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/sql/DatabaseMetaData.html#getProcedures(java.lang.String,%20java.lang.String,%20java.lang.String)">java.sql.DatabaseMetaData#getProcedures</a>.
     *
     * @param procedurePattern The procedure pattern
     * @ant.not-required By default, all procedures are read (value <code>%</code>).
     */
    public void setProcedurePattern(String procedurePattern)
    {
        _procedurePattern = ((procedurePattern == null) || (procedurePattern.length() == 0) ? null : procedurePattern);
    }

    /**
     * Specifies the columns to be processed. For details and typical table types see
     * <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/sql/DatabaseMetaData.html#getColumns(java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String[])">java.sql.DatabaseMetaData#getColumns</a>.
     *
     * @param columnPattern The column pattern
     * @ant.not-required By default, all columns are read (value <code>%</code>).
     */
    public void setColumnPattern(String columnPattern)
    {
        _columnPattern = ((columnPattern == null) || (columnPattern.length() == 0) ? null : columnPattern);
    }

    /**
     * Specifies the table types to be processed. For details and typical table types see
     * <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/sql/DatabaseMetaData.html#getTables(java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String[])">java.sql.DatabaseMetaData#getTables</a>.
     *
     * @param tableTypes The table types to read
     * @ant.not-required By default, all types of tables are read.
     */
    public void setTableTypes(String tableTypes)
    {
        ArrayList types = new ArrayList();

        if (tableTypes != null)
        {
            StringTokenizer tokenizer = new StringTokenizer(tableTypes, ",");

            while (tokenizer.hasMoreTokens())
            {
                String token = tokenizer.nextToken().trim();

                if (token.length() > 0)
                {
                    types.add(token);
                }
            }
        }
        _tableTypes = (String[])types.toArray(new String[types.size()]);
    }

    /**
     * Specifies whether procedures shall be read from the database.
     *
     * @param readProcedures <code>true</code> if procedures shall be read
     * @ant.not-required By default, procedures are read.
     */
    public void setDumpProcedures(boolean readProcedures)
    {
        _dumpProcedures = readProcedures;
    }

    /**
     * Specifies whether tables shall be read from the database.
     *
     * @param readTables <code>true</code> if tables shall be read
     * @ant.not-required By default, tables are read.
     */
    public void setDumpTables(boolean readTables)
    {
        _dumpTables = readTables;
    }

    /**
     * {@inheritDoc}
     */
    public void execute() throws BuildException
    {
        if (_dataSource == null)
        {
            log("No data source specified, so there is nothing to do.", Project.MSG_INFO);
            return;
        }

        Connection connection = null;
        try
        {
            Document document = DocumentFactory.getInstance().createDocument();
            Element  root     = document.addElement("metadata");

            root.addAttribute("driverClassName", _dataSource.getDriverClassName());
            
            connection = _dataSource.getConnection();
            
            dumpMetaData(root, connection.getMetaData());

            OutputFormat outputFormat = OutputFormat.createPrettyPrint();
            XMLWriter    xmlWriter    = null;

            outputFormat.setEncoding(_outputEncoding);
            if (_outputFile == null)
            {
                xmlWriter = new XMLWriter(System.out, outputFormat);
            }
            else
            {
                xmlWriter = new XMLWriter(new FileOutputStream(_outputFile), outputFormat);
            }
            xmlWriter.write(document);
            xmlWriter.close();
        }
        catch (Exception ex)
        {
            throw new BuildException(ex);
        }
        finally
        {
            if (connection != null)
            {
                try
                {
                    connection.close();
                }
                catch (SQLException ex)
                {}
            }
        }
    }

    /**
     * Dumps the database meta data into XML elements under the given element.
     * 
     * @param element  The XML element
     * @param metaData The meta data
     */
    private void dumpMetaData(Element element, DatabaseMetaData metaData) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, SQLException
    {
        // We rather iterate over the methods because most metadata properties
        // do not follow the bean naming standard
        Method[] methods  = metaData.getClass().getMethods();
        Set      filtered = new HashSet(Arrays.asList(IGNORED_PROPERTY_METHODS));

        for (int idx = 0; idx < methods.length; idx++)
        {
            // only no-arg methods that return something and that are not defined in Object
            // we also filter certain methods
            if ((methods[idx].getParameterTypes().length == 0) && 
                (methods[idx].getReturnType() != null) &&
                (Object.class != methods[idx].getDeclaringClass()) &&
                !filtered.contains(methods[idx].getName()))
            {
                dumpProperty(element, metaData, methods[idx]);
            }
        }
        dumpCatalogsAndSchemas(element, metaData);
        if (_dumpTables)
        {
            dumpTables(element, metaData);
        }
        if (_dumpProcedures)
        {
            dumpProcedures(element, metaData);
        }
    }

    /**
     * Dumps the property represented by the given method.
     * 
     * @param parent     The parent XML element
     * @param obj        The application we're working on
     * @param propGetter The method for accessing the property
     */
    private void dumpProperty(Element parent, Object obj, Method propGetter)
    {
        try
        {
            addProperty(parent, getPropertyName(propGetter.getName()), propGetter.invoke(obj, null));
        }
        catch (Throwable ex)
        {
            log("Could not dump property "+propGetter.getName()+" because of "+ex.getMessage(), Project.MSG_WARN);
        }
    }

    /**
     * Adds a property to the given element, either as an attribute (primitive value or
     * string) or as a sub element.
     * 
     * @param element The XML element
     * @param name    The name of the property
     * @param value   The value of the property
     */
    private void addProperty(Element element, String name, Object value)
    {
        if (value != null)
        {
            if (value.getClass().isArray())

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -