/*******************************************************************************
 *  Copyright 2017 Centre for Development of Advanced Computing(C-DAC), Pune
 *  
 *  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 cdac.medinfo.sdk.hl7282.baselibs;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Locale;
import java.util.logging.Level;

import cdac.medinfo.sdk.hl7282.commoninterface.IDataType;
import cdac.medinfo.sdk.hl7282.commoninterface.IDataTypeKey;
import cdac.medinfo.sdk.hl7282.commoninterface.IDelimiter;
import cdac.medinfo.sdk.hl7282.commoninterface.IHL7Stream;
import cdac.medinfo.sdk.hl7282.exceptions.InvalidDataTypeException;
import cdac.medinfo.sdk.hl7282.exceptions.InvalidLengthException;
import cdac.medinfo.sdk.hl7282.exceptions.InvalidValueException;
import cdac.medinfo.sdk.hl7282.hl7streams.HL7BufferStream;
import cdac.medinfo.sdk.hl7282.utils.HL7Config;
import cdac.medinfo.sdk.hl7282.utils.HL7Constants;
import cdac.medinfo.sdk.hl7282.utils.HL7Logger;
import cdac.medinfo.sdk.hl7282.utils.IPairedCollection;
import cdac.medinfo.sdk.hl7282.utils.PairedCollection;
import cdac.medinfo.sdk.hl7282.utils.ResourceBundleWrapper;

/**
 * The Base Data Type class which is Responsible for the Validation, setting the values 
 * and Read and Write of all the Primitive DataTypes which extends from this class.
 */
public abstract class PrimitiveDataType implements IDataType   
{
	/**
	 * This variable holds minimum length
	 */
	protected int iMinLength;
	/**
	 * This variable holds maximum length
	 */
	protected int iMaxLength;
	/**
	 * This variable holds Conformance length
	 */
	protected String iConformanceLength;
	/**
	 * This variable holds the table number of HL7 or UserDefined Table.
	 */
	protected int iTableNo;
	/**
	 * This holds actual value.
	 */
	String strValue;
	/**
	 * This holds constant of PrimitiveDataType.
	 */
	IDataTypeKey objIDataTypeKey;
	/**
	 * This holds constant of datatype.
	 */
	int iDataType;

	/**
	 * constructor for the Class PrimitiveDataType 
	 */
	public PrimitiveDataType(IDataTypeKey objIDataTypeKey)
	{
		this.objIDataTypeKey = objIDataTypeKey;
	}
	/**
	 * Constructor for PrimitiveDataType which takes two arguments and 
	 * sets the value in the respective member variable.
	 * @param objIDataTypeKey object of IDataTypeKey.
	 * @param iMinLength The Minimum length the DataType can have.
	 * @param iMaxLength The Maximum length the DataType can have.
	 * @param iCLength The Conformance length the DataType can have.
	 */
	public PrimitiveDataType(IDataTypeKey objIDataTypeKey,int iMinLength, int iMaxLength, String strCLength)
	{
		this.objIDataTypeKey = objIDataTypeKey;
		this.iMinLength = iMinLength;
		this.iMaxLength = iMaxLength;
		this.iConformanceLength = strCLength;
	}
	/**
	 * Constructor for PrimitiveDataType which takes three arguments and 
	 * sets the value in the respective member variable.
	 * @param objIDataTypeKey object of IDataTypeKey.
	 * @param iMinLength The Minimum length the DataType can have.
	 * @param iMaxLength The Maximum length the DataType can have.
	 * @param iCLength The Conformance length the DataType can have.
	 * @param iTableNo The Table number to which the value for the component is specified. 
	 */
	public PrimitiveDataType(IDataTypeKey objIDataTypeKey,int iMinLength, int iMaxLength, String strCLength,int iTableNo)
	{
		this.objIDataTypeKey = objIDataTypeKey;
		this.iMinLength = iMinLength;
		this.iMaxLength = iMaxLength;
		this.iConformanceLength = strCLength;
		this.iTableNo = iTableNo;
	}
	
	/**
	 * This method returns the name of Data Type.
	 * @return IDataTypeKey - Name of the Data Type.
	 */
	public IDataTypeKey getDataTypeName()
	{
		return this.objIDataTypeKey;
	}

