/** * Copyright (C) 2013 Romain Guefveneu. * * This file is part of naonedbus. * * Naonedbus 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 3 of the License, or * (at your option) any later version. * * Naonedbus 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, see <http://www.gnu.org/licenses/>. */ package net.naonedbus.helper; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Classe gérer les fichiers de PreparedStatement. * * @author romain * */ public class BulkLoaderHelper { private static final String COMMENT_TOKEN = "#"; private static final char CHAR_PARAM_SPLIT = ';'; private final InputStream inputStream; private final List<BulkQuery> bulkQueries; public BulkLoaderHelper(final InputStream inputStream) { this.inputStream = inputStream; bulkQueries = new ArrayList<BulkLoaderHelper.BulkQuery>(); } public List<BulkQuery> getQueries() throws IOException { if (bulkQueries.isEmpty()) { load(); } return bulkQueries; } private void load() throws IOException { final BufferedReader buffer = new BufferedReader(new InputStreamReader(inputStream)); BulkQuery bulkQuery = null; boolean changePattern = true; String line; while ((line = buffer.readLine()) != null) { if (line.trim().length() == 0) { changePattern = true; continue; } if (line.startsWith(COMMENT_TOKEN)) { continue; } if (changePattern) { changePattern = false; if (bulkQuery != null) { bulkQueries.add(bulkQuery); } bulkQuery = new BulkQuery(line); } else { bulkQuery.addValues(fastSplit(line, CHAR_PARAM_SPLIT)); } } buffer.close(); if (bulkQuery != null) { bulkQueries.add(bulkQuery); } } /** * Découper une chaîne selon un caractère. * * @param line * La chaîne à découper * @param split * Le caractère de séparation * @return La chaîne découpée sous forme de tableau */ private static String[] fastSplit(final String line, final char split) { final String[] temp = new String[line.length() / 2]; int wordCount = 0; int i = 0; int j = line.indexOf(split); // First substring while (j >= 0) { temp[wordCount++] = line.substring(i, j); i = j + 1; j = line.indexOf(split, i); // Rest of substrings } temp[wordCount++] = line.substring(i); // Last substring final String[] result = new String[wordCount]; System.arraycopy(temp, 0, result, 0, wordCount); return result; } /** * Classe définissant une requête. * * @author romain * */ public static class BulkQuery { private static final char paramChar = '?'; private String pattern; private List<String[]> values; private int paramCount = 0; public BulkQuery(final String pattern) { this.values = new ArrayList<String[]>(); setPattern(pattern); } public String getPattern() { return pattern; } public void setPattern(final String pattern) { this.pattern = pattern; this.paramCount = countOccurrences(pattern, paramChar, 0); } public void addValues(final String[] values) { if (values.length != paramCount) { throw new IllegalArgumentException("Nombre de paramètres incorrect : " + values.length + " au lieu de " + paramCount + " attendus. [" + Arrays.toString(values) + "]"); } this.values.add(values); } public List<String[]> getValues() { return values; } public void setValues(final List<String[]> values) { this.values = values; } private static int countOccurrences(final String haystack, final char needle, final int index) { if (index >= haystack.length()) { return 0; } final int contribution = haystack.charAt(index) == needle ? 1 : 0; return contribution + countOccurrences(haystack, needle, index + 1); } } }