Package cli_fmw.directory.editors.kladr

Source Code of cli_fmw.directory.editors.kladr.DBaseParser

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package cli_fmw.directory.editors.kladr;

import cli_fmw.delegate.directory.complex.DirectoryKladr;
import cli_fmw.delegate.directory.complex.DirectoryKladrType;
import cli_fmw.delegate.directory.complex.DirectoryKladrTypeItem;
import cli_fmw.delegate.directory.complex.DirectoryLocator;
import cli_fmw.main.ClipsException;
import cli_fmw.utils.SelectorEditableExceptional;
import framework.beans.address.KladrCode;
import framework.beans.address.KladrItem;
import framework.beans.address.entities.AddressObjectTypeDetails;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.xBaseJ.micro.DBF;
import org.xBaseJ.micro.fields.CharField;
import org.xBaseJ.micro.xBaseJException;

/**
* Разбирает адрес в формате КЛАДРАа и заполняет структуру для
* загрузки его в базу
* @author petr
*/
public class DBaseParser {

    public static final String ALTNAMES = "ALTNAMES.DBF";
    public static final String DOMA = "DOMA.DBF";
    public static final String FLAT = "FLAT.DBF";
    public static final String KLADR = "KLADR.DBF";
    public static final String SOCRBASE = "SOCRBASE.DBF";
    public static final String STREET = "STREET.DBF";
    /**6*/
    private static final int code_section_count = KladrCode.MAX_LENGHT;//начинаем с 1, вопросы к авторам кладра
    private static final int f_type_level = 0;
    private static final int f_type_abbriv = 1;
    private static final int f_type_title = 2;
    private static final int f_type_code = 3;
    private static final int f_title = 0;
    private static final int f_abbriv = 1;
    private static final int f_code = 2;
    private static final int f_index = 3;
    private static final int f_codeIfns = 4;
    private static final int f_localCodeIfns = 5;
    private static final int f_okato = 6;
    private static final int f_status = 7;

    //for fucking crazy humanoids who born file "doma.dbf"
    private static final int f_doma_title = 0;
    private static final int f_doma_corp = 1;
    private static final int f_doma_abbriv = 2;
    private static final int f_doma_code = 3;
    private static final int f_doma_index = 4;
    private static final int f_doma_codeIfns = 5;
    private static final int f_doma_localCodeIfns = 6;
    private static final int f_doma_okato = 7;

    //for altnames
    private static final int f_old_code = 0;
    private static final int f_new_code = 1;
    private static final int f_level = 2;
    private File db;
    private File altnames = null;
    private File doma = null;
    private File flat = null;
    private File kladr = null;
    private File socrbase = null;
    private File street = null;
    private ArrayList<AddressObjectTypeDetails> types;
    private ArrayList<KladrItem> addressRoots;
    /** Map<ladr code, directory item> */
    private Map<KladrCode, KladrItem> items;
    /** Map<needing paren code, List<directory item>>*/
    private Map<KladrCode, Set<KladrItem>> notAddedYet;
    /** Map<Abbrivation+Level, directory type item>*/
    private Map<String, DirectoryKladrTypeItem> kladrTypes;
    /** Map<old kladr code, new kladr code>*/
    private Map<KladrCode, KladrCode> altNames;
    private DirectoryKladrType directoryKladrType;
    private DirectoryKladr directoryKladr;

    /**
     *
     * @param db
     * @throws java.io.IOException
     */
    public DBaseParser(File db) throws ClipsException {
        this.db = db;
        if (db.isDirectory()) {
            File[] filesInDir = db.listFiles();
            for (File f : filesInDir) {
                System.out.println("file: " + f.getName());
                if (f.isFile()) {
                    if (f.getName().equalsIgnoreCase(DBaseParser.ALTNAMES)) {
                        altnames = f;
                    } else if (f.getName().equalsIgnoreCase(DBaseParser.DOMA)) {
                        doma = f;
                    } else if (f.getName().equalsIgnoreCase(DBaseParser.FLAT)) {
                        flat = f;
                    } else if (f.getName().equalsIgnoreCase(DBaseParser.KLADR)) {
                        kladr = f;
                    } else if (f.getName().equalsIgnoreCase(DBaseParser.SOCRBASE)) {
                        socrbase = f;
                    } else if (f.getName().equalsIgnoreCase(DBaseParser.STREET)) {
                        street = f;
                    }
                }
            }
        }

        if (altnames == null) {
            throw new ClipsException("Не найден файл" + DBaseParser.ALTNAMES);
        }
        if (doma == null) {
            throw new ClipsException("Не найден файл" + DBaseParser.DOMA);
        }
        if (flat == null) {
            throw new ClipsException("Не найден файл" + DBaseParser.FLAT);
        }
        if (kladr == null) {
            throw new ClipsException("Не найден файл" + DBaseParser.KLADR);
        }
        if (socrbase == null) {
            throw new ClipsException("Не найден файл" + DBaseParser.SOCRBASE);
        }
        if (street == null) {
            throw new ClipsException("Не найден файл" + DBaseParser.STREET);
        }

        init();
        remapTypes();

        System.out.println("DBASEPARSER: dBase parser was created");

//        DirectoryMKB10 mKB10 = DirectoryLocator.getDirectory(DirectoryMKB10.class, false);
//        DirectoryDialogDefaultCombo dddc = new DirectoryDialogDefaultCombo(MainWindow.mainWindow, mKB10);
//        dddc.setVisible(true);
//        throw new ClipsException();
    }