	protected static final IPairedCollection<Integer, String> objPaireCollection = new PairedCollection<Integer, String>();
	static
	{
		/*
		 * A number represented as a series of ASCII numeric characters 
		 * consisting of an optional leading sign (+ or -),
		 * the digits and an optional decimal point.
		 */
		add(HL7Constants.HL7_DT_NM,"(\\+|\\-)?\\d*\\.?\\d*");
		/*
		 * Format: YYYY[MM[DD]].  not provided the back word compatibility for YYYYMMDD.
		 * Here month and Date are optional.
		 */
		add(HL7Constants.HL7_DT_DT,"((\\d){4})((\\d){2}){0,1}((\\d){2}){0,1}");
		/*
		 * This allows for a number between 0 and 9999 to be specified.
		 */
		add(HL7Constants.HL7_DT_SI,"(\\d{0,1}\\d{0,1}\\d{0,1}\\d{0,1})");
		/*
		 * Format: YYYY[MM[DD[HH[MM[SS[.S[S[S[S]]]]]]]]][+/-ZZZZ]. 
		 */
		add(HL7Constants.HL7_DT_DTM,"(((\\d){4})((\\d){2}){0,1}((\\d){2}){0,1}((\\d){2}){0,1}((\\d){2}){0,1}((\\d){2}){0,1}((\\.\\d{1,4}){0,1}))(\\+(\\d){1,4}|\\-(\\d){1,4}){0,1}");
		//No need to add the regular expressions for IS and ID since they take the values only from ValueTables.
		//add(HL7Constants.HL7_DT_IS,"([\\p{ASCII}&&[^\\x00-\\x20\\x7F]][\\p{ASCII}&&[^\\x00-\\x1F\\x7F]]*)");
		//add(HL7Constants.HL7_DT_ID,"([\\p{ASCII}&&[^\\x00-\\x20\\x7F]][\\p{ASCII}&&[^\\x00-\\x1F\\x7F]]*)");
		/*
		 * Format for TM PrimitiveDataType: HH[MM[SS[.S[S[S[S]]]]]][+/-ZZZZ]
		 * added by Manisha
		 */
		add(HL7Constants.HL7_DT_TM,"(((\\d){2})((\\d){2}){0,1}((\\d){2}){0,1}((\\.\\d{1,4}){0,1}))(\\+(\\d){1,4}|\\-(\\d){1,4}){0,1}");
		/*
		 * The value of FT field follows the same formatting rules for an ST field
		 */
		add(HL7Constants.HL7_DT_FT,"([\\p{ASCII}&&[^\\x00-\\x20\\x7F]][\\p{ASCII}&&[^\\x00-\\x1F\\x7F]]*)");
		/*
		 * String data is left justified with trailing blanks optional. 
		 * Any displayable (printable) ACSII characters 
		 * (hexadecimal values between 20 and 7E, inclusive, or ASCII decimal values between 32 and 126),
		 * except the defined escape characters and defined delimiter characters.
		 * \x20-is the hex value for Space.
		 */
		add(HL7Constants.HL7_DT_ST,"([\\p{ASCII}&&[^\\x00-\\x20\\x7F]][\\p{ASCII}&&[^\\x00-\\x1F\\x7F]]*)");
		/*
		 * The value of ID & IS field follows the formatting rules for an ST field  
		 */
		add(HL7Constants.HL7_DT_ID,"([\\p{ASCII}&&[^\\x00-\\x20\\x7F]][\\p{ASCII}&&[^\\x00-\\x1F\\x7F]]*)");
		add(HL7Constants.HL7_DT_IS,"([\\p{ASCII}&&[^\\x00-\\x20\\x7F]][\\p{ASCII}&&[^\\x00-\\x1F\\x7F]]*)");
		/*
		 * The expression should satisfy the same condition as of ST But,
		 * Leading spaces should be included. Trailing spaces should be removed.
		 */
		add(HL7Constants.HL7_DT_TX,"[\\p{ASCII}&&[^\\x00-\\x1F\\x7F]]+");
		/*
		 * The value of GTS field follows the same formatting rules for an ST field
		 */
		add(HL7Constants.HL7_DT_GTS,"([\\p{ASCII}&&[^\\x00-\\x20\\x7F]][\\p{ASCII}&&[^\\x00-\\x1F\\x7F]]*)");
		/*
		 * The value of SNM field 														
		 */
		add(HL7Constants.HL7_DT_SNM,"(^\\+?[0-9. ()-]{10,25}$)");
	}


