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