www.pudn.com > sxg.rar > GwElement.java


/*
 * Copyright (c) 2003 Jens Mueller
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/**
	Instances of this class represent SNMP-Objects

 	@author jens Mueller
 */

import java.util.Vector;
import java.util.Iterator;
import java.util.StringTokenizer;

import org.apache.xml.utils.StringToIntTable;

public class GwElement
{
	private String _name;
	private GwOID _oid;
	private boolean _isElement;
	//public Vector _enum;
	private SnmpGetRequestResult _res;
	private String _snmpSetData;
	private String _typePrefix;
	private String _typeName;
	private String _maxAccess;
	private String _status;
	private String _use;	
	private GwType _ancestor;
	
	
	
	public GwElement( String name, GwOID oid, boolean isElement )
	{
		_name = name;
		_oid = oid;
		_isElement = isElement;
		//_enum = new Vector();
	}
	
	
	public void setSnmpSetData( String data )
	{
		_snmpSetData = data;
	}
	
	
	public String getUse()
	{
		return _use;
	}
	
	
	public void setUse( String use )
	{
		_use = use;
	}
	
	
	public String getSnmpSetData()
	{
		return _snmpSetData;
	}
	
	
	public String getName()
	{
		return _name;
	}
	
	
	public GwOID getOid()
	{
		return _oid;
	}	
	
	
	public boolean isElement()
	{
		return _isElement;
	}
	
	
	public void setOid( GwOID oid )
	{
		_oid = oid;
	}
	
	
	public String getTypeName()
	{
		return _typeName;
	}


	public String getTypePrefix()
	{
		return _typePrefix;
	}


	public void setTypeName( String typeName )
	{
		_typeName = typeName;
	}


	public void setTypePrefix( String typePrefix )
	{
		_typePrefix = typePrefix;
	}
	
	
	public void setExecutionResult( SnmpGetRequestResult res )
	{
		_res = res;
	}
	

	public SnmpGetRequestResult getExecutionResult()
	{
		return _res;
	}
	
	
	public String getMaxAccess()
	{
		return _maxAccess;
	}


	public String getStatus()
	{
		return _status;
	}
	
	
	public void setMaxAccess( String maxAccess )
	{
		_maxAccess = maxAccess;
	}