	/**
	 * This Function to map a key with specified regular expression in the HashMap
	 * @param iKey This is the Value Representation Type
	 * @param strRegex This is the regular Expression for validating the datatype
	 */
	private static void add(int iKey,String strRegex)
	{
		objPaireCollection.put(new Integer(iKey), strRegex);
	}
	/**
	 * Function returns the maxLength in the member variable iMaxLength.
	 * @return int - the Maximum length.
	 */
	public int getIMaxLength() 
	{
		return iMaxLength;
	}

	/**
	 * Function sets the maxLength in the member variable iMaxVariable.
	 * @param maxLength - the Maximum length. 
	 */
	public void setIMaxLength(int maxLength)
	{
		iMaxLength = maxLength;
	}
	
	/**
	 * Function returns the minLength in the member variable iMinLength.
	 * @return int - the Minimum length.
	 */
	public int getIMinLength() 
	{
		return iMinLength;
	}

	/**
	 * Function sets the minLength in the member variable iMinVariable.
	 * @param maxLength - the Minimum length. 
	 */
	public void setIMinLength(int minLength)
	{
		iMinLength = minLength;
	}

	/**
	 * Function returns the cLength in the member variable iConformanceLength.
	 * @return String - the Conformance length.
	 */
	public String getICLength() 
	{
		return iConformanceLength;
	}

	/**
	 * Function sets the cLength in the member variable iCVariable.
	 * @param cLength - the Confromance length. 
	 */
	public void setICLength(String  cLength)
	{
		iConformanceLength = cLength;
	}

	/**
	 * Function returns the value in the member variable strValue.
	 * @return String - string actual value.
	 */
	public Object getValue() 
	{
		return (Object)strValue;
	}

	/**
	 * Function sets the value in the member variable strValue after validations.
	 * @param objValue - the Object value as String.
	 */
	public void setValue(Object objValue) throws InvalidDataTypeException
	{
			this.strValue = (String)objValue;
	}

	/**
	 *Method writes the data to the Stream.
	 *@param objIHL7Stream Object of HL7Stream
	 *@param objIDelimiter Object of class Delimiter
	 *@return the integer value depending on the result.
	 *@throws IOException - if IO exception fails.
	 */	
	public int write(IHL7Stream objIHL7Stream,IDelimiter objIDelimiter) throws IOException
	{


		/*Check if the the String ot be written is null 
		 * or Object of archive stream is null
		 */
		if(strValue==null || objIHL7Stream==null || objIDelimiter==null)
		{
			return 0;
		}	
		else
		{
				//The method is used to add the escape sequence for Escape Character.
				char cEscapeChar = objIDelimiter.getEscapeCharacter();
				addEscapeSequences(cEscapeChar);
				//The logic is to replace the seperators with the respective escape Sequences.
				strValue = strValue.replace(""+objIDelimiter.getComponentSeparator(),"\\S\\");
				strValue = strValue.replace(""+objIDelimiter.getFieldSeparator(),"\\F\\");
				strValue = strValue.replace(""+objIDelimiter.getRepetitionSeparator(),"\\R\\");
				strValue = strValue.replace(""+objIDelimiter.getSubComponentSeparator(),"\\T\\");
				strValue = strValue.replace(""+objIDelimiter.getTruncationCharacter(), "\\P\\");
				//The String write operation
				objIHL7Stream.writeString(strValue);
				return 1;
		}
	}