    private void init() {
        //initializing
        types = new ArrayList<AddressObjectTypeDetails>();
        items = new TreeMap<KladrCode, KladrItem>();
        notAddedYet = new TreeMap<KladrCode, Set<KladrItem>>();
        addressRoots = new ArrayList<KladrItem>();
    }

    /**
     * запускает разбор файлов КЛАДРа
     * @throws cli_fmw.main.ClipsException
     */
    public void run() throws ClipsException {
        System.out.println("DBASEPARSER: parsing was started");
        directoryKladr = (DirectoryKladr) DirectoryLocator.getDirectory(DirectoryKladr.class, false);
        directoryKladrType = (DirectoryKladrType) DirectoryLocator.getDirectory(DirectoryKladrType.class, false);

        parseSocrBase(socrbase);
        directoryKladrType.syncDirectory(types);
        remapTypes();

        parseAltNames(altnames);

        parseKladr(kladr);
        parseKladr(street);
        parseDoma(doma);

//        while(MessageBox.showConfirmYesNo(MessageBox.C_OVERWRITE_FILE, "Загрузить КЛАДР") == MessageBox.ANSWER_YES){
//            try{
        directoryKladr.syncDirectory(addressRoots, altNames);
//            }catch(Exception ex){
//                ex.printStackTrace();
//            }
//        }
        System.out.println("DBASEPARSER: parsing was canceled");
    }

    private void parseAltNames(File altnames) throws ClipsException {
        DBF dbf = createDBF(altnames);
        CharField[] fields = getFields(dbf);
        int recordCount = dbf.getRecordCount();
        String s = null;
        int c = 0;
        for (c = 1; c <= recordCount; c++) {
            try {
                dbf.read();
                KladrCode oldCode = null;
                KladrCode newCode = null;
                for (int i = 0; i < fields.length; i++) {
                    s = new String(fields[i].get().trim());
                    switch (i) {
                        case f_old_code:
                            oldCode = new KladrCode(parseCode(s));
                            break;
                        case f_new_code:
                            newCode = new KladrCode(parseCode(s));
                            break;
                        case f_level: {
                            //do nothing
                        }
                    }
                }
                altNames.put(newCode, oldCode);

            } catch (xBaseJException ex) {
                throw new ClipsException("Ошибка при чтении данных из файла " + dbf.getName(), ex);
            } catch (IOException ex) {
                throw new ClipsException("Не найден файл " + dbf.getName(), ex);
            }
        }
    }

    /**
     * разбирает таблицу сокращений
     * @param dbf
     */
    private void parseSocrBase(File f) throws ClipsException {
        DBF dbf = createDBF(f);
        CharField[] fields = getFields(dbf);
        int recordCount = dbf.getRecordCount();
        String s = null;
        int c = 0;
        for (c = 1; c <= recordCount; c++) {
            try {
                dbf.read();
                AddressObjectTypeDetails type = new AddressObjectTypeDetails();
                for (int i = 0; i < fields.length; i++) {
                    s = new String(fields[i].get().trim());
                    switch (i) {
                        case f_type_level:
                            type.level = Integer.parseInt(s);
                            break;
                        case f_type_abbriv:
                            type.abbrivation = s;
                            break;
                        case f_type_title:
                            type.title = s;
                            break;
                        case f_type_code:
                            type.code = Integer.parseInt(s);
                            break;
                    }
                }
                types.add(type);

            } catch (xBaseJException ex) {
                throw new ClipsException("Ошибка при чтении данных из файла " + dbf.getName(), ex);
            } catch (IOException ex) {
                throw new ClipsException("Не найден файл " + dbf.getName(), ex);
            }
        }

//        for (AddressObjectTypeDetails type : types) {
//            System.out.println(type.title + "     " + type.abbrivation + "     " + type.level + "     " + type.code);
//        }
    }

