package com.bagri.core.server.api.impl; import static com.bagri.support.util.FileUtils.def_encoding; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.bagri.core.DataKey; import com.bagri.core.api.BagriException; import com.bagri.core.model.Data; import com.bagri.core.model.Element; import com.bagri.core.model.Elements; import com.bagri.core.model.Path; import com.bagri.core.server.api.ModelManagement; public abstract class ContentBuilderBase<C> { protected final Logger logger = LoggerFactory.getLogger(getClass()); protected ModelManagement model; /** * * @param model the model management component. Used to search/add model paths. */ protected ContentBuilderBase(ModelManagement model) { this.model = model; } /** * {@inheritDoc} */ public abstract C buildContent(Collection<Data> elements) throws BagriException; /** * {@inheritDoc} */ public C buildContent(Map<DataKey, Elements> elements) throws BagriException { Collection<Data> dataList = buildDataList(elements); return buildContent(dataList); } /** * {@inheritDoc} */ public InputStream buildStream(Map<DataKey, Elements> elements) throws BagriException { Collection<Data> dataList = buildDataList(elements); return buildStream(dataList); } /** * {@inheritDoc} */ public InputStream buildStream(Collection<Data> elements) throws BagriException { C content = buildContent(elements); if (content != null) { try { return new ByteArrayInputStream(((String) content).getBytes(def_encoding)); } catch (UnsupportedEncodingException ex) { throw new BagriException(ex, BagriException.ecInOut); } } return null; } protected Collection<Data> buildDataList(Map<DataKey, Elements> elements) { logger.trace("buildDataList; got elements: {}", elements); Map<Element, Data> dataMap = new HashMap<>(); List<Data> dataList = new ArrayList<>(elements.size()*2); // here the source elements contain elements with values only // we should enrich the collection with intermediate parents for (Map.Entry<DataKey, Elements> entry: elements.entrySet()) { int pathId = entry.getKey().getPathId(); Path path = model.getPath(pathId); if (path == null) { logger.info("buildDataSet; can't get path for pathId: {}", pathId); continue; } for (Element element: entry.getValue().getElements()) { int parentId = path.getParentId(); Data data = new Data(path, element); dataMap.put(element, data); dataList.add(data); Element elt = element; while (parentId > 0) { //1 int[] position = elt.getPosition(); elt = new Element(Arrays.copyOf(position, position.length - 1), null); if (dataMap.containsKey(elt)) { break; } else { Path parent = model.getPath(parentId); if (parent != null) { data = new Data(parent, elt); dataMap.put(elt, data); dataList.add(data); parentId = parent.getParentId(); } } } } } Collections.sort(dataList); logger.trace("buildDataList; returning: {}", dataList); return dataList; } public static Map<DataKey, Elements> dataToElements(List<Data> data) { long docKey = 0; Map<DataKey, Elements> result = new HashMap<>(); for (Data xdm: data) { if (xdm.getValue() != null) { DataKey xdk = new DataKey(docKey, xdm.getPathId()); Elements xdes = result.get(xdk); if (xdes == null) { xdes = new Elements(xdk.getPathId(), null); result.put(xdk, xdes); } xdes.addElement(xdm.getElement()); } } return result; } }