All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.datastax.data.dataset.io.schema.XMLDataSetSchemaReader Maven / Gradle / Ivy

The newest version!

package com.datastax.data.dataset.io.schema;

import com.datastax.data.dataset.*;
import com.datastax.data.dataset.provider.sql.SQLCommand;
import com.datastax.data.dataset.provider.sql.SQLDataProvider;
import com.datastax.data.dataset.provider.sql.TableCommand;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;


public class XMLDataSetSchemaReader implements DataSetSchemaReader {
   
   private String xmlContents;
   
   
   private DataSetParser lastParserUsed;
   
   
   public XMLDataSetSchemaReader(InputStream xmlInputStream) throws SchemaReaderException {
      this(new InputStreamReader(xmlInputStream));
   }
   
   
   public XMLDataSetSchemaReader(Reader xmlReader) throws SchemaReaderException {
      String xml = "";
      if ( ! ( xmlReader instanceof BufferedReader)) {
         xmlReader = new BufferedReader(xmlReader);
      }
      try {
         StringBuilder builder = new StringBuilder();
         char[] bytes = new char[4096];
         int length = -1;
         while ((length = xmlReader.read(bytes)) != -1) {
            builder.append(new String(bytes, 0, length));
         }
         this.xmlContents = builder.toString();
      } catch (Exception e) {
         throw new SchemaReaderException("Can't read input stream to parse schema from.", e);
      }
   }
   
   
   public DataSet readDataSet() throws SchemaReaderException {
      return readXml(new DataSet());
   }
   
   
   public DataSet readDataSet(String... tableNames) throws SchemaReaderException {
      return readXml(new DataSet(), tableNames);
   }
   
   
   public List addRelations(DataSet dataSet, String... tableNames) throws SchemaReaderException {
      readXml(dataSet, tableNames);
      return lastParserUsed.getRelationsAdded();
      
   }
   
   
   public List addTables(DataSet dataSet, String... tableNames) throws SchemaReaderException {
      readXml(dataSet, tableNames);
      return lastParserUsed.getTablesAdded();
   }
   
   
   private DataSet readXml(DataSet dataSet, String... tableNames) throws SchemaReaderException {
      
      try {
         SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
         InputSource is = new InputSource(new StringReader(xmlContents));
         lastParserUsed = new DataSetParser(dataSet, tableNames);
         parser.parse(is, lastParserUsed);
      } catch (Exception e) {
         throw new SchemaReaderException("Failed to setup schema XML parser.", e);
      }
      return dataSet;
   }
   
   
   private static final class DataSetParser extends DefaultHandler {
      public int elementDepth = 0;
      private Attributes attrs;
      private DataSet ds;
      private DataTable table;
      private DataColumn column;
      private DataProvider dataProvider;
      private List tableNames;
      private List tablesAdded;
      private List relationsAdded;
      
      public DataSetParser(DataSet ds, String... tableNames) {
         this.ds = ds == null ? new DataSet() : ds;
         this.tableNames = new ArrayList(tableNames.length);
         Collections.addAll(this.tableNames, tableNames);
      }
      
      public DataSet getDataSet() {
         return ds;
      }
      
      
      public void startDocument() throws SAXException {
         super.startDocument();
         this.tablesAdded = new ArrayList();
         this.relationsAdded = new ArrayList();
      }
      
