mirror of
				https://github.com/Alfresco/alfresco-community-repo.git
				synced 2025-10-29 15:21:53 +00:00 
			
		
		
		
	<schema ... tablecolumnorder="false"> The above snippet will disable column order checking for tables. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@46517 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
		
			
				
	
	
		
			323 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			323 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| /*
 | |
|  * Copyright (C) 2005-2011 Alfresco Software Limited.
 | |
|  *
 | |
|  * This file is part of Alfresco
 | |
|  *
 | |
|  * Alfresco is free software: you can redistribute it and/or modify
 | |
|  * it under the terms of the GNU Lesser General Public License as published by
 | |
|  * the Free Software Foundation, either version 3 of the License, or
 | |
|  * (at your option) any later version.
 | |
|  *
 | |
|  * Alfresco 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 Lesser General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU Lesser General Public License
 | |
|  * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | |
|  */
 | |
| package org.alfresco.util.schemacomp;
 | |
| 
 | |
| import java.util.List;
 | |
| 
 | |
| import org.alfresco.util.schemacomp.model.Column;
 | |
| import org.alfresco.util.schemacomp.model.DbObject;
 | |
| import org.alfresco.util.schemacomp.model.ForeignKey;
 | |
| import org.alfresco.util.schemacomp.model.Index;
 | |
| import org.alfresco.util.schemacomp.model.PrimaryKey;
 | |
| import org.alfresco.util.schemacomp.model.Schema;
 | |
| import org.alfresco.util.schemacomp.model.Table;
 | |
| import org.alfresco.util.schemacomp.validator.DbValidator;
 | |
| import org.xml.sax.Attributes;
 | |
| import org.xml.sax.ContentHandler;
 | |
| import org.xml.sax.SAXException;
 | |
| import org.xml.sax.helpers.AttributesImpl;
 | |
| 
 | |
| /**
 | |
|  * Converts DbObject instances into an XML output stream.
 | |
|  * 
 | |
|  * @author Matt Ward
 | |
|  */
 | |
| public class DbObjectXMLTransformer
 | |
| {
 | |
|     private static final Attributes EMPTY_ATTRIBUTES = new AttributesImpl();
 | |
|     private ContentHandler xmlOut;
 | |
|     
 | |
|     
 | |
|     public DbObjectXMLTransformer(ContentHandler contentHandler)
 | |
|     {
 | |
|         this.xmlOut = contentHandler;
 | |
|     }
 | |
|     
 | |
|     public void output(DbObject dbObject)
 | |
|     {
 | |
|         try
 | |
|         {
 | |
|             attemptOutput(dbObject);
 | |
|         }
 | |
|         catch (SAXException e)
 | |
|         {
 | |
|             throw new RuntimeException("Unable to output " + dbObject, e);
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     private void attemptOutput(DbObject dbObject) throws SAXException
 | |
|     {
 | |
|         // All DbObjects result in an XML element with the DbObject's class name as the tag
 | |
|         // and a name attribute corresponding to the value of getName(),
 | |
|         // e.g. For an instance of a Column: <column name="the_column_name"/>
 | |
|         final AttributesImpl attribs = new AttributesImpl();
 | |
|         if (dbObject instanceof Schema)
 | |
|         {
 | |
|             // XML Schema (XSD) declarations.
 | |
|             attribs.addAttribute("", "", "xmlns", "CDATA", "http://www.alfresco.org/repo/db-schema");
 | |
|             attribs.addAttribute("", "", "xmlns:xsi", "CDATA", "http://www.w3.org/2001/XMLSchema-instance");
 | |
|             attribs.addAttribute("", "", "xsi:schemaLocation", "CDATA", "http://www.alfresco.org/repo/db-schema db-schema.xsd");
 | |
|         }
 | |
|         attribs.addAttribute("", "", XML.ATTR_NAME, "CDATA", dbObject.getName());
 | |
|         // Add class-specific attributes (after common DbObject attributes).
 | |
|         addAttributes(dbObject, attribs);
 | |
|         String tagName = dbObject.getClass().getSimpleName().toLowerCase();   
 | |
|         xmlOut.startElement("", "", tagName, attribs);
 | |
|         
 | |
|         // All DbObjects potentially have validator configuration present in the XML.
 | |
|         transformValidators(dbObject.getValidators());
 | |
|         
 | |
|         // The element's contents can optionally be populated with class-specific content.
 | |
|         transformDbObject(dbObject);
 | |
|         
 | |
|         
 | |
|         // Provide the end tag, or close an empty element.
 | |
|         xmlOut.endElement("", "", tagName);
 | |
|     }
 | |
|     
 | |
|     
 | |
|     /**
 | |
|      * @param validators
 | |
|      * @throws SAXException 
 | |
|      */
 | |
|     private void transformValidators(List<DbValidator> validators) throws SAXException
 | |
|     {
 | |
|         if (validators.size() > 0)
 | |
|         {
 | |
|             simpleStartTag(XML.EL_VALIDATORS);
 | |
|             for (DbValidator dbv : validators)
 | |
|             {
 | |
|                 final AttributesImpl attribs = new AttributesImpl();
 | |
|                 attribs.addAttribute("", "", XML.ATTR_CLASS, "CDATA", dbv.getClass().getName());
 | |
|                 xmlOut.startElement("", "", XML.EL_VALIDATOR, attribs);
 | |
|                 
 | |
|                 if (dbv.getPropertyNames().size() > 0)
 | |
|                 {
 | |
|                     simpleStartTag(XML.EL_PROPERTIES);
 | |
|                     for (String propName : dbv.getPropertyNames())
 | |
|                     {
 | |
|                         final AttributesImpl propAttrs = new AttributesImpl();
 | |
|                         propAttrs.addAttribute("", "", XML.ATTR_NAME, "CDATA", propName);
 | |
|                         xmlOut.startElement("", "", XML.EL_PROPERTY, propAttrs);
 | |
|                         String propValue = dbv.getProperty(propName);
 | |
|                         char[] chars = propValue.toCharArray();
 | |
|                         xmlOut.characters(chars, 0, chars.length);
 | |
|                         simpleEndTag(XML.EL_PROPERTY);
 | |
|                     }
 | |
|                     simpleEndTag(XML.EL_PROPERTIES);
 | |
|                 }
 | |
|                 
 | |
|                 simpleEndTag(XML.EL_VALIDATOR);
 | |
|             }
 | |
|             simpleEndTag(XML.EL_VALIDATORS);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Add class-specific attributes.
 | |
|      * 
 | |
|      * @param dbObject
 | |
|      * @param attribs
 | |
|      */
 | |
|     private void addAttributes(DbObject dbObject, AttributesImpl attribs)
 | |
|     {
 | |
|         if (dbObject instanceof Schema)
 | |
|         {
 | |
|             Schema schema = (Schema) dbObject;
 | |
|             attribs.addAttribute("", "", XML.ATTR_DB_PREFIX, "CDATA", schema.getDbPrefix());
 | |
|             attribs.addAttribute("", "", XML.ATTR_VERSION, "CDATA", Integer.toString(schema.getVersion()));
 | |
|             attribs.addAttribute("", "", XML.ATTR_TABLE_COLUMN_ORDER, "CDATA", Boolean.toString(schema.isCheckTableColumnOrder()));
 | |
|         }
 | |
|         else if (dbObject instanceof Index)
 | |
|         {
 | |
|             Index index = (Index) dbObject;
 | |
|             attribs.addAttribute("", "", XML.ATTR_UNIQUE, "CDATA", Boolean.toString(index.isUnique()));
 | |
|         }
 | |
|         else if (dbObject instanceof Column)
 | |
|         {
 | |
|             Column column = (Column) dbObject;
 | |
|             attribs.addAttribute("", "", XML.ATTR_ORDER, "CDATA", Integer.toString(column.getOrder()));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private void transformDbObject(DbObject dbObject) throws SAXException
 | |
|     {
 | |
|         if (dbObject instanceof Schema)
 | |
|         {
 | |
|             transformSchema((Schema) dbObject);
 | |
|         }
 | |
|         else if (dbObject instanceof Table)
 | |
|         {
 | |
|             transformTable((Table) dbObject);
 | |
|         }
 | |
|         else if (dbObject instanceof Column)
 | |
|         {
 | |
|             transformColumn((Column) dbObject);
 | |
|         }
 | |
|         else if (dbObject instanceof ForeignKey)
 | |
|         {
 | |
|             transformForeignKey((ForeignKey) dbObject);
 | |
|         }
 | |
|         else if (dbObject instanceof Index)
 | |
|         {
 | |
|             transformIndex((Index) dbObject);
 | |
|         }
 | |
|         else if (dbObject instanceof PrimaryKey)
 | |
|         {
 | |
|             transformPrimaryKey((PrimaryKey) dbObject);
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     
 | |
| 
 | |
|     private void transformSchema(Schema schema) throws SAXException
 | |
|     {
 | |
|         simpleStartTag(XML.EL_OBJECTS);
 | |
|         for (DbObject dbo : schema)
 | |
|         {
 | |
|             output(dbo);
 | |
|         }
 | |
|         simpleEndTag(XML.EL_OBJECTS);
 | |
|     }
 | |
|     
 | |
|     private void transformTable(Table table) throws SAXException
 | |
|     {
 | |
|         // Output columns
 | |
|         simpleStartTag(XML.EL_COLUMNS);
 | |
|         for (Column column : table.getColumns())
 | |
|         {
 | |
|             output(column);
 | |
|         }
 | |
|         simpleEndTag(XML.EL_COLUMNS);
 | |
|         
 | |
|         // Output primary key
 | |
|         if (table.hasPrimaryKey())
 | |
|         {
 | |
|             output(table.getPrimaryKey());
 | |
|         }
 | |
|         
 | |
|         // Output foreign keys
 | |
|         simpleStartTag(XML.EL_FOREIGN_KEYS);
 | |
|         for (ForeignKey fk : table.getForeignKeys())
 | |
|         {
 | |
|             output(fk);
 | |
|         }
 | |
|         simpleEndTag(XML.EL_FOREIGN_KEYS);
 | |
| 
 | |
|         // Output indexes
 | |
|         simpleStartTag(XML.EL_INDEXES);
 | |
|         for (Index index : table.getIndexes())
 | |
|         {
 | |
|             output(index);
 | |
|         }
 | |
|         simpleEndTag(XML.EL_INDEXES);
 | |
|     }
 | |
|     
 | |
|     private void transformColumn(Column column) throws SAXException
 | |
|     {
 | |
|         simpleElement(XML.EL_TYPE, column.getType());
 | |
|         simpleElement(XML.EL_NULLABLE, Boolean.toString(column.isNullable()));
 | |
|         simpleElement(XML.EL_AUTOINCREMENT, Boolean.toString(column.isAutoIncrement()));
 | |
|     }
 | |
| 
 | |
|     private void transformForeignKey(ForeignKey fk) throws SAXException
 | |
|     {
 | |
|         simpleElement(XML.EL_LOCAL_COLUMN, fk.getLocalColumn());
 | |
|         simpleElement(XML.EL_TARGET_TABLE, fk.getTargetTable());
 | |
|         simpleElement(XML.EL_TARGET_COLUMN, fk.getTargetColumn()); 
 | |
|     }
 | |
| 
 | |
|     private void transformIndex(Index index) throws SAXException
 | |
|     {
 | |
|         columnNameList(index.getColumnNames(), null);
 | |
|     }
 | |
|     
 | |
|     private void transformPrimaryKey(PrimaryKey pk) throws SAXException
 | |
|     {
 | |
|         columnNameList(pk.getColumnNames(), pk.getColumnOrders());
 | |
|     }
 | |
|     
 | |
|     
 | |
|     /**
 | |
|      * Create a simple element of the form:
 | |
|      * <pre>
 | |
|      *    <tag>content</tag>
 | |
|      * </pre>
 | |
|      * 
 | |
|      * @param tag
 | |
|      * @param content
 | |
|      * @throws SAXException
 | |
|      */
 | |
|     private void simpleElement(String tag, String content) throws SAXException
 | |
|     {
 | |
|         simpleStartTag(tag);
 | |
|         char[] chars = content.toCharArray();
 | |
|         xmlOut.characters(chars, 0, chars.length);
 | |
|         simpleEndTag(tag);
 | |
|     }
 | |
|     
 | |
|     private void simpleStartTag(String tag) throws SAXException
 | |
|     {
 | |
|         xmlOut.startElement("", "", tag, DbObjectXMLTransformer.EMPTY_ATTRIBUTES);
 | |
|     }
 | |
|     
 | |
|     private void simpleEndTag(String tag) throws SAXException
 | |
|     {
 | |
|         xmlOut.endElement("", "", tag);        
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Outputs a list of columnname elements sandwiched within a columnnames element.
 | |
|      * <p>
 | |
|      * The columnOrders parameter will provide a corresponding list of integers that will be
 | |
|      * provided in each columnname element's order attribute. This parameter may be null
 | |
|      * in which case order attributes will be ommitted.
 | |
|      *  
 | |
|      * @param columnNames
 | |
|      * @param columnOrders
 | |
|      * @throws SAXException
 | |
|      */
 | |
|     private void columnNameList(List<String> columnNames,
 | |
|                                 List<Integer> columnOrders) throws SAXException
 | |
|     {
 | |
|         simpleStartTag(XML.EL_COLUMN_NAMES);
 | |
|         for (int i = 0; i < columnNames.size(); i++)
 | |
|         {
 | |
|             String columnName = columnNames.get(i);
 | |
|             
 | |
|             final AttributesImpl attribs = new AttributesImpl();
 | |
|             if (columnOrders != null)
 | |
|             {
 | |
|                 int columnOrder = columnOrders.get(i);   
 | |
|                 attribs.addAttribute("", "", XML.ATTR_ORDER, "CDATA", Integer.toString(columnOrder));
 | |
|             }
 | |
|             // Create a <columnname> or <columnname order="n"> start tag
 | |
|             xmlOut.startElement("", "", XML.EL_COLUMN_NAME, attribs);
 | |
|             
 | |
|             // Provide the elements content
 | |
|             char[] chars = columnName.toCharArray();
 | |
|             xmlOut.characters(chars, 0, chars.length);
 | |
|             
 | |
|             // Provide the closing tag
 | |
|             simpleEndTag(XML.EL_COLUMN_NAME);
 | |
|         }
 | |
|         simpleEndTag(XML.EL_COLUMN_NAMES);
 | |
|     }
 | |
| }
 |