📄 tablecomponent.java
字号:
/*
* ====================================================================
* This software is subject to the terms of the Common Public License
* Agreement, available at the following URL:
* http://www.opensource.org/licenses/cpl.html .
* Copyright (C) 2003-2004 TONBELLER AG.
* All Rights Reserved.
* You must accept the terms of that agreement to use this software.
* ====================================================================
*
*
*/
package com.tonbeller.jpivot.table;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import com.tonbeller.jpivot.core.ModelChangeEvent;
import com.tonbeller.jpivot.core.ModelChangeListener;
import com.tonbeller.jpivot.olap.model.Axis;
import com.tonbeller.jpivot.olap.model.Cell;
import com.tonbeller.jpivot.olap.model.Member;
import com.tonbeller.jpivot.olap.model.OlapModel;
import com.tonbeller.jpivot.olap.model.Position;
import com.tonbeller.jpivot.olap.model.Result;
import com.tonbeller.jpivot.olap.navi.ClickableExtension;
import com.tonbeller.jpivot.table.span.PropertyConfig;
import com.tonbeller.tbutils.res.Resources;
import com.tonbeller.wcf.component.Component;
import com.tonbeller.wcf.component.ComponentSupport;
import com.tonbeller.wcf.controller.RequestContext;
import com.tonbeller.wcf.controller.RequestListener;
import com.tonbeller.wcf.utils.XmlUtils;
/**
* Contains a reference to the olap data plus additional gui settings.
* Renders the pivot table
*/
public class TableComponent extends ComponentSupport implements ModelChangeListener {
private static Logger logger = Logger.getLogger(TableComponent.class);
// configurable options from config.xml
CellBuilder cellBuilder;
CornerBuilder cornerBuilder;
SlicerBuilder slicerBuilder;
RowAxisBuilder rowAxisBuilder;
ColumnAxisBuilder columnAxisBuilder;
Resources resources;
// extensions, map for scripting, list for ordered initializing
List extensionList = new ArrayList();
Map extensionMap = new HashMap();
// initialized from tag
OlapModel olapModel;
Document document;
/** valid between startBuild() and stopBuild() */
Result result;
/** valid between startBuild() and stopBuild() */
Iterator cellIterator;
/** valid between startBuild() and stopBuild() */
int dimCount;
/** valid between startBuild() and stopBuild() */
Element rootElement;
public TableComponent(String id, Component parent) {
super(id, parent);
}
public TableComponent(String id, Component parent, OlapModel newOlapModel) {
super(id, parent);
logger.info("TableComponent");
this.olapModel = newOlapModel;
olapModel.addModelChangeListener(this);
}
/**
* for instantiation via reflection api.
* @see #setOlapModel
*/
public TableComponent() {
super(null, null);
}
public void setOlapModel(OlapModel newOlapModel) {
logger.info("setOlapModel");
if (olapModel != null)
olapModel.removeModelChangeListener(this);
olapModel = newOlapModel;
olapModel.addModelChangeListener(this);
}
/**
* deferred ctor called once by the creating tag
*/
public void initialize(RequestContext context) throws Exception {
logger.info("initialize");
super.initialize(context);
resources = context.getResources(TableComponent.class);
for (Iterator it = extensionList.iterator(); it.hasNext();)
((TableComponentExtension) it.next()).initialize(context, this);
columnAxisBuilder.initialize(context, this);
rowAxisBuilder.initialize(context, this);
cellBuilder.initialize(context, this);
cornerBuilder.initialize(context, this);
slicerBuilder.initialize(context, this);
}
/**
* deferred ctor called once by the creating tag
*/
public void destroy(HttpSession session) throws Exception {
logger.info("destroy");
slicerBuilder.destroy(session);
cornerBuilder.destroy(session);
cellBuilder.destroy(session);
rowAxisBuilder.destroy(session);
columnAxisBuilder.destroy(session);
for (Iterator it = extensionList.iterator(); it.hasNext();)
((TableComponentExtension) it.next()).destroy(session);
super.destroy(session);
}
public Object getBookmarkState(int levelOfDetail) {
logger.info("getBookmarkState");
Map map = (Map) super.getBookmarkState(levelOfDetail);
map.put("slicerBuilder", slicerBuilder.getBookmarkState(levelOfDetail));
map.put("cornerBuilder", cornerBuilder.getBookmarkState(levelOfDetail));
map.put("cellBuilder", cellBuilder.getBookmarkState(levelOfDetail));
map.put("rowAxisBuilder", rowAxisBuilder.getBookmarkState(levelOfDetail));
map.put("columnAxisBuilder", columnAxisBuilder.getBookmarkState(levelOfDetail));
for (Iterator it = extensionList.iterator(); it.hasNext();) {
TableComponentExtension tce = (TableComponentExtension) it.next();
map.put(tce.getId(), tce.getBookmarkState(levelOfDetail));
}
return map;
}
public void setBookmarkState(Object state) {
if (state == null)
return;
logger.info("setBookmarkState");
super.setBookmarkState(state);
Map map = (Map) state;
slicerBuilder.setBookmarkState(map.get("slicerBuilder"));
cornerBuilder.setBookmarkState(map.get("cornerBuilder"));
cellBuilder.setBookmarkState(map.get("cellBuilder"));
rowAxisBuilder.setBookmarkState(map.get("rowAxisBuilder"));
columnAxisBuilder.setBookmarkState(map.get("columnAxisBuilder"));
for (Iterator it = extensionList.iterator(); it.hasNext();) {
TableComponentExtension tce = (TableComponentExtension) it.next();
tce.setBookmarkState(map.get(tce.getId()));
}
}
public Iterator clickableIterator() {
ClickableExtension ce = (ClickableExtension) olapModel.getExtension(ClickableExtension.ID);
if (ce == null)
return Collections.EMPTY_LIST.iterator();
return ce.getClickables().iterator();
}
public void request(RequestContext context) throws Exception {
super.request(context);
for (Iterator it = clickableIterator(); it.hasNext();)
((RequestListener)it.next()).request(context);
}
/**
* notifies PartBuilders that a new DOM will be created
*/
private void startBuild(RequestContext context) {
logger.info("enter startBuild");
columnAxisBuilder.startBuild(context);
rowAxisBuilder.startBuild(context);
cellBuilder.startBuild(context);
cornerBuilder.startBuild(context);
slicerBuilder.startBuild(context);
for (Iterator it = extensionList.iterator(); it.hasNext();)
((TableComponentExtension) it.next()).startBuild(context);
for (Iterator it = clickableIterator(); it.hasNext();)
((ClickableMember) it.next()).startRendering(context, this);
logger.info("leave startBuild");
}
/**
* notifies PartBuilders that a new DOM has been created
*/
private void stopBuild() {
logger.info("enter stopBuild");
for (Iterator it = extensionList.iterator(); it.hasNext();)
((TableComponentExtension) it.next()).stopBuild();
slicerBuilder.stopBuild();
cornerBuilder.stopBuild();
cellBuilder.stopBuild();
rowAxisBuilder.stopBuild();
columnAxisBuilder.stopBuild();
for (Iterator it = clickableIterator(); it.hasNext();)
((ClickableMember) it.next()).stopRendering();
// reduce memory usage
result = null;
cellIterator = null;
logger.info("leave stopBuild");
}
/**
* main entry point
*/
public Document render(RequestContext context) throws Exception {
logger.info("render");
if (document == null) {
logger.info("creating document");
long t1 = System.currentTimeMillis();
document = XmlUtils.createDocument();
Element elem = render2(context);
document.appendChild(elem);
if (logger.isInfoEnabled()) {
long t2 = System.currentTimeMillis();
logger.info("Rendering of Table took " + (t2 - t1) + " millisec");
}
}
return document;
}
protected Result updateOlapModel() throws Exception {
return olapModel.getResult();
}
private Element render2(RequestContext context) throws Exception {
logger.info("render2");
this.result = updateOlapModel();
this.cellIterator = result.getCells().iterator();
this.dimCount = result.getAxes().length;
rootElement = document.createElement("mdxtable");
Element head = append("head", rootElement);
Element body = append("body", rootElement);
startBuild(context);
switch (dimCount) {
case 0 :
logger.info("0-dim data");
buildRows0Dim(body);
break;
case 1 :
logger.info("1-dim data");
buildColumns1Dim(head);
buildRows1Dim(body);
break;
case 2 :
logger.info("2-dim data");
buildColumns2Dim(head);
buildRows2Dim(body);
break;
default :
logger.error("more than 2 dimensions");
throw new IllegalArgumentException("TableRenderer requires 0, 1 or 2 dimensional result");
}
rootElement.appendChild(buildSlicer());
stopBuild();
return rootElement;
}
private Element buildSlicer() {
logger.info("buildSlicer");
Element slicer = elem("slicer");
Iterator pi = getResult().getSlicer().getPositions().iterator();
while (pi.hasNext()) {
Position p = (Position) pi.next();
Member[] members = p.getMembers();
for (int i = 0; i < members.length; i++) {
Element e = slicerBuilder.build(members[i]);
slicer.appendChild(e);
}
}
return slicer;
}
/* ---------------------- 0 dim ------------------------------- */
private void buildRows0Dim(Element parent) {
logger.info("buildRows0Dim");
// if result is empty, dont show anything
if (!cellIterator.hasNext())
return;
Element row = append("row", parent);
Cell cell = (Cell) cellIterator.next();
Element cellElem = cellBuilder.build(cell, true);
row.appendChild(cellElem);
}
/* ---------------------- 1 dim ------------------------------- */
private void buildRows1Dim(Element parent) {
logger.info("buildRows1Dim");
Element row = append("row", parent);
buildCells(row, false);
}
private void buildColumns1Dim(Element parent) {
logger.info("buildColumns1Dim");
final int N = columnAxisBuilder.getRowCount();
for (int i = 0; i < N; i++) {
Element row = append("row", parent);
columnAxisBuilder.buildRow(row, i);
}
}
/* ---------------------- 2 dim ------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -