/* * $Id: SimpleDelimiterFormat.java,v 1.2 2005/12/19 12:31:29 oldman1004 Exp $ * * Copyright(c) 2002 Infomata * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package com.infomata.data; /** * SimpleDelimiterFormat is configurable data format that uses * simple delimiter and escape sequence scheme to encode data into a * text file. * <p style="font-weight:bold;"> * Examples: * </p> * <table class="example"> * <tr> * <th class="example">Format</th> * <th class="example">Instantiation</th> * </tr> * <tr> * <td class="example">Tab separated</td> * <td class="example"><code>new SimpleDelimiterFormat("\t", null)</code></td> * </tr> * <tr> * <td class="example">Pipe separated</td> * <td class="example"><code>new SimpleDelimiterFormat("|", "\")</code></td> * </tr> * </table> * * @author <a href="mailto:oldman1004@gmail.com">Sam Kim</a> * @version $Revision: 1.2 $ */ public class SimpleDelimiterFormat implements DataFormat { private char[] delimiter = null; private char[] escape = null; /** * Creates a new instance of SimpleDelimiterFormat with * specified delimiter and escape sequence. * * @param delimiter - character sequence used to separate one element * from another. <code>delimiter</code> * CANNOT be NULL or empty string. * @param escape - character sequence used to signal that next * character sequence (either <code>delimiter</code> * or <code>escape</code>) is part of data. */ public SimpleDelimiterFormat(String delimiter, String escape) throws IllegalArgumentException { if (delimiter == null || delimiter.length() == 0) { throw new IllegalArgumentException("delimter cannot be null or empty."); } this.delimiter = delimiter.toCharArray(); if (escape == null) { this.escape = new char[0]; } else { this.escape = escape.toCharArray(); } } /* (non-Javadoc) * @see com.infomata.data.DataFormat#parseLine(java.lang.String) */ public DataRow parseLine(String line) { DataRow row = new DataRow(); if (line != null && line.length() > 0) { StringBuffer o = new StringBuffer(); char[] ch = line.toCharArray(); int start = 0; boolean ignore = false; for (int i = 0; i < ch.length; i++) { if (ch[i] == delimiter[0] && isDelimiter(ch, i)) { if (ignore) { ignore = false; } else { row.add(decodeData(new String(ch, start, i - start))); start = i + delimiter.length; } i += delimiter.length - 1; } else if (escape.length > 0 && ch[i] == escape[0] && isEscape(ch, i)) { ignore = !ignore; i += escape.length - 1; } } o.append(new String(ch, start, ch.length - start)); row.add(o.toString()); } return row; } /* (non-Javadoc) * @see com.infomata.data.DataFormat#format(com.infomata.data.DataRow) */ public String format(DataRow row) { StringBuffer o = new StringBuffer(); if (row != null && row.size() > 0) { o.append(encodeData(row.getString(0))); for (int i = 1; i < row.size(); i++) { o.append(delimiter); o.append(encodeData(row.getString(i))); } } return o.toString(); } private String decodeData(String content) { StringBuffer o = new StringBuffer(); if (content == null) { o.append("null"); } else if (content.length() > 0) { char[] ch = content.toCharArray(); for (int i = 0; i < ch.length; i++) { if (escape.length > 0 && ch[i] == escape[0] && isEscape(ch, i)) { i += escape.length; } o.append(ch[i]); } } return o.toString(); } private String encodeData(String content) { StringBuffer o = new StringBuffer(); if (content == null) { o.append("null"); } else if (content.length() > 0) { char[] ch = content.toCharArray(); for (int i = 0; i < ch.length; i++) { if ((ch[i] == delimiter[0] && isDelimiter(ch, i)) || (escape.length > 0 && ch[i] == escape[0] && isEscape(ch, i))) { o.append(escape); } o.append(ch[i]); } } return o.toString(); } private boolean isDelimiter(char[] ch, int offset) { return match(ch, delimiter, offset); } private boolean isEscape(char[] ch, int offset) { return match(ch, escape, offset); } private boolean match(char[] ch, char[] sp, int offset) { for (int i = 0; i < sp.length && i + offset < ch.length; i++) { if (ch[offset + i] != sp[i]) { return false; } } return true; } /* protected void out(Object o) { System.out.print(o.toString()); } protected void outln(Object o) { System.out.println(o.toString()); } */ }