/*
* 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 cli_fmw.main.DirectoryItemReplacedException;
import cli_fmw.utils.Selector;
import framework.beans.directory.DirectoryBeanRemote;
import framework.beans.directory.DirectoryItemDetails;
import framework.beans.directory.DirectoryItemRecursiveDetails;
import framework.beans.directory.RecursiveLazy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
*
* @param <BEAN> l
* @param <ITEM>
* @author axe
*/
abstract public class DirectoryRecursive<
BEAN extends DirectoryBeanRemote<?>,
ITEM extends DirectoryItemRecursive<ITEM, ?>
>extends DirectoryMagic<BEAN, ITEM>{
protected DirectoryRecursive(String beanName)
throws ClipsException {
super(beanName);
}
@Override
public ITEM getItemFromID(int id) throws DirectoryItemNotFoundException {
ITEM found = null;
found = super.getItemFromID(id);
if (found != null) {
return found;
}else if (this instanceof DirectoryRecursiveLazy) {
return null;
} else {
throw new DirectoryItemNotFoundException("Элемент справочника \'" + getDirectoryTitle() + "\' № " + id + " не найден");
}
/* Selector<ITEMCLASS> ii = getItems();
for (int i = 0; i < ii.size(); i++) {
ITEMCLASS item = ii.get(i);
found = item.getItemFromID(id);
if (found != null) {
return found;
}
}*/
}
@Override
protected void load() throws ClipsException {
try {
List<? extends DirectoryItemDetails> detail = getBean().get().getDirectory();
ArrayList<ITEM> newItems = new ArrayList<ITEM>(detail.size() + 20);
for (DirectoryItemDetails item : detail) {
ITEM tmp = createFromLoadedDetails(item);
newItems.add(tmp);
tmp.setDirectory(this);
}
setDirectoryIndex(newItems);
ArrayList<ITEM> rootlist = buildTree(newItems);
for (ITEM directoryItemRecursive : rootlist) {
fastAddLoadedItem(directoryItemRecursive);
}
ITEM itemNull = createNullItem();
if (itemNull != null) {
addLoadedItem(itemNull);
}
sort();
} catch (Exception ex) {
getBean().clear();
throw new ClipsException("Ошибка при загрузке справочника '" +
getDirectoryTitle() + "'", ex);
}
}
/**
* Строит дерево из переданных элементов.
* @param newItems
* @return
* @throws cli_fmw.main.ClipsException
*/
@SuppressWarnings("unchecked")
ArrayList<ITEM> buildTree(ArrayList<ITEM> newItems) throws ClipsException {
ArrayList<ITEM> sortedItem = new ArrayList<ITEM>(newItems);
Collections.sort(sortedItem);
ArrayList<ITEM> rootlist = new ArrayList<ITEM>();
for (int i = 0; i < sortedItem.size(); i++) {
ITEM item = sortedItem.get(i);
int parentid = item.getParentID();
if (parentid == 0) {
rootlist.add(item);
} else {
ITEM parent = findById(newItems, parentid);
//int newParentIdx = Collections.binarySearch(newItems, parentid, intCmp);
//if (newParentIdx < 0 || newParentIdx >= newItems.size() || newItems.get(newParentIdx).getID() != parentid) {
if (parent == null) {
throw new ClipsException("Нарушена структура справочника " + getDirectoryTitle());
}
parent.fastAddLoadedItem(item);
}
}
return rootlist;
}
/**
* Вызывается перед созданием дочернего элемента справочника,
* для возможной предварительной модификации загруженных деталей
* @param parent родительский элемент
* @param loaded загруженныен детали дочернего элемента
*/
protected void prebuildNodeModification(ITEM parent, DirectoryItemRecursiveDetails loaded) {
}
@Override
public DirectoryItemRO[] toArray() throws ClipsException {
return toArray(true, false);
}
@Override
public DirectoryItemRO[] toArray(boolean withNull) throws ClipsException {
return toArray(withNull, false);
}
public DirectoryItemRO[] toArray(boolean withNull, boolean recursive) throws ClipsException {
List<DirectoryItemRO> visible = new LinkedList<DirectoryItemRO>();
Selector<ITEM> it = getItems();
for(int i=0; i< it.size(); i++) {
if(recursive) {
fillList(visible, it.get(i), withNull);
} else {
ITEM item = it.get(i);
if(item.getID() != 0 || withNull) {
visible.add(item);
}
}
}
DirectoryItemRO[] array = new DirectoryItemRO[visible.size()];
visible.toArray(array);
return array;
}
@Override
public ITEM[] toArray(ITEM[] array) throws ClipsException {
return toArray(array, true, false);
}
@Override
public ITEM[] toArray(ITEM[] array, boolean withNull) throws ClipsException {
return toArray(array, withNull, false);
}
public ITEM[] toArray(ITEM[] array, boolean withNull, boolean recursive) throws ClipsException {
List<DirectoryItemRO> visible = new LinkedList<DirectoryItemRO>();
Selector<ITEM> it = getItems();
for(int i=0; i< it.size(); i++) {
if(recursive) {
fillList(visible, it.get(i), withNull);
} else {
ITEM item = it.get(i);
if(item.getID() != 0 || withNull) {
visible.add(item);
}
}
}
visible.toArray(array);
return array;
}
private void fillList(List<DirectoryItemRO> out, ITEM parent, boolean withNull) throws ClipsException {
if(!withNull && parent.getID() == 0) {
return;
}
out.add(parent);
Selector<ITEM> it = parent.getItems();
for(int i=0; i< it.size(); i++) {
fillList(out, it.get(i), withNull);
}
}
}