    /**
     * for fucking crazy humanoids who born file "doma.dbf"
     * @param dbf
     */
    private void parseDoma(File f) throws ClipsException {
        types = new ArrayList<AddressObjectTypeDetails>();
        DBF dbf = createDBF(f);
        CharField[] fields = getFields(dbf);
        int recordCount = dbf.getRecordCount();
        String s = null;
        String code = null;
        String abbr = null;
        int c = 0;
        for (c = 1; c < recordCount; c++) {
            try {
                dbf.read();
                KladrItem item = new KladrItem();
                for (int i = 0; i < fields.length; i++) {
                    s = new String(fields[i].get().trim());
//                    System.out.print(s + "     ");
                    switch (i) {
                        case f_doma_title:
                            item.title = s;
                            break;
                        case f_doma_corp:
                            item.title += s;
                        case f_doma_abbriv:
                            abbr = s;
                            break;
                        case f_doma_code:
                            code = s;
                            break;
                        case f_doma_index:
                            item.postIndex = s.isEmpty() ? 0 : Integer.parseInt(s);
                            break;
                        case f_doma_codeIfns:
                            item.ifnsCode = s.isEmpty() ? 0 : Integer.parseInt(s);
                            break;
                        case f_doma_localCodeIfns:
                            item.ifnsLocalCode = s.isEmpty() ? 0 : Integer.parseInt(s);
                            break;
                        case f_doma_okato:
                            item.okato = s.isEmpty() ? 0 : Long.parseLong(s);
                            break;
                    }
                }
                addKladrObject(code, abbr, item);
//                System.out.println();
                if (c % 1000 == 0) {
                    System.out.println("process " + c + " records");
                }
            } catch (xBaseJException ex) {
                throw new ClipsException("Ошибка при чтении данных из файла " + dbf.getName(), ex);
            } catch (IOException ex) {
                throw new ClipsException("Не найден файл " + dbf.getName(), ex);
            }
        }
    }

    /**
     * разбирает файл кладра
     * @param f файл должен быть таблицей в дБейс формате
     * @throws org.xBaseJ.micro.xBaseJException
     * @throws java.io.IOException
     */
    private void parseKladr(File f) throws ClipsException {
        DBF dbf = createDBF(f);
        CharField[] fields = getFields(dbf);
        int recordCount = dbf.getRecordCount();
        String s = null;
        String code = null;
        String abbr = null;
        int c = 0;
        for (c = 1; c <= recordCount; c++) {
            try {
                dbf.read();
                KladrItem item = new KladrItem();
                for (int i = 0; i < fields.length; i++) {
                    s = new String(fields[i].get().trim());
//                    System.out.print(s + "     ");
                    switch (i) {
                        case f_title:
                            item.title = s;
                            break;
                        case f_abbriv:
                            abbr = s;
                            break;
                        case f_code:
                            code = s;
                            break;
                        case f_index:
                            item.postIndex = s.isEmpty() ? 0 : Integer.parseInt(s);
                            break;
                        case f_codeIfns:
                            item.ifnsCode = s.isEmpty() ? 0 : Integer.parseInt(s);
                            break;
                        case f_localCodeIfns:
                            item.ifnsLocalCode = s.isEmpty() ? 0 : Integer.parseInt(s);
                            break;
                        case f_okato:
                            item.okato = s.isEmpty() ? 0 : Long.parseLong(s);
                            break;
                        case f_status:
                            //нах это поле
                            break;
                    }
                }
                addKladrObject(code, abbr, item);
//                System.out.println();
                if (c % 1000 == 0) {
                    System.out.println("process " + c + " records");
                }
            } catch (xBaseJException ex) {
                throw new ClipsException("Ошибка при чтении данных из файла " + f.getName(), ex);
            } catch (IOException ex) {
                throw new ClipsException("Не найден файл " + f.getName(), ex);
            }
        }

    }

    /**
     * создаёт дбф файл из данного
     * @param f
     * @return
     * @throws cli_fmw.main.ClipsException
     */
    private DBF createDBF(File f) throws ClipsException {
        String filename = f.getName();
        try {
            DBF dbf = new DBF(f.getAbsolutePath(), "cp866");
            System.out.println("DBASEPARSER: parse file '" + filename);
            return dbf;
        } catch (xBaseJException ex) {
            throw new ClipsException("Ошибка при чтении данных из файла " + filename, ex);
        } catch (IOException ex) {
            throw new ClipsException("Не найден файл " + filename, ex);
        }
    }

