/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * Copyright (c) 2013, MPL CodeInside http://codeinside.ru */ package ru.codeinside.adm.parser; import com.google.common.base.Splitter; import com.google.common.collect.Lists; import org.apache.commons.lang.StringUtils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.LinkedList; /** * Разбор файла фикстур с данными о услугах и процедурах */ public class ServiceFixtureParser { private final LinkedList<Row> stack; public ServiceFixtureParser() { stack = new LinkedList<Row>(); } public void loadFixtures(InputStream is, ServiceFixtureParser.PersistenceCallback callback) throws IOException { final Splitter propertySplitter = Splitter.on(':'); final BufferedReader reader = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8"))); String line; int lineNumber = 0; while ((line = reader.readLine()) != null) { lineNumber++; int level = startIndex(line); if (line.startsWith("#") || level < 0) { continue; } final ArrayList<String> props = Lists.newArrayList(propertySplitter.split(line.substring(level))); final String name = StringUtils.trimToNull(props.get(0)).replace("<br/>", "\n"); if (name == null) { throw new IllegalStateException("Пропущено имя( строка:" + lineNumber + ")"); } final Long regCode; try { regCode = Long.parseLong(props.get(1)); } catch (NumberFormatException e) { throw new IllegalStateException("Пропущен код ( строка:" + lineNumber + "): " + name); } final boolean isProc = level > 0; Row parent = getParentRow(level); if (!isProc) { long servId = callback.onServiceComplete(name, regCode); stack.addLast(new Row(level, servId)); } if (isProc && parent != null) { callback.onProcedureComplete(name, regCode, parent.id); } if (isProc && parent == null) { throw new IllegalStateException("Процедура без услуги( строка:" + lineNumber + "): " + name); } } } private Row getParentRow(int level) { Row parent = stack.isEmpty() ? null : stack.getLast(); while (!stack.isEmpty()) { if (parent != null && (parent.level < level)) { break; } stack.removeLast(); parent = stack.isEmpty() ? null : stack.getLast(); } return parent; } private int startIndex(String line) { int N = line.length(); for (int i = 0; i < N; i++) { char c = line.charAt(i); if (c != ' ') { return i; } } return -1; } public interface PersistenceCallback { Long onServiceComplete(String orgName, Long regCode); void onProcedureComplete(String name, Long regCode, long orgId); } final static class Row { final int level; final long id; Row(int level, long id) { this.level = level; this.id = id; } } }