Package cli_fmw.delegate.directory

Source Code of cli_fmw.delegate.directory.DirectoryRecursiveLazy

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

import cli_fmw.main.ClipsException;
import cli_fmw.main.DirectoryItemNotFoundException;
import framework.beans.directory.DirectoryItemRecursiveDetails;
import framework.beans.directory.RecursiveLazy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
*
* @author petr
* @param <BEAN>
* @param <ITEM>
*/
abstract public class DirectoryRecursiveLazy
    <BEAN extends RecursiveLazy<? extends DirectoryItemRecursiveDetails>,
    ITEM extends DirectoryItemRecursiveLazy<ITEM, ?>>
        extends DirectoryRecursive<BEAN, ITEM> {

    /**Indexes of loaded items by create path*/
    private int[] pathIDs = new int[0];

    protected DirectoryRecursiveLazy(String beanName)
            throws ClipsException {
        super(beanName);
    }

    @Override
    public ITEM getItemFromID(int id) throws DirectoryItemNotFoundException {
        ITEM found = super.getItemFromID(id);
        if (found != null){
            return found;
        }else{
            try {
                List<? extends DirectoryItemRecursiveDetails> path = getBean().get().getPath(id);
                List<ITEM> itemList = createPath(path);
                return itemList.get(itemList.size()-1);
            } catch (Exception ex) {
                ex.printStackTrace();
                clearBean();
                throw new DirectoryItemNotFoundException("Элемент справочника '" + getDirectoryTitle() + "' № " + id + " не найден");
            }
        }
    }
   
    /**
     * превращает цепочку деталей в цепочку итемов, недостающие итемы создаёт
     * @param path цепочка от корня до итема
     */
    private List<ITEM> createPath(List<? extends DirectoryItemRecursiveDetails> path) throws ClipsException{
        ITEM parent = null;
        ArrayList<ITEM> itemList = new ArrayList<ITEM>();

        //relength of loaded ids array
//        int l = pathIDs.length;
//        pathIDs = Arrays.copyOf(pathIDs, l + path.size());

        for (int i = 0; i < path.size(); i++) {
            DirectoryItemRecursiveDetails d = path.get(i);
      ITEM      newItem = findIDX(d.getId());
            if (newItem == null) {
        newItem = createFromLoadedDetails(d);
                itemList.add(newItem);

                //add to loaded
//                pathIDs[l++] = d.id;

                ITEM item = itemList.get(i);
                if (parent != null){
                    parent.addLoadedItem(item);
                }else{
                    if (!isItemLoaded(item.getID())) {
                        this.addLoadedItem(itemList.get(i));
                    }else{
//                        todo подумать надо ли это
//                        ITEMCLASS findIDX = findIDX(item.getID());
//                        findIDX.setDetails(item.getDetails());
                    }
                }
            }else {
        itemList.add(newItem);
      }
            parent = newItem;
        }
        Arrays.sort(pathIDs);
        return itemList;
    }
   
    /**
     * Создаёт итем по деталям
     * @param details
     * @return
     */
    final ITEM createItemByDetails(DirectoryItemRecursiveDetails details){
        ITEM item = createFromLoadedDetails(details);
        item.setDirectory(this);
        return item;
    }

    @Override
    public boolean isItemLoaded(int id) {
//        if (Arrays.binarySearch(pathIDs, id) < 0){
            return super.isItemLoaded(id);
//        }else{
//            return true;
//        }
    }

    /**
     * Проверяет упорядоченность элементов по идентификатьору
     * @param items должен содержать не менее 2х элементов
     * @return истина если порядок соблюдается
     */
    private boolean checkOrder(ArrayList<ITEM> items){
        for (int i = 1; i < items.size(); i++) {
            if (items.get(i-1).getID() - items.get(i).getID() >= 0){
                return false;
            }
        }
        return true;
    }

    /**
     * Добавляет толпой массив итемов
     * @param items
     */
    protected void addIdxItems(ArrayList<ITEM> items) {
        if (items != null && !items.isEmpty()){
            if (!checkOrder(items)){
                Collections.sort(items, idComparator);
            }
            //найти место для первого элемента
            Map<Integer, List<ITEM>> parentsMap = new HashMap<Integer, List<ITEM>>();
            int idx = Collections.binarySearch(idxItems, items.get(0), idComparator);
            int dirItemIdx = 0;
            int newItemIdx = 0;
            if (idx < 0) {
                dirItemIdx = (-idx) - 1;
            } else {
                newItemIdx++;
                dirItemIdx = idx + 1;
            }
            while (newItemIdx < items.size()) {
                int compare = 1;
                if (dirItemIdx >= idxItems.size()){//если достигнута граница основного массива то пишем ему в конец
                    dirItemIdx = idxItems.size();
                }else{
                    compare = idComparator.compare(idxItems.get(dirItemIdx), items.get(newItemIdx));
                }
                if (compare == 0) {//дропнуть повтор
                    newItemIdx++;
                } else if (compare < 0) {//увеличит индекс у первого массива
                    dirItemIdx++;
                } else {//добавить текущий элемент из нового массива и увеличить оба индекса
                    ITEM current = items.get(newItemIdx);
                    idxItems.add(dirItemIdx, current);
                    newItemIdx++;
                    dirItemIdx++;
                    int parentId = current.getParentID();
                    if (parentId > 0) {
                        if (parentsMap.get(parentId) == null) {
                            parentsMap.put(parentId, new ArrayList<ITEM>());
                        }
                        int point = Collections.binarySearch(parentsMap.get(parentId), current);
                        if (point < 0){
                            parentsMap.get(parentId).add(-point-1, current);
                        }
                    }
                }
            }

            for (Integer parentId : parentsMap.keySet()) {
                ITEM parent = findIDX(parentId);
                if (parent != null){
                    parent.fastAddItemList(parentsMap.get(parentId));
                }
            }
        }
    }
}
TOP

Related Classes of cli_fmw.delegate.directory.DirectoryRecursiveLazy

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.