      public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
         this.attrs = atts;
         if (qName.equals("xs:element")) {
            elementDepth++;
            switch(elementDepth) {
               case 1:
                  
                  ds.setName(attrs.getValue("name"));
                  break;
               case 2:
                  
                  String tableName = attrs.getValue("name");
                  
                  
                  if ( ds.getTable(tableName) != null ) {
                     System.out.println("TABLE " + tableName + " ALREADY IN DATASET; SKIPPING.");
                     table = null;
                     break;
                  }
                  
                  if ( tableNames.size() > 0 && !tableNames.contains(tableName)) {
                     table = null;
                     break;
                  }
                  
                  table = ds.createTable(tableName);
                  
                  String val = attrs.getValue("appendRowSupported");
                  table.setAppendRowSupported(val == null || val.equalsIgnoreCase("true"));
                  val = attrs.getValue("deleteRowSupported");
                  table.setDeleteRowSupported(val == null || val.equalsIgnoreCase("true"));
                  tablesAdded.add(tableName);
                  break;
               case 3:
                  if ( table == null ) break;
                  
                  
                  column = table.createColumn(attrs.getValue("name"));
                  
                  val = attrs.getValue("minOccurs");
                  if (val != null && val.equals("")) {
                     column.setRequired(true);
                  }
                  
                  
                  val = attrs.getValue("keyColumn");
                  column.setKeyColumn(val == null ? false : val.equalsIgnoreCase("true"));
                  
                  
                  val = attrs.getValue("readOnly");
                  column.setReadOnly(val == null ? false : val.equalsIgnoreCase("true"));
                  
                  
                  String defaultValue = attrs.getValue("default");
                  
                  
                  val = attrs.getValue("type");
                  if (val.equals("xs:string")) {
                     column.setType(String.class);
                     if (defaultValue != null && !defaultValue.equals("")) {
                        column.setDefaultValue(defaultValue);
                     }
                  } else if (val.equals("xs:decimal")) {
                     column.setType(BigDecimal.class);
                     if (defaultValue != null && !defaultValue.equals("")) {
                        column.setDefaultValue(new BigDecimal(defaultValue));
                     }
                  } else if (val.equals("xs:integer") || val.equals("xs:int")) {
                     column.setType(Integer.class);
                     if (defaultValue != null && !defaultValue.equals("")) {
                        column.setDefaultValue(new Integer(defaultValue));
                     }
                  } else if (val.equals("xs:boolean")) {
                     column.setType(Boolean.class);
                     if (defaultValue != null && !defaultValue.equals("")) {
                        column.setDefaultValue(Boolean.parseBoolean(defaultValue));
                     }
                  } else if (val.equals("xs:date") || val.equals("xs:time") || val.equals("xs:dateTime")) {
                     column.setType(Date.class);
                     if (defaultValue != null && !defaultValue.equals("")) {
                        column.setDefaultValue(new Date(Date.parse(defaultValue)));
                     }
                  } else if (val.equals("xs:unsignedByte")) {
                     column.setType(Byte.class);
                     if (defaultValue != null && !defaultValue.equals("")) {
                        column.setDefaultValue(new Byte(defaultValue));
                     }
                  } else {
                     System.err.println("unexpected classType: '"  + val + "'");
                  }
                  
                  
                  val = attrs.getValue("expression");
                  if (val != null && !("".equals(val))) {
                     column.setExpression(val);
                  }
                  break;
               default:
                  
                  System.out.println("Error in DataSetParser");
            }
         } else if (qName.equals("dataProvider")) {
            String classType = attrs.getValue("class");
            if (classType != null) {
               try {
                  dataProvider = (DataProvider) Class.forName(classType).newInstance();
                  table.setDataProvider(dataProvider);
                  
                  if (dataProvider instanceof SQLDataProvider) {
                     String tableName = attrs.getValue("tableName");
                     if (tableName != null && !tableName.equals("")) {
                        TableCommand cmd = new TableCommand(tableName);
                        cmd.setWhereClause(attrs.getValue("whereClause"));
                        cmd.setOrderByClause(attrs.getValue("orderByClause"));
                        cmd.setHavingClause(attrs.getValue("havingClause"));
                        dataProvider.setCommand(cmd);
                     } else {
                        SQLCommand command = new SQLCommand();
                        
                        
                        command.setSelectSQL(attrs.getValue("select"));
                        command.setInsertSQL(attrs.getValue("insert"));
                        command.setUpdateSQL(attrs.getValue("update"));
                        command.setDeleteSQL(attrs.getValue("delete"));
                        dataProvider.setCommand(command);
                     }
                  }
               } catch (Exception e) {
                  
                  e.printStackTrace();
               }
            }
         } else if (qName.equals("dataRelationTable")) {
            DataRelationTable drt = ds.createRelationTable(attrs.getValue("name"));
            drt.setRelation((DataRelation)ds.getElement(attrs.getValue("relation")));
            drt.setParentSelector((DataSelector)ds.getElement(attrs.getValue("parentSelector")));
            drt.setParentTable((DataTable)ds.getElement(attrs.getValue("parentTable")));
         } else if (qName.equals("dataRelation")) {
            String relationName = attrs.getValue("name");
            
            String parentColumnName = attrs.getValue("parentColumn");
            String childColumnName = attrs.getValue("childColumn");
            String parentTableName = parentColumnName.substring(0, parentColumnName.indexOf("."));
            String childTableName = childColumnName.substring(0, childColumnName.indexOf("."));
            try {
               if ( tableNames.size() > 0 &&
                     tableNames.contains(parentTableName) &&
                     tableNames.contains(childTableName)) {
                  
                  DataColumn parentColumn = (DataColumn)ds.getElement(parentColumnName);
                  DataColumn childColumn = (DataColumn)ds.getElement(childColumnName);
                  if ( parentColumn != null && childColumn != null ) {
                     if ( ds.getRelation(relationName) != null ) {
                        ds.dropRelation(relationName);
                     }
                     DataRelation relation = ds.createRelation(relationName);
                     
                     relation.setParentColumn(parentColumn);
                     relation.setChildColumn(childColumn);
                     relationsAdded.add(relationName);
                  }
               } else {
                  System.err.println("DataRelation: Either parent " + parentColumnName + " or child " + childColumnName +
                        " is missing in DataSource. Tables might not be loaded, or the respective columns might not be. " +
                        "Skipping.");
               }
            } catch ( Exception e ) {
               System.out.println("failed on Parent: " + parentColumnName);
               
            }
         } else if (qName.equals("dataValue")) {
            DataValue value = ds.createValue(attrs.getValue("name"));
            value.setExpression(attrs.getValue("expression"));
         }
      }
      
      public void endElement(String uri, String localName, String qName) throws SAXException {
         if (qName.equals("xs:element")) {
            switch(elementDepth) {
               case 1:
                  
                  break;
               case 2:
                  
                  break;
               case 3:
                  
                  break;
               default:
                  
                  System.out.println("Error in DataSetParser");
            }
            elementDepth--;
         }
      }
      
      public void endDocument() throws SAXException {
      }
      
      public List getTablesAdded() {
         return tablesAdded;
      }
      
      public List getRelationsAdded() {
         return relationsAdded;
      }
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy