/*! ****************************************************************************** * * Pentaho Data Integration * * Copyright (C) 2002-2013 by Pentaho : http://www.pentaho.com * ******************************************************************************* * * 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 org.pentaho.di.trans.steps.xmlinputsax; import org.pentaho.di.core.Const; import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.core.exception.KettleValueException; import org.pentaho.di.core.row.ValueMeta; import org.pentaho.di.core.xml.XMLHandler; import org.w3c.dom.Node; /** * Describes an XML field and the position in an XML file * * @author Matt * @since 16-12-2005 * */ public class XMLInputSaxField implements Cloneable { public static final int TYPE_TRIM_NONE = 0; public static final int TYPE_TRIM_LEFT = 1; public static final int TYPE_TRIM_RIGHT = 2; public static final int TYPE_TRIM_BOTH = 3; public static final String[] trimTypeDesc = { "none", "left", "right", "both" }; public static final String POSITION_MARKER = ","; private String name; private XMLInputSaxFieldPosition[] fieldPosition; private int type; private int length; private String format; private int trimtype; private int precision; private String currencySymbol; private String decimalSymbol; private String groupSymbol; private boolean repeat; private String[] samples; public XMLInputSaxField( String fieldname, XMLInputSaxFieldPosition[] xmlInputFieldPositions ) { this.name = fieldname; this.fieldPosition = xmlInputFieldPositions; this.length = -1; this.type = ValueMeta.TYPE_STRING; this.format = ""; this.trimtype = TYPE_TRIM_NONE; this.groupSymbol = ""; this.decimalSymbol = ""; this.currencySymbol = ""; this.precision = -1; this.repeat = false; } public XMLInputSaxField() { this( null, null ); } public String getXML() { String retval = ""; retval += " <field>" + Const.CR; retval += " " + XMLHandler.addTagValue( "name", getName() ); retval += " " + XMLHandler.addTagValue( "type", getTypeDesc() ); retval += " " + XMLHandler.addTagValue( "format", getFormat() ); retval += " " + XMLHandler.addTagValue( "currency", getCurrencySymbol() ); retval += " " + XMLHandler.addTagValue( "decimal", getDecimalSymbol() ); retval += " " + XMLHandler.addTagValue( "group", getGroupSymbol() ); retval += " " + XMLHandler.addTagValue( "length", getLength() ); retval += " " + XMLHandler.addTagValue( "precision", getPrecision() ); retval += " " + XMLHandler.addTagValue( "trim_type", getTrimTypeDesc() ); retval += " " + XMLHandler.addTagValue( "repeat", isRepeated() ); retval += " <positions>"; for ( int i = 0; i < fieldPosition.length; i++ ) { retval += XMLHandler.addTagValue( "position", fieldPosition[i].toString(), false ); } retval += " </positions>" + Const.CR; retval += " </field>" + Const.CR; return retval; } public XMLInputSaxField( Node fnode ) throws KettleValueException { setName( XMLHandler.getTagValue( fnode, "name" ) ); setType( ValueMeta.getType( XMLHandler.getTagValue( fnode, "type" ) ) ); setFormat( XMLHandler.getTagValue( fnode, "format" ) ); setCurrencySymbol( XMLHandler.getTagValue( fnode, "currency" ) ); setDecimalSymbol( XMLHandler.getTagValue( fnode, "decimal" ) ); setGroupSymbol( XMLHandler.getTagValue( fnode, "group" ) ); setLength( Const.toInt( XMLHandler.getTagValue( fnode, "length" ), -1 ) ); setPrecision( Const.toInt( XMLHandler.getTagValue( fnode, "precision" ), -1 ) ); setTrimType( getTrimType( XMLHandler.getTagValue( fnode, "trim_type" ) ) ); setRepeated( !"N".equalsIgnoreCase( XMLHandler.getTagValue( fnode, "repeat" ) ) ); Node positions = XMLHandler.getSubNode( fnode, "positions" ); int nrPositions = XMLHandler.countNodes( positions, "position" ); fieldPosition = new XMLInputSaxFieldPosition[nrPositions]; for ( int i = 0; i < nrPositions; i++ ) { Node positionnode = XMLHandler.getSubNodeByNr( positions, "position", i ); String encoded = XMLHandler.getNodeValue( positionnode ); fieldPosition[i] = new XMLInputSaxFieldPosition( encoded ); } } public static final int getTrimType( String tt ) { if ( tt == null ) { return 0; } for ( int i = 0; i < trimTypeDesc.length; i++ ) { if ( trimTypeDesc[i].equalsIgnoreCase( tt ) ) { return i; } } return 0; } public static final String getTrimTypeDesc( int i ) { if ( i < 0 || i >= trimTypeDesc.length ) { return trimTypeDesc[0]; } return trimTypeDesc[i]; } public Object clone() { try { XMLInputSaxField retval = (XMLInputSaxField) super.clone(); if ( fieldPosition != null ) { XMLInputSaxFieldPosition[] positions = new XMLInputSaxFieldPosition[fieldPosition.length]; for ( int i = 0; i < fieldPosition.length; i++ ) { positions[i] = (XMLInputSaxFieldPosition) fieldPosition[i].clone(); } retval.setFieldPosition( positions ); } return retval; } catch ( CloneNotSupportedException e ) { return null; } } /** * @return Returns the xmlInputFieldPositions. */ public XMLInputSaxFieldPosition[] getFieldPosition() { return fieldPosition; } /** * @param xmlInputFieldPositions * The xmlInputFieldPositions to set. */ public void setFieldPosition( XMLInputSaxFieldPosition[] xmlInputFieldPositions ) { this.fieldPosition = xmlInputFieldPositions; } public int getLength() { return length; } public void setLength( int length ) { this.length = length; } public String getName() { return name; } public void setName( String fieldname ) { this.name = fieldname; } public int getType() { return type; } public String getTypeDesc() { return ValueMeta.getTypeDesc( type ); } public void setType( int type ) { this.type = type; } public String getFormat() { return format; } public void setFormat( String format ) { this.format = format; } public void setSamples( String[] samples ) { this.samples = samples; } public String[] getSamples() { return samples; } public int getTrimType() { return trimtype; } public String getTrimTypeDesc() { return getTrimTypeDesc( trimtype ); } public void setTrimType( int trimtype ) { this.trimtype = trimtype; } public String getGroupSymbol() { return groupSymbol; } public void setGroupSymbol( String group_symbol ) { this.groupSymbol = group_symbol; } public String getDecimalSymbol() { return decimalSymbol; } public void setDecimalSymbol( String decimal_symbol ) { this.decimalSymbol = decimal_symbol; } public String getCurrencySymbol() { return currencySymbol; } public void setCurrencySymbol( String currency_symbol ) { this.currencySymbol = currency_symbol; } public int getPrecision() { return precision; } public void setPrecision( int precision ) { this.precision = precision; } public boolean isRepeated() { return repeat; } public void setRepeated( boolean repeat ) { this.repeat = repeat; } public void flipRepeated() { repeat = !repeat; } public String getFieldPositionsCode() { String enc = ""; for ( int i = 0; i < fieldPosition.length; i++ ) { XMLInputSaxFieldPosition pos = fieldPosition[i]; if ( i > 0 ) { enc += POSITION_MARKER; } enc += pos.toString(); } return enc; } public String getFieldPositionsCode( int startPosition ) { String enc = ""; for ( int i = startPosition; i < fieldPosition.length; i++ ) { XMLInputSaxFieldPosition pos = fieldPosition[i]; if ( i > startPosition ) { enc += POSITION_MARKER; } enc += pos.toString(); } return enc; } public void guess() { } public void setFieldPosition( String encoded ) throws KettleException { try { String[] codes = encoded.split( POSITION_MARKER ); fieldPosition = new XMLInputSaxFieldPosition[codes.length]; for ( int i = 0; i < codes.length; i++ ) { fieldPosition[i] = new XMLInputSaxFieldPosition( codes[i] ); } } catch ( Exception e ) { throw new KettleException( "Unable to parse the field positions because of an error" + Const.CR + "Please use E=element or A=attribute in a comma separated list (code: " + encoded + ")", e ); } } public boolean equals( Object arg ) { if ( arg instanceof XMLInputSaxField ) { XMLInputSaxField f = (XMLInputSaxField) arg; if ( this.name.equals( f.getName() ) && this.getFieldPositionsCode().equals( f.getFieldPositionsCode() ) ) { return true; } else { return false; } } else { return false; } } }