    /**
     * Вытаскивает поля из таблицы
     * @param dbf файл с таблицей
     * @return
     * @throws java.lang.ArrayIndexOutOfBoundsException
     * @throws org.xBaseJ.micro.xBaseJException
     */
    private CharField[] getFields(DBF dbf) throws ClipsException {
        try {
            int fieldCount = dbf.getFieldCount();
            System.out.println("DBASEPARSER: item count: " + dbf.getRecordCount());
            CharField[] fields = new CharField[fieldCount];
            for (int i = 1; i <= fieldCount; i++) {
                fields[i - 1] = (CharField) dbf.getField(i);
                String fieldName = fields[i - 1].getName();
                System.out.print(fieldName + "       ");
            }
            System.out.println();
            return fields;
        } catch (ArrayIndexOutOfBoundsException ex) {
            throw new ClipsException("Неверно определено количество полей в файле" + dbf.getName(), ex);
        } catch (xBaseJException ex) {
            throw new ClipsException("Ошибка при чтении данных из файла " + dbf.getName(), ex);
        }
    }

    /**
     * Разделяет код на составные части
     * @param code
     * @return массив с кодами конкретных уровней
     * @throws cli_fmw.main.ClipsException
     */
    private int[] parseCode(String code) throws ClipsException {
        int[] cc;
        int ln = code.length();
        if (ln != 13 & ln != 17 & ln != 19) {
            throw new ClipsException("Неверная длина кода КЛАДРа: " + ln);
        }
        try {//проверим код
            cc = KladrCode.parseCode(code);
        } catch (NumberFormatException ex) {
            throw new ClipsException("Неправильный формат кода КЛАДРа", ex);
        }
        return cc;
    }

    /**
     * определяет актуальность
     * @param code
     * @return истина если актуален
     */
    private boolean isActual(String code) throws ClipsException {
        try {
            if (code.length() == 19) {
                return true;//alwais actual
            }
            int pos = code.length() - 2;
            return Integer.parseInt(code.substring(pos, pos + 2)) == 0;//актуальность
        } catch (NumberFormatException ex) {
            throw new ClipsException("Неправильный формат кода КЛАДРа", ex);
        }
    }

    /**
     * добавляет данные об итеме в структуру отправляемую на сервер
     * @param code код КЛАДРа
     * @param abbr сокращение названия типа
     * @param item итем
     * @throws cli_fmw.main.ClipsException
     */
    private void addKladrObject(String code, String abbr, KladrItem item) throws ClipsException {

        int itemLevel = 0;

        int[] cc = parseCode(code);

        if (isActual(code)) {//только для актуальных
            if (cc[0] == 0) {
                throw new ClipsException("Неверный код объекта: " + code);
            }

            //определяем уровень и код
            item.kladrCode = new KladrCode(cc);
            //оставляем только код родителя
            for (int level = code_section_count - 1; level >= 0; level--) {
                if (cc[level] > 0) {
                    itemLevel = level + 1;
                    cc[level] = 0;
                    break;
                }
            }
            KladrCode parentCode = new KladrCode(cc);

            //set type by abbrivation and level
            DirectoryKladrTypeItem type = kladrTypes.get(abbr + itemLevel);
            if (type == null) {
                throw new ClipsException("Неизвестный тип адресуемого объекта (abbrivation: " + abbr + " level: " + itemLevel + "), обновите файл сокращений");
            }
            item.typeId = type.getID();

            Set<KladrItem> childrenFromMap = notAddedYet.get(item.kladrCode);    //add children from 'needParent' map
            if (childrenFromMap != null) {
                if (item.children == null) {
                    item.children = new ArrayList<KladrItem>();
                }
                item.children.addAll(childrenFromMap);
                notAddedYet.remove(item.kladrCode);   //and clear children list
            }

            items.put(item.kladrCode, item)//put into items

            if (itemLevel == 1) {    //root
                addressRoots.add(item); //add item into roots
            } else //only for children
                //find parent in map and add child into it
                KladrItem parent = items.get(parentCode);//find parent

                //if parent not created put item into 'needParent' map
                if (parent == null) {
                    if (notAddedYet.get(parentCode) == null) {
                        notAddedYet.put(parentCode, new HashSet<KladrItem>());
                    }
                    notAddedYet.get(parentCode).add(item);
                } else {//if parent was find
                    if (parent.children == null) {
                        parent.children = new ArrayList<KladrItem>();
                    }
                    parent.children.add(item);
                }

            }

        }
        return;

    }

    /**
     * загружает типы КЛАДРа из справочника в мап
     */
    private void remapTypes() throws ClipsException {
        directoryKladrType = (DirectoryKladrType) DirectoryLocator.getDirectory(DirectoryKladrType.class, true);
        kladrTypes = new HashMap<String, DirectoryKladrTypeItem>();
        SelectorEditableExceptional<DirectoryKladrTypeItem> see = directoryKladrType.getItems();
        for (int i = 0; i < see.size(); i++) {
            DirectoryKladrTypeItem type = see.get(i);
            kladrTypes.put(type.getAbbrivation() + type.getLevel(), type);
        }
    }
}
TOP

Related Classes of cli_fmw.directory.editors.kladr.DBaseParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.