Java tutorial
/** * 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; } }