/******************************************************************************* * Copyright 2017 Capital One Services, LLC and Bitwise, Inc. * Licensed 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 hydrograph.ui.propertywindow.widgets.customwidgets.schema; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import javax.xml.XMLConstants; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.PropertyException; import javax.xml.bind.Unmarshaller; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import org.apache.commons.lang.StringUtils; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.MessageBox; import org.slf4j.Logger; import org.w3c.dom.Document; import org.xml.sax.SAXException; import hydrograph.ui.common.schema.Field; import hydrograph.ui.common.schema.FieldDataTypes; import hydrograph.ui.common.schema.Fields; import hydrograph.ui.common.schema.ScaleTypes; import hydrograph.ui.common.schema.Schema; import hydrograph.ui.common.util.Constants; import hydrograph.ui.datastructure.property.BasicSchemaGridRow; import hydrograph.ui.datastructure.property.FixedWidthGridRow; import hydrograph.ui.datastructure.property.GenerateRecordSchemaGridRow; import hydrograph.ui.datastructure.property.GridRow; import hydrograph.ui.datastructure.property.MixedSchemeGridRow; import hydrograph.ui.datastructure.property.XPathGridRow; import hydrograph.ui.logging.factory.LogFactory; import hydrograph.ui.propertywindow.messages.Messages; import hydrograph.ui.propertywindow.widgets.listeners.ListenerHelper; import hydrograph.ui.propertywindow.widgets.listeners.ListenerHelper.HelperType; import hydrograph.ui.propertywindow.widgets.listeners.grid.ELTGridDetails; import hydrograph.ui.propertywindow.widgets.utility.GridWidgetCommonBuilder; /** * The Class GridRowLoader. * * @author Bitwise */ public class GridRowLoader { public final static String SCHEMA_CONFIG_XSD_PATH = Platform.getInstallLocation().getURL().getPath() + Messages.SCHEMA_CONFIG_XSD_PATH; private static Logger logger = LogFactory.INSTANCE.getLogger(GridRowLoader.class); private String gridRowType; private File schemaFile; private Fields fields; public GridRowLoader(String gridRowType, File schemaFile){ this.gridRowType = gridRowType; this.schemaFile = schemaFile; } public static void showMessageBox(String message,String header,int SWT_Type) { MessageBox box=new MessageBox(Display.getCurrent().getActiveShell(), SWT_Type); box.setMessage(message); box.setText(header); box.open(); } /** * The method import schema rows from schema file into schema grid. * */ public List<GridRow> importGridRowsFromXML(ListenerHelper helper){ List<GridRow> schemaGridRowListToImport = null; ELTGridDetails gridDetails = (ELTGridDetails)helper.get(HelperType.SCHEMA_GRID); List<GridRow> grids = gridDetails.getGrids(); grids.clear(); try(InputStream xml = new FileInputStream(schemaFile); InputStream xsd = new FileInputStream(SCHEMA_CONFIG_XSD_PATH);) { if(StringUtils.isNotBlank(schemaFile.getPath())){ if(!schemaFile.getName().contains(".")) { logger.error(Messages.IMPORT_XML_IMPROPER_EXTENSION); throw new Exception(Messages.IMPORT_XML_IMPROPER_EXTENSION); } if(!(schemaFile.getPath().endsWith(".schema")) && !(schemaFile.getPath().endsWith(".xml"))){ logger.error(Messages.IMPORT_XML_INCORRECT_FILE); throw new Exception(Messages.IMPORT_XML_INCORRECT_FILE); } if(validateXML(xml, xsd)){ DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); builderFactory.setExpandEntityReferences(false); builderFactory.setNamespaceAware(true); builderFactory.setFeature(Constants.DISALLOW_DOCTYPE_DECLARATION,true); DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder(); Document document=documentBuilder.parse(schemaFile); JAXBContext jaxbContext = JAXBContext.newInstance(Schema.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); Schema schema= (Schema) jaxbUnmarshaller.unmarshal(document); fields = schema.getFields(); List<Field> fieldsList = fields.getField(); GridRow gridRow = null; schemaGridRowListToImport = new ArrayList<GridRow>(); if(Messages.GENERIC_GRID_ROW.equals(gridRowType)){ for (Field field : fieldsList) { addRowToList(gridDetails, grids, getBasicSchemaGridRow(field), schemaGridRowListToImport); } }else if(Messages.FIXEDWIDTH_GRID_ROW.equals(gridRowType)){ for (Field field : fieldsList) { addRowToList(gridDetails, grids, getFixedWidthGridRow(field), schemaGridRowListToImport); } }else if(Messages.GENERATE_RECORD_GRID_ROW.equals(gridRowType)){ for (Field field : fieldsList) { addRowToList(gridDetails, grids, getGenerateRecordGridRow(field), schemaGridRowListToImport); } }else if(Messages.XPATH_GRID_ROW.equals(gridRowType)){ for (Field field : fieldsList) { XPathGridRow xPathGridRow = new XPathGridRow(); populateCommonFields(xPathGridRow, field); xPathGridRow.setXPath(field.getAbsoluteOrRelativeXpath()); addRowToList(gridDetails, grids, xPathGridRow, schemaGridRowListToImport); } }else if(Messages.MIXEDSCHEME_GRID_ROW.equals(gridRowType)){ for (Field field : fieldsList) { addRowToList(gridDetails, grids, getMixedSchemeGridRow(field), schemaGridRowListToImport); } } } }else{ logger.error(Messages.EXPORT_XML_EMPTY_FILENAME); throw new Exception(Messages.EXPORT_XML_EMPTY_FILENAME); } } catch (JAXBException e1) { grids.clear(); showMessageBox(Messages.IMPORT_XML_FORMAT_ERROR + " -\n"+e1.getMessage(),"Error",SWT.ERROR); logger.error(Messages.IMPORT_XML_FORMAT_ERROR); return null; }catch (DuplicateFieldException e1) { grids.clear(); showMessageBox(e1.getMessage(),"Error", SWT.ERROR); logger.error(e1.getMessage()); return null; } catch (Exception e) { grids.clear(); showMessageBox(Messages.IMPORT_XML_ERROR+" -\n"+e.getMessage(),"Error",SWT.ERROR); logger.error(Messages.IMPORT_XML_ERROR); return null; } return schemaGridRowListToImport; } /** * For importing engine-XML, this method import schema rows from schema file into schema grid. * */ public List<GridRow> importGridRowsFromXML(){ List<GridRow> schemaGridRowListToImport = new ArrayList<GridRow>(); if(StringUtils.isNotBlank(schemaFile.getPath())){ try(InputStream xml = new FileInputStream(schemaFile); InputStream xsd = new FileInputStream(SCHEMA_CONFIG_XSD_PATH)) { if(validateXML(xml, xsd)){ DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); builderFactory.setExpandEntityReferences(false); builderFactory.setNamespaceAware(true); builderFactory.setFeature(Constants.DISALLOW_DOCTYPE_DECLARATION,true); DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder(); Document document=documentBuilder.parse(schemaFile); JAXBContext jaxbContext = JAXBContext.newInstance(Schema.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); Schema schema= (Schema) jaxbUnmarshaller.unmarshal(document); fields = schema.getFields(); List<Field> fieldsList = fields.getField(); GridRow gridRow = null; schemaGridRowListToImport = new ArrayList<GridRow>(); if(Messages.GENERIC_GRID_ROW.equals(gridRowType)){ for (Field field : fieldsList) { gridRow = getBasicSchemaGridRow(field); schemaGridRowListToImport.add(gridRow); } }else if(Messages.FIXEDWIDTH_GRID_ROW.equals(gridRowType)){ for (Field field : fieldsList) { schemaGridRowListToImport.add(getFixedWidthGridRow(field)); } }else if(Messages.GENERATE_RECORD_GRID_ROW.equals(gridRowType)){ for (Field field : fieldsList) { gridRow = getGenerateRecordGridRow(field); schemaGridRowListToImport.add(gridRow); } }else if(Messages.MIXEDSCHEME_GRID_ROW.equals(gridRowType)){ for (Field field : fieldsList) { gridRow = getMixedSchemeGridRow(field); schemaGridRowListToImport.add(gridRow); } } else if(Messages.XPATH_GRID_ROW.equals(gridRowType)){ for (Field field : fieldsList) { gridRow = new XPathGridRow(); populateCommonFields(gridRow, field); ((XPathGridRow)gridRow).setXPath(field.getAbsoluteOrRelativeXpath()); schemaGridRowListToImport.add(gridRow); } } } } catch (JAXBException e1) { logger.warn(Messages.IMPORT_XML_FORMAT_ERROR); return schemaGridRowListToImport; } catch (IOException ioException) { logger.warn(Messages.IMPORT_XML_ERROR); return schemaGridRowListToImport; } catch (ParserConfigurationException | SAXException exception) { logger.warn("Doctype is not allowed in schema files",exception); return schemaGridRowListToImport; } }else{ logger.warn(Messages.EXPORT_XML_EMPTY_FILENAME); } return schemaGridRowListToImport; } /** * The method exports schema rows from schema grid into schema file. * */ public void exportXMLfromGridRows(List<GridRow> schemaGridRowList){ Schema schema = new Schema(); fields= new Fields(); try { if(StringUtils.isNotBlank(schemaFile.getPath())){ if(!schemaFile.getName().contains(".")) { logger.error(Messages.EXPORT_XML_IMPROPER_EXTENSION); throw new Exception(Messages.EXPORT_XML_IMPROPER_EXTENSION); } if(!(schemaFile.getPath().endsWith(".schema")) && !(schemaFile.getPath().endsWith(".xml"))){ logger.error(Messages.EXPORT_XML_INCORRECT_FILE); throw new Exception(Messages.EXPORT_XML_INCORRECT_FILE); } exportFile(schemaGridRowList, schema); showMessageBox(Messages.EXPORTED_SCHEMA,"Information",SWT.ICON_INFORMATION); }else{ logger.error(Messages.EXPORT_XML_EMPTY_FILENAME); throw new Exception(Messages.EXPORT_XML_EMPTY_FILENAME); } } catch (JAXBException e) { showMessageBox(Messages.EXPORT_XML_ERROR+" -\n" + ((e.getCause() != null)? e.getLinkedException().getMessage():e.getMessage()),"Error",SWT.ERROR); logger.error(Messages.EXPORT_XML_ERROR); }catch (Exception e) { showMessageBox(Messages.EXPORT_XML_ERROR+" -\n"+e.getMessage(),"Error",SWT.ERROR); logger.error(Messages.EXPORT_XML_ERROR); } } /** * The method exports schema rows from schema grid into schema file. * */ public void exportXMLfromGridRowsWithoutMessage(List<GridRow> schemaGridRowList){ Schema schema = new Schema(); fields= new Fields(); try { if(StringUtils.isNotBlank(schemaFile.getPath())){ exportFile(schemaGridRowList, schema); }else{ logger.error(Messages.EXPORT_XML_EMPTY_FILENAME); throw new Exception(Messages.EXPORT_XML_EMPTY_FILENAME); } } catch (JAXBException e) { showMessageBox(Messages.EXPORT_XML_ERROR+" -\n" + ((e.getCause() != null)? e.getLinkedException().getMessage():e.getMessage()),"Error",SWT.ERROR); logger.error(Messages.EXPORT_XML_ERROR); }catch (Exception e) { showMessageBox(Messages.EXPORT_XML_ERROR+" -\n" +e.getMessage(),"Error",SWT.ERROR); logger.error(Messages.EXPORT_XML_ERROR); } } private void exportFile(List<GridRow> schemaGridRowList, Schema schema) throws JAXBException, PropertyException { JAXBContext jaxbContext; jaxbContext = JAXBContext.newInstance(Schema.class); Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); for (GridRow gridRow : schemaGridRowList) { Field field = new Field(); field.setName(gridRow.getFieldName()); field.setType(FieldDataTypes.fromValue(gridRow.getDataTypeValue())); if(gridRow instanceof XPathGridRow){ if(StringUtils.isNotBlank(((XPathGridRow)gridRow).getXPath())){ field.setAbsoluteOrRelativeXpath((((XPathGridRow)gridRow).getXPath())); } } if(StringUtils.isNotBlank(gridRow.getDateFormat())){ field.setFormat(gridRow.getDateFormat()); } if(StringUtils.isNotBlank(gridRow.getPrecision())){ field.setPrecision(Integer.parseInt(gridRow.getPrecision())); } if(StringUtils.isNotBlank(gridRow.getScale())){ field.setScale(Integer.parseInt(gridRow.getScale())); } if(gridRow.getScaleTypeValue()!=null){ if(!gridRow.getScaleTypeValue().equals("") && !gridRow.getScaleTypeValue().equals(Messages.SCALE_TYPE_NONE)){ field.setScaleType(ScaleTypes.fromValue(gridRow.getScaleTypeValue())); } } if(StringUtils.isNotBlank(gridRow.getDescription())){ field.setDescription(gridRow.getDescription()); } if(gridRow instanceof FixedWidthGridRow){ if(StringUtils.isNotBlank(((FixedWidthGridRow)gridRow).getLength())){ field.setLength(new BigInteger(((FixedWidthGridRow)gridRow).getLength())); } } if(gridRow instanceof MixedSchemeGridRow){ if(StringUtils.isNotBlank(((MixedSchemeGridRow)gridRow).getLength())){ field.setLength(new BigInteger(((MixedSchemeGridRow)gridRow).getLength())); } if(StringUtils.isNotBlank(((MixedSchemeGridRow)gridRow).getDelimiter())){ field.setDelimiter((((MixedSchemeGridRow)gridRow).getDelimiter())); } } if(gridRow instanceof GenerateRecordSchemaGridRow){ if(StringUtils.isNotBlank(((GenerateRecordSchemaGridRow)gridRow).getLength())){ field.setLength(new BigInteger(((GenerateRecordSchemaGridRow)gridRow).getLength())); } if(StringUtils.isNotBlank(((GenerateRecordSchemaGridRow) gridRow).getRangeFrom())){ field.setRangeFrom((((GenerateRecordSchemaGridRow) gridRow).getRangeFrom())); } if(StringUtils.isNotBlank(((GenerateRecordSchemaGridRow) gridRow).getRangeTo())){ field.setRangeTo(((GenerateRecordSchemaGridRow) gridRow).getRangeTo()); } if(StringUtils.isNotBlank(((GenerateRecordSchemaGridRow) gridRow).getDefaultValue())){ field.setDefault(((GenerateRecordSchemaGridRow) gridRow).getDefaultValue()); } } fields.getField().add(field); } schema.setFields(fields); jaxbMarshaller.marshal(schema, schemaFile); } private GridRow getBasicSchemaGridRow(Field field) { GridRow gridRow = new BasicSchemaGridRow(); populateCommonFields(gridRow, field); return gridRow; } private class DuplicateFieldException extends Exception{ private static final long serialVersionUID = -6430674437086982389L; public DuplicateFieldException(String message) { super(message); } } private GridRow getGenerateRecordGridRow(Field field) { GridRow gridRow = new GenerateRecordSchemaGridRow(); populateCommonFields(gridRow, field); if(field.getLength()!=null){ ((GenerateRecordSchemaGridRow) gridRow).setLength(String.valueOf(field.getLength())); }else{ ((GenerateRecordSchemaGridRow) gridRow).setLength(""); } if(field.getDefault()!=null){ ((GenerateRecordSchemaGridRow) gridRow).setDefaultValue((String.valueOf(field.getDefault()))); }else{ ((GenerateRecordSchemaGridRow) gridRow).setDefaultValue((String.valueOf(""))); } if(field.getRangeFrom()!=null){ ((GenerateRecordSchemaGridRow) gridRow).setRangeFrom(String.valueOf(field.getRangeFrom())); }else{ ((GenerateRecordSchemaGridRow) gridRow).setRangeFrom(""); } if(field.getRangeFrom()!=null){ ((GenerateRecordSchemaGridRow) gridRow).setRangeTo(String.valueOf(field.getRangeTo())); }else{ ((GenerateRecordSchemaGridRow) gridRow).setRangeTo(""); } return gridRow; } private GridRow getFixedWidthGridRow(Field field) { GridRow gridRow = new FixedWidthGridRow(); populateCommonFields(gridRow, field); if(field.getLength()!=null){ ((FixedWidthGridRow) gridRow).setLength(String.valueOf(field.getLength())); }else{ ((FixedWidthGridRow) gridRow).setLength(""); } return gridRow; } private GridRow getMixedSchemeGridRow(Field field) { GridRow gridRow = new MixedSchemeGridRow(); populateCommonFields(gridRow, field); if(field.getLength()!=null){ ((MixedSchemeGridRow) gridRow).setLength(String.valueOf(field.getLength())); }else{ ((MixedSchemeGridRow) gridRow).setLength(""); } if(field.getDelimiter()!=null){ ((MixedSchemeGridRow)gridRow).setDelimiter(field.getDelimiter()); }else{ ((MixedSchemeGridRow) gridRow).setDelimiter(""); } return gridRow; } private boolean validateXML(InputStream xml, InputStream xsd){ try { SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); javax.xml.validation.Schema schema = factory.newSchema(new StreamSource(xsd)); Validator validator = schema.newValidator(); validator.validate(new StreamSource(xml)); return true; } catch( SAXException| IOException ex) { MessageDialog.openError(Display.getCurrent().getActiveShell(), "Error", Messages.IMPORT_XML_FORMAT_ERROR + "-\n" + ex.getMessage()); logger.error(Messages.IMPORT_XML_FORMAT_ERROR); return false; } } private void addRowToList(ELTGridDetails gridDetails, List<GridRow> grids, GridRow gridRow, List<GridRow> schemaGridRowListToImport) throws Exception { if(!grids.contains(gridRow)){ grids.add(gridRow); gridDetails.setGrids(grids); schemaGridRowListToImport.add(gridRow); } else{ logger.error(Messages.IMPORT_XML_DUPLICATE_FIELD_ERROR); throw new DuplicateFieldException(Messages.IMPORT_XML_DUPLICATE_FIELD_ERROR); } } private void populateCommonFields(GridRow gridRow, Field field) { gridRow.setFieldName(field.getName()); gridRow.setDataType(GridWidgetCommonBuilder.getDataTypeByValue(field.getType().value())); gridRow.setDataTypeValue(GridWidgetCommonBuilder.getDataTypeValue()[GridWidgetCommonBuilder.getDataTypeByValue(field.getType().value())]); if(field.getFormat()!=null){ gridRow.setDateFormat(field.getFormat()); }else{ gridRow.setDateFormat(""); } if(FieldDataTypes.JAVA_MATH_BIG_DECIMAL.equals(field.getType())){ populateBigDecimal(gridRow, field); }else{ gridRow.setPrecision(""); gridRow.setScale(""); gridRow.setScaleType(GridWidgetCommonBuilder.getScaleTypeByValue(Messages.SCALE_TYPE_NONE)); gridRow.setScaleTypeValue(GridWidgetCommonBuilder.getScaleTypeValue()[Integer.valueOf(Constants.DEFAULT_INDEX_VALUE_FOR_COMBOBOX)]); } if(field.getDescription()!=null) gridRow.setDescription(field.getDescription()); else gridRow.setDescription(""); } private void populateBigDecimal(GridRow gridRow, Field field) { if(field.getPrecision()!=null) gridRow.setPrecision(String.valueOf(field.getPrecision())); else gridRow.setPrecision(""); if(field.getScale()!=null) gridRow.setScale(String.valueOf(field.getScale())); else gridRow.setScale(""); if(field.getScaleType()!=null){ gridRow.setScaleType(GridWidgetCommonBuilder.getScaleTypeByValue(field.getScaleType().value())); gridRow.setScaleTypeValue(GridWidgetCommonBuilder.getScaleTypeValue()[GridWidgetCommonBuilder.getScaleTypeByValue(field.getScaleType().value())]); }else{ gridRow.setScaleType(GridWidgetCommonBuilder.getScaleTypeByValue(Messages.SCALE_TYPE_NONE)); gridRow.setScaleTypeValue(GridWidgetCommonBuilder.getScaleTypeValue()[Integer.valueOf(Constants.DEFAULT_INDEX_VALUE_FOR_COMBOBOX)]); } } }