	public void setStatus( String status )
	{
		_status = status;
	}
	
	
	public void setAncestor( GwType ancestor )
	{
		_ancestor = ancestor;
	}
	
	
	public boolean isOidType()
	{
		if ( _ancestor == null )
			return false;
		else
			return _ancestor.isOidType();
	}
	
	
	public String getCastType()
	{
		return _ancestor.getCastType();
	}
	
	
	/**
	  	encodes data retrieved via SNMP-get into corresponding XML-representation recursively. 
	 	@param type	the GwType processed in current step of recursion 	 	@param data	the data to be encoded 	 	@return the XML-representation of the data to be set as text of the corresponding
	 				XML-Element 	 */
	private String traverseEncode( GwType type, String data )
	{
		if ( type.isUnion() )
		{
			return data;
		}
		
		if ( type.isList() )
		{
								String debug="";					

			GwType ancestor = ( GwType )type._ancestors.elementAt( 0 );
			if ( ancestor.isEnumeration() )
			{
				String res = "";
				boolean first = true;			
				try
				{
					byte[] bytes = data.getBytes();
					//debug += data+": ";
					int enumCount = ancestor._enum.size();
					
				/*	//debug*****************************************************************
					int k = 0;
					while( k < bytes.length )
					{
						int currInt = new Byte( bytes[ k ] ).intValue();
						String currByteString = Integer.toBinaryString( new Byte( bytes[ k ] ).intValue() );
						if( currByteString.length() > 8 )
						 	currByteString = currByteString.substring( 0, 8 );
						 else
						 	if  ( currByteString.length() < 8 )
						 	{
						 		String leadingZeros = "";
						 		int it = currByteString.length();
						 		while( it <= 8 )
						 		{
						 			leadingZeros += "0";
						 			it++;
						 		}
						 		currByteString = leadingZeros + currByteString;
						 	}
						res += currByteString + " "; 
						k++;
					}
				*/	//debug*****************************************************************

					if( bytes.length * 8 < enumCount )
					{
						return("Error in processing of bitlist");
					}					
					else
					{
						int i = 0;
						int[] div = { 128, 64, 32, 16, 8, 4, 2, 1 };
						while( i < bytes.length )
						{
							char[] chars = { '0', '0', '0', '0', '0', '0', '0', '0' };
							int divIter = 0;
							int unsignedByteValue = 0;
							if( bytes[ i ] < 0 )
							{
								unsignedByteValue = 127 + ( 129 - Math.abs( bytes[ i ] ) );
								debug += "127 + ( 129 - "+Math.abs( bytes[ i ] )+" ) = " + unsignedByteValue + ": ";
							}
							else
							{
								unsignedByteValue = bytes[ i ];
								debug += unsignedByteValue + ": ";
							}
							
							while( divIter < div.length )
							{
								if( unsignedByteValue - div[ divIter ] >= 0 )
								{
									unsignedByteValue = unsignedByteValue - div[ divIter ];
									chars[ divIter ] = '1';
								}
								divIter++;
							}
							//Byte currByte = bytes[ i ];
							String currByteString = new String( chars );
							debug += currByteString + " ";
							int j = 0;
							while( j < currByteString.length() )
							{
								if( currByteString.charAt( j ) == '1' )
								{
									for ( Iterator iterator = ancestor._enum.iterator(); iterator.hasNext(); )
									{
										EnumElement enumElement = ( EnumElement ) iterator.next();
										if ( enumElement.getIntVal() != null )
										{
											if( i*8 + j ==  Integer.parseInt( enumElement.getIntVal() ) )
											{
												if( first )
												{
													res += enumElement.getValue();
													first = false;
												}
												else
												{
													res += " " + enumElement.getValue();
												}
											}
										}
										else
											res += Integer.toString( i*8 + j );
									}
								}						
								j++;
							}
							i++;
						}
					}
				}
				catch( NumberFormatException e )
				{
					return data;
				}
				return res;//;debug + " " + res;
			}
			else
				return data;
		}
				


		if ( type.isEnumeration() )
		{
			for ( Iterator iterator = type._enum.iterator(); iterator.hasNext(); )
			{
				EnumElement enumElement = ( EnumElement ) iterator.next();
				if ( enumElement.getIntVal() != null )
					if ( data.equals( enumElement.getIntVal() ) )
						return enumElement.getValue();
			}
			return data;
		}
		
		if ( type.getDisplayHint() != null )
		{
			String displayHint = type.getDisplayHint();
			StringTokenizer strtok = new StringTokenizer( displayHint, "-" );
			// guessing something like "d-2"
			if ( strtok.countTokens() == 2 )
			{
				String first = strtok.nextToken();
				String encodedString = data;
				// d handled by default
				if ( first.equals( "b" ) )
				{
					encodedString = Integer.toBinaryString( Integer.parseInt( data ) );
				}
				if ( first.equals( "o" ) )
				{
					encodedString = Integer.toOctalString( Integer.parseInt( data ) );
				}
				if ( first.equals( "x" ) )
				{
					encodedString = Integer.toHexString( Integer.parseInt( data ) );
				}
				
				int postComma = Integer.parseInt( strtok.nextToken() );
				String result = encodedString.substring( 0, encodedString.length() - postComma );
				result += "." + encodedString.substring( encodedString.length() - postComma );
				return result;
			}
			//checking for something like "1x:"
			if ( displayHint.length() == 3 )
			{
				byte[] bytes = data.getBytes();
				String res = "";
				String firstChar = displayHint.substring( 0, 1 );
				int groupCount = Integer.parseInt( firstChar );
				String secChar = displayHint.substring( 1, 2 );
				String thirdChar = displayHint.substring( 2, 3 );
				int bytesCount = bytes.length;
				int i = 0;
				String delim;
				while( i < bytesCount )
				{
					if( i < bytesCount - 1 )
						delim = thirdChar;
					else
						delim = "";
						
					if( secChar.equals( "d" ) )
					{
						String singleByte = Integer.toString( 
																	Integer.parseInt( Byte.toString( bytes[ i ] ) ) );
						if( singleByte.length() > 3 )
							singleByte = singleByte.substring( singleByte.length() - 3 );
						if( singleByte.length() == 2 )
							singleByte = "0"+singleByte;
						if( singleByte.length() == 1 )
							singleByte = "00"+singleByte;
						res +=  singleByte;						
					}
					if( secChar.equals( "b" ) )
					{
						String singleByte =  Integer.toBinaryString( 
																	Integer.parseInt( Byte.toString( bytes[ i ] ) ) );
						if( singleByte.length() > 8 )
							singleByte = singleByte.substring( singleByte.length() - 8 );
						String leadingZeros = "";
						for( int missingZeros = 8 - singleByte.length(); i > 0; i-- )
							leadingZeros += "0";
						singleByte = leadingZeros + singleByte; 
						res +=  singleByte;													
					}
					if( secChar.equals( "o" ) )
					{
						String singleByte = Integer.toOctalString( 
																	Integer.parseInt( Byte.toString( bytes[ i ] ) ) );
						if( singleByte.length() > 3 )
							singleByte = singleByte.substring( singleByte.length() - 3 );
						if( singleByte.length() == 2 )
							singleByte = "0"+singleByte;
						if( singleByte.length() == 1 )
							singleByte = "00"+singleByte;
						res +=  singleByte;						
					}
					if( secChar.equals( "x" ) )
					{
						String singleByte = Integer.toHexString( 
																	Integer.parseInt( Byte.toString( bytes[ i ] ) ) );
						if( singleByte.length() > 2 )
							singleByte = singleByte.substring( singleByte.length() - 2 );
						if( singleByte.length() < 2 )
						singleByte = "0"+singleByte;
						res +=  singleByte;
					}
					i++;
					if( i % groupCount == 0 )
						res += delim;
				}	
				return res;			
			}
			//SNMPv2-TC::DateAndTime
			if( displayHint.equals( "2d-1d-1d,1d:1d:1d.1d,1a1d:1d") )
			{
				byte[] bytes = data.getBytes();
				String res = "";
				String year1 = Integer.toHexString( Integer.parseInt( Byte.toString( bytes[ 0 ] ) ) );
				if( year1.length() > 2 )
					year1 = year1.substring( year1.length() - 2 );
				String year2 = Integer.toHexString( Integer.parseInt( Byte.toString( bytes[ 1 ] ) ) );
				if( year2.length() > 2 )
					year2 = year2.substring( year2.length() - 2 );
				
				String year = year1 + year2;
				res += Integer.toString( Integer.parseInt( year, 16 ) );
				//res +=  Integer.toString( Integer.parseInt( Byte.toString( bytes[ 0 ] ) ) );
				//res +=  Integer.toString( Integer.parseInt( Byte.toString( bytes[ 1 ] ) ) );
				res += "-";
				res +=  Integer.toString( Integer.parseInt( Byte.toString( bytes[ 2 ] ) ) );
				res += "-";
				res +=  Integer.toString( Integer.parseInt( Byte.toString( bytes[ 3 ] ) ) );
				res += ",";
				res +=  Integer.toString( Integer.parseInt( Byte.toString( bytes[ 4 ] ) ) );
				res += ":";
				res +=  Integer.toString( Integer.parseInt( Byte.toString( bytes[ 5 ] ) ) );
				res += ":";
				res +=  Integer.toString( Integer.parseInt( Byte.toString( bytes[ 6 ] ) ) );
				res += ".";
				res +=  Integer.toString( Integer.parseInt( Byte.toString( bytes[ 7 ] ) ) );
				//check if time zone information is provided
				if( bytes.length == 11 )
				{
					res += ",";
					if ( Byte.toString( bytes[ 8 ] ).equals( "43" ) )
						res += "+";
					else
						res += "-";
					res +=  Integer.toString( Integer.parseInt( Byte.toString( bytes[ 9 ] ) ) );
					res += ":";
					res +=  Integer.toString( Integer.parseInt( Byte.toString( bytes[ 10 ] ) ) );
				}
				return res;
			}
			return data;
		}
		if ( type.getXsdBaseType() != null )
			return data;
		else		
		{
			GwType ancestor = ( GwType )type._ancestors.elementAt( 0 );
			if ( ancestor != null )
				return traverseEncode( ancestor, data );
			else
				return data;
		}
	}

	
	/** 	 	@return the result of a SNMP-set in XML-representation 	 */
	public String getEncodedExecutionResult()
	{
		String res = traverseEncode( _ancestor, _res.getData() );
		return res;
	}

	
	/**
	 	@return the raw SNMP-datastring to be send for set-requests 	 	@throws IllegalArgumentException 	 */
	public String getDecodedExecutionString() throws IllegalArgumentException
	{				
		return traverseDecode( _ancestor, _snmpSetData );
	}
	
	
	
