Java tutorial
/* * Copyright (c) 2007 NTT DATA Corporation * * 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 jp.terasoluna.fw.file.dao.standard; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; import jp.terasoluna.fw.file.annotation.FileFormat; import jp.terasoluna.fw.file.dao.FileException; /** * ??(?) * <p> * ?????1?? ??<br> * CSV???????????? ????? * </p> * <b>??</b><br> * @{@link FileFormat}?<br> * <div align="center"> * <table width="90%" border="1" bgcolor="#FFFFFF"> * <tr> * <td><b>???</b></td> * <td><b>???</b></td> * <td><b></b></td> * <td><b></b></td> * </tr> * <tr> * <td> <code></code></td> * <td> <code>lineFeedChar</code></td> * <td> <code>?</code></td> * <td> <code></code></td> * </tr> * <tr> * <td> <code></code></td> * <td> <code>delimiter</code></td> * <td> <code>','</code></td> * <td> <code></code></td> * </tr> * <tr> * <td> <code>?</code></td> * <td> <code>encloseChar</code></td> * <td> <code>??('\u0000')</code></td> * <td> <code></code></td> * </tr> * <tr> * <td> <code></code></td> * <td> <code>fileEncodeing</code></td> * <td> <code>?</code></td> * <td> <code></code></td> * </tr> * <tr> * <td> <code></code></td> * <td> <code>headerLineCount</code></td> * <td> <code>0</code></td> * <td> <code></code></td> * </tr> * <tr> * <td> <code></code></td> * <td> <code>trailerLineCount</code></td> * <td> <code>0</code></td> * <td> <code></code></td> * </tr> * </table> * </div> <br> * @{@link jp.terasoluna.fw.file.annotation.InputFileColumn}?@{@link jp.terasoluna.fw.file.annotation.OutputFileColumn}?<br> * <div align="center"> * <table width="90%" border="1" bgcolor="#FFFFFF"> * <tr> * <td><b>???</b></td> * <td><b>???</b></td> * <td><b></b></td> * <td><b></b></td> * </tr> * <tr> * <td> <code></code></td> * <td> <code>columnIndex</code></td> * <td>-</td> * <td> <code></code></td> * </tr> * <tr> * <td> <code></code></td> * <td> <code>columnFormat</code></td> * <td> <code>""</code></td> * <td> <code></code></td> * </tr> * <tr> * <td> <code>?</code></td> * <td> <code>bytes</code></td> * <td> <code>-1</code></td> * <td> <code></code></td> * </tr> * <tr> * <td> <code></code></td> * <td> <code>paddingType</code></td> * <td> <code>??</code></td> * <td> <code></code></td> * </tr> * <tr> * <td> <code></code></td> * <td> <code>paddingChar</code></td> * <td> <code>' '</code></td> * <td> <code></code></td> * </tr> * <tr> * <td> <code></code></td> * <td> <code>trimType</code></td> * <td> <code>??</code></td> * <td> <code></code></td> * </tr> * <tr> * <td> <code></code></td> * <td> <code>trimChar</code></td> * <td> <code>' '</code></td> * <td> <code></code></td> * </tr> * <tr> * <td> <code>?</code></td> * <td> <code>stringConverter</code></td> * <td> <code>NullStringConverter.class</code></td> * <td> <code></code></td> * </tr> * </table> * </div> <br> * <b>?</b><br> * <ul> * * <li>?Caracter.MIN_VALUE???????()</li> * </ul> * @param <T> */ public class VariableFileLineIterator<T> extends AbstractFileLineIterator<T> { /** * */ private char delimiter = ','; /** * ? */ private char encloseChar = Character.MIN_VALUE; /** * * @param fileName ?? * @param clazz * @param columnParserMap */ public VariableFileLineIterator(String fileName, Class<T> clazz, Map<String, ColumnParser> columnParserMap) { super(fileName, clazz, columnParserMap); FileFormat fileFormat = clazz.getAnnotation(FileFormat.class); // ?Character.MIN_VALUE???? if (fileFormat.delimiter() == Character.MIN_VALUE) { throw new FileException("Delimiter can not use '\\u0000'.", new IllegalStateException(), fileName); } // ????????? if (fileFormat.lineFeedChar().indexOf(fileFormat.delimiter()) >= 0) { throw new FileException("delimiter is the same as lineFeedChar and is no use.", new IllegalStateException(), fileName); } // ?? this.encloseChar = fileFormat.encloseChar(); // ? this.delimiter = fileFormat.delimiter(); // ??? super.init(); } /** * ????? ???? ????<br> * <code>fileLineString</code>?<code>null</code>???? ?????????<code>String</code>???? * @param fileLineString ??1? * @return ? */ @Override protected String[] separateColumns(String fileLineString) { if (fileLineString == null || "".equals(fileLineString)) { return new String[0]; } // 1??? StringBuilder columnBuilder = new StringBuilder(); // ???? char previousChar = Character.MIN_VALUE; // ?????? List<String> columnList = new ArrayList<String>(); boolean isEnclosed = true; boolean isEscaped = false; int fieldCount = 0; char[] columnEncloseChar = getColumnEncloseChar(); if (!isEnclosed()) { return StringUtils.splitByWholeSeparatorPreserveAllTokens(fileLineString, Character.toString(delimiter)); } else { for (char currentChar : fileLineString.toCharArray()) { if (previousChar == Character.MIN_VALUE) { previousChar = currentChar; } if (previousChar == getEncloseCharcter(columnEncloseChar, fieldCount)) { if (isEnclosed) { if (currentChar == getEncloseCharcter(columnEncloseChar, fieldCount)) { isEnclosed = false; } } else { if (currentChar == getEncloseCharcter(columnEncloseChar, fieldCount)) { if (isEscaped) { columnBuilder.append(currentChar); isEscaped = false; } else { isEscaped = true; } } else if (currentChar == getDelimiter()) { if (isEscaped) { columnList.add(columnBuilder.toString()); previousChar = Character.MIN_VALUE; columnBuilder.delete(0, columnBuilder.length()); isEnclosed = true; isEscaped = false; fieldCount++; } else { columnBuilder.append(currentChar); isEscaped = false; } } else { columnBuilder.append(currentChar); } } } else { if (currentChar != getDelimiter()) { columnBuilder.append(currentChar); } else { columnList.add(columnBuilder.toString()); previousChar = Character.MIN_VALUE; columnBuilder.delete(0, columnBuilder.length()); fieldCount++; } } } columnList.add(columnBuilder.toString()); return columnList.toArray(new String[columnList.size()]); } } /** * ????? * @param index ? * @return ? */ private char getEncloseCharcter(char[] columnEncloseChar, int index) { if (columnEncloseChar.length == 0 || index >= columnEncloseChar.length) { return this.encloseChar; } else { return columnEncloseChar[index]; } } /** * ?? * @return */ @Override public char getDelimiter() { return delimiter; } /** * ??? * @return ? */ @Override public char getEncloseChar() { return encloseChar; } }