org.jasig.portal.tools.dbloader.TableXmlHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.jasig.portal.tools.dbloader.TableXmlHandler.java

Source

/**
 * Licensed to Jasig under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Jasig 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.
 */

package org.jasig.portal.tools.dbloader;

import java.lang.reflect.Field;
import java.sql.Types;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.hibernate.MappingException;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Mappings;
import org.hibernate.dialect.Dialect;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Index;
import org.hibernate.mapping.PrimaryKey;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.UniqueKey;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

/**
 * Builds an object model of Hibernate mapping objects for tables based on an
 * XML definition file. Once parsing is complete the generated objects are availabe
 * via {@link #getTables()}
 * 
 * @author Eric Dalquist
 * @version $Revision$
 */
public class TableXmlHandler extends BaseDbXmlHandler implements ITableDataProvider {
    private final Mappings mappings = new Configuration().createMappings();
    private final Dialect dialect;

    public TableXmlHandler(Dialect dialect) {
        this.dialect = dialect;
    }

    @Override
    public Map<String, Table> getTables() {
        return this.tables;
    }

    @Override
    public Map<String, Map<String, Integer>> getTableColumnTypes() {
        return tableColumnTypes;
    }

    private Map<String, Table> tables = new LinkedHashMap<String, Table>();
    private Map<String, Map<String, Integer>> tableColumnTypes = new CaseInsensitiveMap();

    private Table currentTable = null;
    private Map<String, Column> currentColumns = null;
    private Map<String, Integer> currentColumnTypes = null;
    private Column currentColumn = null;
    private PrimaryKey primaryKey = null;
    private Index currentIndex = null;
    private UniqueKey currentUnique = null;

    /* (non-Javadoc)
     * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
     */
    @Override
    public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
        if ("table".equals(name)) {
            this.currentColumns = new LinkedHashMap<String, Column>();
            this.currentColumnTypes = new CaseInsensitiveMap();
        } else if ("index".equals(name)) {
            this.currentIndex = new Index();
            this.currentIndex.setTable(this.currentTable);
        } else if ("unique".equals(name)) {
            this.currentUnique = new UniqueKey();
            this.currentUnique.setTable(this.currentTable);
        }

        this.chars = new StringBuilder();
    }

    /* (non-Javadoc)
     * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
     */
    @Override
    public void endElement(String uri, String localName, String name) throws SAXException {
        if ("table".equals(name)) {
            for (final Column column : this.currentColumns.values()) {
                this.currentTable.addColumn(column);
            }

            if (this.primaryKey != null) {
                this.currentTable.setPrimaryKey(this.primaryKey);
            }

            this.tables.put(this.currentTable.getName(), this.currentTable);
            this.tableColumnTypes.put(this.currentTable.getName(), this.currentColumnTypes);
            this.primaryKey = null;
            this.currentColumns = null;
            this.currentColumnTypes = null;
            this.currentTable = null;
        } else if ("column".equals(name)) {
            this.currentColumns.put(this.currentColumn.getName(), this.currentColumn);
            this.currentColumn = null;
        } else if ("name".equals(name)) {
            final String itemName = this.chars.toString().trim();

            if (this.currentIndex != null) {
                this.currentIndex.setName(itemName);
            } else if (this.currentUnique != null) {
                this.currentUnique.setName(itemName);
            } else if (this.currentTable == null) {
                this.currentTable = new Table(itemName);
            } else if (this.currentColumn == null) {
                this.currentColumn = new Column(itemName);
            }
        } else if ("type".equals(name)) {
            final String sqlTypeName = this.chars.toString().trim();

            final int sqlType = this.getSqlType(sqlTypeName);
            this.currentColumnTypes.put(this.currentColumn.getName(), sqlType);

            final String hibType = this.getHibernateType(sqlType);

            final SimpleValue value = new SimpleValue(this.mappings, this.currentTable);
            value.setTypeName(hibType);

            this.currentColumn.setValue(value);
        } else if ("param".equals(name)) {
            final String param = this.chars.toString().trim();

            final Integer length = Integer.valueOf(param);
            this.currentColumn.setLength(length);
        } else if ("primary-key".equals(name)) {
            final String columnName = this.chars.toString().trim();

            if (this.primaryKey == null) {
                this.primaryKey = new PrimaryKey();
            }

            final Column column = this.currentColumns.get(columnName);
            this.primaryKey.addColumn(column);
        } else if ("not-null".equals(name)) {
            final String columnName = this.chars.toString().trim();
            final Column column = this.currentColumns.get(columnName);
            column.setNullable(false);
        } else if ("column-ref".equals(name)) {
            final String columnName = this.chars.toString().trim();
            final Column column = this.currentColumns.get(columnName);

            if (this.currentIndex != null) {
                this.currentIndex.addColumn(column);
            } else if (this.currentUnique != null) {
                this.currentUnique.addColumn(column);
            }
        } else if ("index".equals(name)) {
            this.currentTable.addIndex(this.currentIndex);
            this.currentIndex = null;
        } else if ("unique".equals(name)) {
            this.currentTable.addUniqueKey(this.currentUnique);
            this.currentUnique = null;
        } else if ("key".equals(name)) {
            this.logger.warn("the 'key' element is ignored, use the table level 'primary-key' element instead");
        }

        this.chars = null;
    }

    protected int getSqlType(final String sqlTypeName) {
        try {
            final Field sqlTypeField = Types.class.getField(sqlTypeName);
            return sqlTypeField.getInt(null);
        } catch (SecurityException e) {
            throw new RuntimeException("Cannot access field '" + sqlTypeName + "' on " + Types.class
                    + " for column '" + this.currentColumn.getName() + "'", e);
        } catch (NoSuchFieldException e) {
            throw new IllegalArgumentException("No SQL Type field '" + sqlTypeName + "' on " + Types.class
                    + " for column '" + this.currentColumn.getName() + "'", e);
        } catch (IllegalArgumentException e) {
            throw new RuntimeException("Cannot access field '" + sqlTypeName + "' on " + Types.class
                    + " for column '" + this.currentColumn.getName() + "'", e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Cannot access field '" + sqlTypeName + "' on " + Types.class
                    + " for column '" + this.currentColumn.getName() + "'", e);
        }
    }

    protected String getHibernateType(final int sqlType) {
        final String hibType;
        try {
            hibType = this.dialect.getHibernateTypeName(sqlType);
        } catch (MappingException e) {
            throw new IllegalArgumentException("No mapped hibernate type found for '" + sqlType + "' Types value="
                    + sqlType + " for column '" + this.currentColumn.getName() + "'", e);
        }

        return hibType;
    }
}