	/**
	  	decodes XML-represented data submitted by clients for set-requests into
	  	a corresponding SNMP-datastring recursively

	 	@param type	the GwType processed in current step of recursion
	 	@param data	the data to be decoded
	 	@return the SNMP-datastring of the data to be set via SNMP-set
	 	@throws IllegalArgumentException 	 */
	private String traverseDecode( GwType type, String data ) throws IllegalArgumentException
	{
		if ( type.isUnion() )
		{
			return data;
		}
		
		if ( type.isList() )
		{
			GwType ancestor = ( GwType )type._ancestors.elementAt( 0 );
			if ( ancestor.isEnumeration() )
			{
				StringTokenizer strtok = new StringTokenizer( data, " " );
				int  size = ancestor._enum.size() / 8;
				if( ancestor._enum.size() % 8 != 0 )
					size++;
				char[] chars = new char[ size * 8 ];
				int position = 0;
				while( position < chars.length )
				{
					chars[ position ] = '0';
					position++;
				}
				
				while( strtok.hasMoreTokens() )
				{
					String currValue = strtok.nextToken();
					for ( Iterator iterator = ancestor._enum.iterator(); iterator.hasNext(); )
					{
						EnumElement enumElement = ( EnumElement )iterator.next();
						if( enumElement.getValue().equals( currValue ) && 
							enumElement.getIntVal() != null )
						{
							chars[ Integer.parseInt( enumElement.getIntVal() ) ] = '1';
							break;
						}
					}
				}
				
				position = 0;
				int offset = 0;
				String binary;
				String hexres = "";
	//			hexres = "anc._enum.size: "+ ancestor._enum.size() + " char.length: "+chars.length + ": " + String.copyValueOf( chars ) + " ";
				while( position < chars.length )
				{
					if( position  % 8 == 0 )
					{
	//					try
	//					{
							binary = String.copyValueOf( chars, offset * 8, 8 );
							String hexval = Integer.toHexString( Integer.parseInt( binary, 2 ) );
							if( hexval.length() == 1 )
								hexval = "0"+hexval;
							hexres += hexval;
	//					}
	//					catch( StringIndexOutOfBoundsException e ) 
	//					{
	//						hexres += " Exc: pos: " + position + " offs: " + offset; 
	//					}
						offset++;
					}
					position++;
				}
				return hexres;
			}
		}
		
		if ( type.isEnumeration() )
		{
			for ( Iterator iterator = type._enum.iterator(); iterator.hasNext(); )
			{
				EnumElement enumElement = ( EnumElement ) iterator.next();
				if ( enumElement.getIntVal() != null )
					if ( data.equals( enumElement.getValue() ) )
						return enumElement.getIntVal();
			}
			return data;
		}
		
		
		if ( type.getDisplayHint() != null )
		{
			String displayHint = type.getDisplayHint();
			StringTokenizer strtok = new StringTokenizer( displayHint, "-" );
			// guessing something like "d-2"
			if ( strtok.countTokens() == 2 )
			{
				StringTokenizer strtok1 = new StringTokenizer( data, "." );
				if ( strtok.countTokens() != 2 )
				{
					return data;
				}
				else
				{
					String first = strtok.nextToken(); 
					String res = strtok1.nextToken() + strtok1.nextToken(); 
					// d handled by default
					if ( first.equals( "b" ) )
					{
						res = Integer.toString( Integer.parseInt( data, 2 ) );
					}
					if ( first.equals( "o" ) )
					{
						res = Integer.toString( Integer.parseInt( data, 8 ) );
					}
					if ( first.equals( "x" ) )
					{
						res = Integer.toString( Integer.parseInt( data, 16 ) );
					}
					return res;
				}
			}
			//checking for something like "1x:"
			if ( displayHint.length() == 3 )
			{
				String firstChar = displayHint.substring( 0, 1 );
				int groupCount = Integer.parseInt( firstChar );
				String secChar = displayHint.substring( 1, 2 );
				String thirdChar = displayHint.substring( 2, 3 );
				String res = "";
				StringTokenizer strtok1 = new StringTokenizer( data, thirdChar );
				byte[] bytes = new byte[ strtok1.countTokens() * groupCount ];
				int position = 0;
				int groupCountPosition = groupCount;
				while( strtok1.hasMoreTokens() )
				{
					groupCountPosition = groupCount;
					String curr = strtok1.nextToken();
					if ( secChar.equals( "d" ) )
					{
						while( groupCountPosition > 1 )
						{
							String currPart = curr.substring( 3 * ( groupCount - groupCountPosition ), 
																		( 3 * ( groupCount - groupCountPosition ) ) + 3 );
							bytes[ position ] =  Byte.parseByte( currPart, 10 );
							groupCountPosition--;
							position++;
						}
					}					
					if ( secChar.equals( "b" ) )
					{
						while( groupCountPosition > 1 )
						{
							String currPart = curr.substring( 8 * ( groupCount - groupCountPosition ), 
																		( 8 * ( groupCount - groupCountPosition ) ) + 8 );
							bytes[ position ] =  Byte.parseByte( currPart, 2 );
							groupCountPosition--;
							position++;
						}
					}
					if ( secChar.equals( "o" ) )
					{
						while( groupCountPosition > 1 )
						{
							String currPart = curr.substring( 3 * ( groupCount - groupCountPosition ), 
																		( 3 * ( groupCount - groupCountPosition ) ) + 3 );
							bytes[ position ] =  Byte.parseByte( currPart, 8 );
							groupCountPosition--;
							position++;
						}
					}
					if ( secChar.equals( "x" ) )
					{
						while( groupCountPosition > 1 )
						{
							String currPart = curr.substring( 2 * ( groupCount - groupCountPosition ), 
																		( 2 * ( groupCount - groupCountPosition ) ) + 2 );
							bytes[ position ] =  Byte.parseByte( currPart, 16 );
							groupCountPosition--;
							position++;
						}
					}
				}
				return new String( bytes );
			}
			//SNMPv2-TC::DateAndTime
			if( displayHint.equals( "2d-1d-1d,1d:1d:1d.1d,1a1d:1d") )
			{
				StringTokenizer strtok1 = new StringTokenizer( data, "," );
				byte[] bytes;
				if( strtok1.countTokens() == 2 || strtok1.countTokens() == 3 )
				{
					if( strtok1.countTokens() == 2 )
					{
						bytes = new byte[ 8 ];
					}
					else
					{
						bytes = new byte[ 11 ];
					}
					String date = strtok1.nextToken();
					StringTokenizer datetok = new StringTokenizer( date, "-" );
					if( datetok.countTokens() != 3 )
						throw new IllegalArgumentException( 	"SNMPv2-TC::DateAndTime " +
																				"( data does not match display-hint )" );
					else
					{
						String year = datetok.nextToken();
						if( year.length() != 4 )
							throw new IllegalArgumentException( 	"SNMPv2-TC::DateAndTime " +
																					"( data does not match display-hint )" );
						else
						{
							try
							{
								String century	= year.substring( 0, 2 );
								year				 	= year.substring( 2, 4 );
								bytes[ 0 ] = Byte.parseByte( Integer.toHexString( 
																							Integer.parseInt( century ) ), 16 );
								bytes[ 1 ] = Byte.parseByte( Integer.toHexString( 
																							Integer.parseInt( year ) ), 16 );
						
								String month = datetok.nextToken();
								bytes[ 2 ] = Byte.parseByte( Integer.toHexString( 
																							Integer.parseInt( month ) ), 16 );
	
								String day = datetok.nextToken();
								bytes[ 3 ] = Byte.parseByte( Integer.toHexString( 
																							Integer.parseInt( day ) ), 16 );
							}
							catch( NumberFormatException e )
							{
								throw new IllegalArgumentException( "SNMPv2-TC::DateAndTime ( data " +
																						"does not match display-hint )" );
							}
						}
					}
					
					String time = strtok1.nextToken();
					StringTokenizer timetok = new StringTokenizer( time, ":" );
					if( timetok.countTokens() != 3 )
						throw new IllegalArgumentException( 	"SNMPv2-TC::DateAndTime " +
																				"( data does not match display-hint )" );
					else
					{
						try
						{
							String hour = timetok.nextToken();
							bytes[ 4 ] = Byte.parseByte( Integer.toHexString( 
																						Integer.parseInt( hour, 16 ) ) );
							String minutes = timetok.nextToken();
							bytes[ 5 ] = Byte.parseByte( Integer.toHexString( 
																						Integer.parseInt( minutes, 16 ) ) );
							String secs = timetok.nextToken();
							StringTokenizer secstok = new StringTokenizer( secs, "." );
							if( secstok.countTokens() != 2 )
								throw new IllegalArgumentException( "SNMPv2-TC::DateAndTime " +
																					"( data does not match display-hint )" );
							else
							{
								String sec = secstok.nextToken();
								bytes[ 6 ] = Byte.parseByte( Integer.toHexString( 
																						Integer.parseInt( sec, 16 ) ) );
								String msec = secstok.nextToken();
								bytes[ 7 ] = Byte.parseByte( Integer.toHexString( 
																						Integer.parseInt( msec, 16 ) ) );
							}
						}
						catch( NumberFormatException e )
						{
							throw new IllegalArgumentException( 	"SNMPv2-TC::DateAndTime" +
																					"( data does not match display-hint )" );
						}
					}
					
					if( strtok1.countTokens() == 3 )
					{
						String timezone = strtok1.nextToken();
						if( timezone.charAt( 0 ) == '+' )
							bytes[ 8 ] = 43;
						else if( timezone.charAt( 0 ) == '-' )
							bytes[ 8 ] = 45;
						else
							throw new IllegalArgumentException( 	"SNMPv2-TC::DateAndTime " +
																					"( data does not match display-hint )" );
						
						timezone = timezone.substring( 1 );
						StringTokenizer timezonetok = new StringTokenizer( timezone, ":" );
						if( timezonetok.countTokens() != 2 )
							throw new IllegalArgumentException( 	"SNMPv2-TC::DateAndTime " +
																					"( data does not match display-hint )" );
						else
						{
							try
							{
								String timezonehour = timezonetok.nextToken(); 
								bytes[ 9 ] = Byte.parseByte( Integer.toHexString(
																					Integer.parseInt( timezonehour, 16 ) ) );
								String timezonemin = timezonetok.nextToken(); 
								bytes[ 10 ] = Byte.parseByte( Integer.toHexString( 
																					Integer.parseInt( timezonemin, 16 ) ) );
							}
							catch( NumberFormatException e )
							{
								throw new IllegalArgumentException( "SNMPv2-TC::DateAndTime " +
																					"( data does not match display-hint )" );
							}
						}
						return new String( bytes );					
					}
					else
						return new String( bytes );
				}
				else
					throw new IllegalArgumentException( 	"SNMPv2-TC::DateAndTime " +
																			"( data does not match display-hint )" );
			}
		}
			
		if ( type.getXsdBaseType() != null )
			return data;
		else		
		{
			GwType ancestor = ( GwType )type._ancestors.elementAt( 0 );
			if ( ancestor != null )
				return traverseDecode( ancestor, data );
			else
				return data;
		}
	}

		
	/**
	 	@return an textual representation of this SimpleType for debugging purposes
	 */
	public String dump()
	{
		String type;
		if (_isElement)
			type = "Element";
		else
			type = "Attribute";
		String rep = "  "+type+": " + _name+ " "+ _oid.toString() +
						 " of Type: "+_typeName+"
"; rep += _ancestor.dump(); return rep; } }