/* $Id: SyntaxDE.java,v 1.1 2011/05/04 22:37:56 willuhn Exp $ This file is part of HBCI4Java Copyright (C) 2001-2008 Stefan Palme HBCI4Java 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 of the License, or (at your option) any later version. HBCI4Java 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; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** @internal @brief Collection of HBCI datatypes. This package contains a collection of classes, where each class represents one of the datatypes defined in HBCI syntax descriptions (e.g. AN for alphanumeric data, Bin for binary data etc.). These classes are used during the message generation process either when building a new message to be sent or when parsing a received message. These classes are never instantiated directly, but they are loaded and instantiated dynamically (for a certain syntax element, the name of the class to be used for storing its value is determined by the value of the attribute @c type in the syntax description for this syntax element). The classname to be loaded is built from the @c type attribute by prepending @c org.kapott.hbci.datatypes.Syntax */ package org.kapott.hbci.datatypes; import org.kapott.hbci.exceptions.InvalidArgumentException; import org.kapott.hbci.manager.HBCIUtilsInternal; /* @internal @brief Abstract base class for datatypes. This is an abstract base class for all classes that will represent a certain HBCI-datatype. @author $Author: willuhn $ */ public abstract class SyntaxDE { private String content; /**< @internal @brief contains the value of the DE in human readable format */ private void initData(String x,int minsize,int maxsize) { content=null; setContent(x,minsize,maxsize); } /** @internal @brief Creates a new instance of a datatype. In this constructor the data element will be initialized with the given value @p x. During initializing process the size constraints for this element will be verified. If verification fails, an IllegalArgumentException will be thrown. @param x The string representation of the init value. @param minsize The minimum size (string length) of the init value. @param maxsize The maximum size (string length) of the init value. If this is zero, no checking for @p maxsize will be done. */ public SyntaxDE(String x, int minsize, int maxsize) { initData(x,minsize,maxsize); } public void init(String x, int minsize, int maxsize) { initData(x,minsize,maxsize); } public void init(StringBuffer x, int minsize, int maxsize) { initData(x.toString(),minsize,maxsize); } private void initData() { content=null; } /** @internal @overload */ protected SyntaxDE() { initData(); } protected void init() { initData(); } /** @internal @brief Sets the value for a data element. @param st The string representation of the init value. @param minsize The minimum size (string length) of the init value. @param maxsize The maximum size (string length) of the init value. If this is zero, no checking for @p maxsize will be done. @exception IllegalArgumentException when the length of @p x is not in the range @p minsize ... @p maxsize */ protected final void setContent(String st,int minsize,int maxsize) { /* die stringlaenge muss zwischen minsize und maxsize liegen, im falle 'maxsize=0' kann sie beliebig gross sein */ int len=st.length(); if (len<minsize || (maxsize!=0 && len>maxsize)) { String msg=HBCIUtilsInternal.getLocMsg("EXC_DT_INV_STRINGLEN",new Object[] { st,Integer.toString(len),Integer.toString(minsize),Integer.toString(maxsize)}); if (len==0 || !HBCIUtilsInternal.ignoreError(null,"client.errors.ignoreWrongDataLengthErrors",msg)) throw new InvalidArgumentException(msg); } content=st; } /** @internal @brief Returns the value of the data element in the form needed in HBCI messages @param zero Just a dummy argument to overload the toString method. @return A String containing the HBCI representation of this data element */ public String toString(int zero) { return (content!=null)?content:""; } /** @internal @brief Returns the current @c content. @return den aktuellen Inhalt des SyntaxDE in der intern gespeicherten Form (human-readable) */ protected String getContent() { return content; } // ----------------------------------------------------------------------------------- /** @internal @brief Returns the index, where the next value in the HBCI message @c res starts. This method is needed when parsing HBCI messages. It checks the first character of String @p res. If this character is one of the HBCI-specific data-element-delimiters, 1 will be returned, else 0 (i.e. the return value is the index into the String @p res where we can start fetching the next syntax token) @param res A part of an HBCI message to be parsed. @return Index into @p res where next token starts. */ protected static int skipPreDelim(StringBuffer res) { int ret = 0; if (res.length() != 0) { char ch = res.charAt(0); if (ch == '\'' || ch == '+' || ch == ':') { ret++; } } return ret; } /** @internal @brief Returns the index of the next delimiter token. This method is needed when parsing an HBCI message. It scans @p res starting at position @p startidx for the next occurence of an HBCI-specific data-element-delimiter and returns its position. @param res Part of an HBCI-message to be parsed. @param startidx Index position where to start looking for the next delimiter. @return The position of the next delimiter character in @p res. If there is no next delimiter character, the return value will be the next character after the end of the String @p res (i.e. will equal @c res.length()) */ public static int findNextDelim(StringBuffer res, int startidx) { int ret = startidx; boolean quoted = false; boolean quit = false; boolean inBinLen = false; int binLenStart = 0; int len=res.length(); while (ret<len && !quit) { char ch=res.charAt(ret++); if (!quoted) { if (ch == '?') { quoted = true; } else if (ch == '@') { if (!inBinLen) { inBinLen = true; binLenStart = ret; } else { int binLenEnd=ret-1; String st=res.substring(binLenStart, binLenEnd); int binLen = Integer.parseInt(st); ret+=binLen; inBinLen=false; } } else if (ch == '\'' || ch == '+' || ch == ':') { ret--; quit=true; } } else { quoted = false; } } return ret; } /** @internal @brief Returns the human-readable value of this data element. @return Die human-reable Repraesentation dieses Elementes */ public String toString() { return (content==null)?"":content; } public void destroy() { content=null; } }