/*! ******************************************************************************
*
* 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 java.util.List;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.exception.KettleValueException;
public class XMLInputSaxFieldPosition {
public static final int XML_ELEMENT_POS = 1;
public static final int XML_ELEMENT_ATT = 2;
public static final int XML_ATTRIBUTE = 3;
public static final String NR_MARKER = "/";
public static final String ATT_MARKER = ":";
private String name;
/** XML attribute that define element */
private String attribute;
/** XML attribute value that define the field position */
private String value;
private int type;
private int elementNr;
/**
* Create a new XML Input Field position.
*
* @param name
* the name of the element or attribute
* @param type
* Element or Attribute (XML_ELEMENT, XML_ATTRIBUTE)
*/
public XMLInputSaxFieldPosition( String name, int type ) throws KettleValueException {
if ( type != XML_ELEMENT_ATT ) {
this.name = name;
this.type = type;
this.elementNr = 1;
} else {
throw new KettleValueException( "This constructor is for position defined attributes or elements" );
}
}
/**
* Create a new XML Input Field position.
*
* @param name
* the name of the element or attribute
* @param type
* Element or Attribute (XML_ELEMENT, XML_ATTRIBUTE)
* @param elementNr
* the element number to pick.
*/
public XMLInputSaxFieldPosition( String name, int type, int elementNr ) throws KettleValueException {
if ( type != XML_ELEMENT_ATT ) {
this.name = name;
this.type = type;
this.elementNr = elementNr;
} else {
throw new KettleValueException( "This constructor is for position defined attributes or elements" );
}
}
public XMLInputSaxFieldPosition( String name, String attribute, String value ) {
this.name = name;
this.type = XML_ELEMENT_ATT;
this.attribute = attribute;
this.value = value;
}
public String toString() {
String enc = "";
if ( type == XML_ATTRIBUTE ) {
enc += "A=";
enc += name;
enc += NR_MARKER + ( elementNr <= 0 ? 1 : elementNr );
} else {
if ( type == XML_ELEMENT_ATT ) {
enc += "Ea=";
enc += name;
enc += NR_MARKER + attribute + ATT_MARKER + value;
} else {
enc += "Ep=";
enc += name;
enc += NR_MARKER + ( elementNr <= 0 ? 1 : elementNr );
}
}
return enc;
}
/**
* Construnct a new XMLFieldPosition based on an a code: E=Elementame, A=Attributename
*
* @param encoded
*/
public XMLInputSaxFieldPosition( String encoded ) throws KettleValueException {
int equalIndex = encoded.indexOf( '=' );
if ( equalIndex < 0 ) {
throw new KettleValueException( "Sorry, this is not a valid XML Field Position (no equal sign in code: '"
+ encoded + "')" );
}
String positionType = Const.trim( encoded.substring( 0, equalIndex ) );
String nameAndNumber = Const.trim( encoded.substring( equalIndex + 1 ) );
String positionName = nameAndNumber;
// Is there an element number?
int semiIndex = nameAndNumber.indexOf( NR_MARKER );
// Is there an element defining attribute
int semiIndex2 = nameAndNumber.indexOf( ATT_MARKER );
if ( positionType.equalsIgnoreCase( "Ea" ) ) { // Element
this.type = XML_ELEMENT_ATT;
// this.name = positionName;
} else if ( positionType.equalsIgnoreCase( "Ep" ) ) {
this.type = XML_ELEMENT_POS;
this.name = positionName;
} else if ( positionType.equalsIgnoreCase( "A" ) ) { // Attribute
this.type = XML_ATTRIBUTE;
this.name = positionName;
} else {
throw new KettleValueException(
"Sorry, the position type can either be Ep (element defined by position) or "
+ "Ea (element defined by an attribute value) or A (attribute), you specified "
+ positionType );
}
if ( this.type == XML_ELEMENT_ATT ) {
if ( semiIndex2 >= 0 ) {
this.attribute = nameAndNumber.substring( semiIndex + 1, semiIndex2 );
this.value = nameAndNumber.substring( semiIndex2 + 1 );
this.name = nameAndNumber.substring( 0, semiIndex );
} else {
throw new KettleValueException( "Sorry, when the position type is Ea, defining attibute "
+ "and its value must be specified : Ea=element/attribute:value" + "(" + semiIndex2 + ")" );
}
} else {
if ( semiIndex >= 0 ) {
this.elementNr = Const.toInt( nameAndNumber.substring( semiIndex + 1 ), 1 ); // Unreadable: default to 1
this.name = nameAndNumber.substring( 0, semiIndex );
} else {
this.elementNr = 1;
}
}
// Get the element nr
}
/**
* @return Returns the name.
*/
public String getName() {
return name;
}
/**
* @param name
* The name to set.
*/
public void setName( String name ) {
this.name = name;
}
/**
* @return Returns the type.
*/
public int getType() {
return type;
}
/**
* @param type
* The type to set.
*/
public void setType( int type ) {
this.type = type;
}
public String getAttribute() {
return attribute;
}
public String getAttributeValue() {
return value;
}
public Object clone() {
try {
Object retval = super.clone();
return retval;
} catch ( CloneNotSupportedException e ) {
return null;
}
}
/**
* @return Returns the elementNr.
*/
public int getElementNr() {
return elementNr;
}
/**
* @param elementNr
* The elementNr to set.
*/
public void setElementNr( int elementNr ) {
this.elementNr = elementNr;
}
/**
* Encode the path to an XML element or attribute
*
* @param path
* An ArrayList of XMLInputFieldPosition
* @return the path encoded
*/
public static final String encodePath( List<XMLInputSaxFieldPosition> path ) {
String encoded = "";
for ( int p = 0; p < path.size(); p++ ) {
XMLInputSaxFieldPosition pos = path.get( p );
String elementName = pos.toString();
if ( p > 0 ) {
encoded += XMLInputSaxField.POSITION_MARKER;
}
encoded += elementName;
}
return encoded;
}
}