	/**
	 * This validate function validates the data value object
	 * with the regular expression and check for maximum length.
	 * @param strValue - the string value.
	 * @return int - function status [Success/Failure].
	 * @throws InvalidDataTypeException - if Data Type Validation fails
	 */
	public boolean validate() throws InvalidDataTypeException
	{
		if(strValue==null)
			throw new InvalidDataTypeException(this.getClass().getSimpleName());
		String strLogMessage = null;
		try
		{
			//Get the regular expression for the specified PrimitiveDataType Class
			String strRegex = objPaireCollection.get(new Integer(iDataType)).toString();
			if(!strValue.matches(strRegex))
			{
				strLogMessage = ResourceBundleWrapper.getValue("exceptions","RulesViolated",new Locale(HL7Config.createInstance().getLocale()));
				if(HL7Config.createInstance().isLoggingOn())
				{
					HL7Logger objHL7Logger = HL7Logger.getLogger();						
					objHL7Logger.log(Level.WARNING, strLogMessage + " : " + strValue);
				}
			}
			//if value is not present in Value Table return FALSE
			if(iTableNo != 0)
			{
				ValueTables objValueTables = ValueTables.createInstance();
				if(objValueTables.isValuePresent(iTableNo,strValue)==HL7Constants.HL7_VALUE_NOT_FOUND)
				{
					strLogMessage = strValue + ResourceBundleWrapper.getValue("warnings","ValueNotFound",new Locale(HL7Config.createInstance().getLocale())) + iTableNo;
					if(HL7Config.createInstance().isLoggingOn())
					{
						HL7Logger objHL7Logger = HL7Logger.getLogger();						
						objHL7Logger.log(Level.WARNING,strLogMessage);
					}
				}
			}
			
			//if length of data is greater than Min length and Less than Max length and Conformance length is not equal to null return true.
			if(validateForLength())
			{
				if((iConformanceLength.charAt(iConformanceLength.length()-1)=='#' || (iConformanceLength.charAt(iConformanceLength.length()-1))=='='))
				{
					validationForValue();
				}
				if((iConformanceLength.charAt(iConformanceLength.length()-1)!='#') && (iConformanceLength.charAt(iConformanceLength.length()-1)!='='))
				{
					if(strValue.length()<=Integer.parseInt(iConformanceLength));
					
					else
					{
						String strMessage = ResourceBundleWrapper.getValue("exceptions", "Voilating_Conformance_Length",new Locale(HL7Config.createInstance().getLocale()));
						HL7Logger objHLogger = HL7Logger.getLogger();
						objHLogger.log(strMessage);
					}
						
				}
			}
			else
			{
				//Checking for Conformance length 
				if(iConformanceLength!=null)
				{
					if((iConformanceLength.charAt(iConformanceLength.length()-1)=='#' || (iConformanceLength.charAt(iConformanceLength.length()-1))=='=') && strValue!=null)
					{
						validationForValue();
					}
					if(((iConformanceLength.charAt(iConformanceLength.length()-1)!='#') && (iConformanceLength.charAt(iConformanceLength.length()-1)!='=')) && strValue!=null)
					{
						if(strValue.length()<=Integer.parseInt(iConformanceLength));
						
						else
						{
							String strMessage = ResourceBundleWrapper.getValue("exceptions", "Voilating_Conformance_Length",new Locale(HL7Config.createInstance().getLocale()));
							HL7Logger objHLogger = HL7Logger.getLogger();
							objHLogger.log(strMessage);
						}
							
					}
				}
			}
			
			return true;
		}
		catch(InvalidValueException ex)
		{
			if(HL7Config.createInstance().isLoggingOn())
			{
				HL7Logger objHL7Logger = HL7Logger.getLogger();						
				objHL7Logger.log(ex.getMessage());
			}
			throw new InvalidDataTypeException(this.getClass().getSimpleName(),ex);
		}
		catch(InvalidLengthException ex)
		{
			if(HL7Config.createInstance().isLoggingOn())
			{
				HL7Logger objHL7Logger = HL7Logger.getLogger();						
				objHL7Logger.log(ex.getMessage());
			}
			throw new InvalidDataTypeException(this.getClass().getSimpleName(),ex);
		}
	}
	
	

