ru.codeinside.adm.parser.ServiceFixtureParser.java Source code

Java tutorial

Introduction

Here is the source code for ru.codeinside.adm.parser.ServiceFixtureParser.java

Source

/*
 * 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;
        }
    }

}