	/**
	 * The method is used to replace the occurance of BackSlash by the string "\E\".
	 * @param cEscapeChar char to be replaced.
	 * @return int - function status [Success/Failure].
	 */
	private int addEscapeSequences(char cEscapeChar) 
	{
		if(cEscapeChar == '\0')
			return HL7Constants.HL7_FUNCTION_FAIL;
		int iLength = strValue.length();
		int iIndex=0;
		String strReplacedValue = new String();
		int iCounter =0;
		while(iIndex<iLength)
		{
			//Check for occurence of Escape Character 
			if(strValue.charAt(iIndex)==cEscapeChar)
			{
				//Check if only two characters are not remaining.
				if((iLength-iIndex>=3))
				{
					//This block will be executed If there is only "\" and not the formatted characters occured.
					if(!(strValue.substring(iIndex, iIndex+3).equals("\\E\\") || strValue.substring(iIndex, iIndex+3).equals("\\H\\")  
							|| strValue.substring(iIndex, iIndex+3).equals("\\F\\")  || strValue.substring(iIndex, iIndex+3).equals("\\S\\")  
							|| strValue.substring(iIndex, iIndex+3).equals("\\T\\")  || strValue.substring(iIndex, iIndex+3).equals("\\R\\")
							|| strValue.substring(iIndex, iIndex+3).equals("\\N\\")))
					{
						String strTemp = strValue.substring(iCounter, iIndex);
						strReplacedValue = strReplacedValue.concat(strTemp);
						strReplacedValue = strReplacedValue.concat("\\E\\");
						iIndex++;
						iCounter =iIndex;
					}
					//This block will be executed If already the formatted characters occured.
					else
					{
						String strTemp = strValue.substring(iCounter, iIndex+3);
						strReplacedValue = strReplacedValue.concat(strTemp);
						iIndex= iIndex+3;
						iCounter = iIndex;
					}
				}
				//This block will be executed If only two characters are remaining and There encountered "\"
				else
				{
					String strTemp = strValue.substring(iCounter, iIndex);
					strReplacedValue = strReplacedValue.concat(strTemp);
					strReplacedValue = strReplacedValue.concat("\\E\\");
					iIndex++;
					iCounter =iIndex;
				}
			}
			//This block will be executed If no "\" is encountered
			else
			{
				String strTemp = strValue.substring(iCounter, iIndex+1);
				strReplacedValue = strReplacedValue.concat(strTemp);
				iIndex++;
				iCounter = iIndex;
			}
		}
		//assign the replaced string to the strValue.
		strValue = strReplacedValue;
		return HL7Constants.HL7_FUNCTION_SUCCESS;
	}

	/**
	 *Method reads the data from the String.
	 *@param strAttributeData String of HL7Stream.
	 *@param objIDelimiter Object of class Delimiter.
	 *@return integer - Number of bytes read.
	 *				  - Fail if data read is not valid.
	 *@throws IOException - if IO exception fails.
	 */	
	public int read(String strAttributeData, IDelimiter objIDelimiter)  throws IOException
	{
		
		int iReadBytes = 0;
		String strTemp = "";
		int i = -1;
		do
		{
			i++;
			char cTemp = '\0';
	
			cTemp = strAttributeData.charAt(i);
			if((cTemp==objIDelimiter.getFieldSeparator())||(cTemp==objIDelimiter.getComponentSeparator())
					||(cTemp==objIDelimiter.getSubComponentSeparator())||(cTemp==objIDelimiter.getRepetitionSeparator()) || (cTemp=='\r'))
			{
				break;
			}
			else
				strTemp += cTemp;
		}while(strAttributeData.charAt(i)!='\r' && (strAttributeData.length()-1)!= i);

		iReadBytes = strTemp.length();
		if(iReadBytes > 0)
		{
			//Replace escape sequences with proper separators.
			strTemp = strTemp.replace("\\S\\",""+objIDelimiter.getComponentSeparator());
			strTemp = strTemp.replace("\\F\\",""+objIDelimiter.getFieldSeparator());
			strTemp = strTemp.replace("\\R\\",""+objIDelimiter.getRepetitionSeparator());
			strTemp = strTemp.replace("\\T\\",""+objIDelimiter.getSubComponentSeparator());
			strTemp = strTemp.replace("\\E\\",""+objIDelimiter.getEscapeCharacter());
			strTemp = strTemp.replace("\\P\\",""+objIDelimiter.getTruncationCharacter());
			setValue(strTemp);
		}
		return iReadBytes;
	}
	/**
	 * This will create replicate of existing Data Type.
	 * @param objDataType object of Data Type.
	 * @param objDelimiter object of Delimiter.
	 *@throws IOException - if IO operation fails.
	 */
	public void copy(IDataType objDataType, IDelimiter objDelimiter) throws IOException
	{
		ByteArrayOutputStream objByteArrayOutputStream = new ByteArrayOutputStream();

		HL7BufferStream tempStream = new HL7BufferStream();
		tempStream.setOutputStream(objByteArrayOutputStream);

		objDataType.write(tempStream, objDelimiter);
		byte []arrByte =  new byte[objByteArrayOutputStream.size()];
		arrByte = objByteArrayOutputStream.toByteArray();
		ByteArrayInputStream objByteArrayInputStream = new ByteArrayInputStream(arrByte);
		tempStream.setInputStream(objByteArrayInputStream);

		this.read(arrByte.toString(), objDelimiter);
	}
	
	/**
	 * This will return the length of DataType. 
	 * @return int length of String.
	 */
	public int getLength()
	{
		if(strValue!=null)
			return strValue.length();
		else
			return 0;
	}
	
	/**
	 * This method returns the state for Data Type whether it 
	 * is primitive Data Type or composite DataType.
	 * @return false for all Composite DataType. 
	 */
	public boolean isPrimitive()
	{
		return true;
	}
	
	/**
	 * This method returns a string consisting name of the Item.
	 * @return String - name of the Item.
	 */
	public String toString()
	{
		return strValue;
	}
	
	private boolean validateForLength()
	{
		if(strValue != null)
		{
			int iValLength = getLength();
			
			if(iMinLength !=0 )
			{
				if(iMaxLength !=0)
				{
					if(iValLength>=iMinLength && iValLength<=iMaxLength)
					{
						if(iConformanceLength!=null)
							return true;
						else
						{
							return false;
						}
					}
					else
					{
						String strMessage = ResourceBundleWrapper.getValue("exceptions", "Voilating_Max_Min_Bound",new Locale(HL7Config.createInstance().getLocale()));
						HL7Logger objHLogger = HL7Logger.getLogger();
						objHLogger.log(strMessage + ":" + strValue); 
						return false;
					}
						
				}
				else
				{
					if(iValLength>=iMinLength)
					{
						if(iConformanceLength!=null)
							return true;
						else
						{
							return false;
						}
					}
					else
					{
						String strMessage = ResourceBundleWrapper.getValue("exceptions", "Voilating_Max_Min_Bound",new Locale(HL7Config.createInstance().getLocale()));
						HL7Logger objHLogger = HL7Logger.getLogger();
						objHLogger.log(strMessage + ":" + strValue); 
						return false;
					}
				}
			}
		}
		else
		{
			if(iMinLength > 0)
			{
				String strMessage = ResourceBundleWrapper.getValue("warnings", "Value_should_not_be_NULL",new Locale(HL7Config.createInstance().getLocale()));
				HL7Logger objHLogger = HL7Logger.getLogger();
				objHLogger.log(strMessage + ":" + strValue); 
				return false;
			}
		}
		return false;
	}
	
	private boolean validationForValue()
	{
		if(strValue.length()<Integer.parseInt(iConformanceLength.substring(0, iConformanceLength.length()-1)))
		{
			//Message Do not contain Truncation Character and Conformance Length contain truncation character. 
			if(strValue.charAt(strValue.length()-1)!='#'&& (iConformanceLength.charAt(iConformanceLength.length()-1)=='#' || iConformanceLength.charAt(iConformanceLength.length()-1)=='='))
				return true;
			
			if(strValue.charAt(strValue.length()-1)=='#'&& (iConformanceLength.charAt(iConformanceLength.length()-1)=='#' || iConformanceLength.charAt(iConformanceLength.length()-1)=='='))
			{
				String strMessage = ResourceBundleWrapper.getValue("exceptions", "Voilating_Conformance_Length",new Locale(HL7Config.createInstance().getLocale()));
				HL7Logger objHLogger = HL7Logger.getLogger();
				objHLogger.log(strMessage );
				return false;
			}
		}
		//Message Length is greater than Conformance Length
		else
		{
			//If Conformance length contain '=' and Message do not contain Truncation Character log it 
			//else throw exception Truncation Character present in Message.
			if((iConformanceLength.charAt(iConformanceLength.length()-1)=='=' || iConformanceLength.charAt(iConformanceLength.length()-1)=='#') && strValue.charAt(strValue.length()-1)!='#' )
				return true;
			
			if(iConformanceLength.charAt(iConformanceLength.length()-1)=='#' && strValue.charAt(strValue.length()-1)=='#' )
				return true;
			
			//If Conformance length contain '#' and Message Contain/do not contain Truncation Character log it 
			if(iConformanceLength.charAt(iConformanceLength.length()-1)=='=' && (strValue.charAt(strValue.length()-1)=='#'))
			{
				String strMessage = ResourceBundleWrapper.getValue("exceptions", "Voilating_Conformance_Length",new Locale(HL7Config.createInstance().getLocale()));
				HL7Logger objHLogger = HL7Logger.getLogger();
				objHLogger.log(strMessage);
				return false;
			}
		}
		return false;
	}
}

