📄 xmla_model.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.xmla;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java_cup.runtime.Symbol;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionBindingEvent;
import org.apache.log4j.Logger;
import com.tonbeller.jpivot.core.Extension;
import com.tonbeller.jpivot.core.ModelChangeEvent;
import com.tonbeller.jpivot.core.ModelChangeListener;
import com.tonbeller.jpivot.olap.mdxparse.Exp;
import com.tonbeller.jpivot.olap.mdxparse.Formula;
import com.tonbeller.jpivot.olap.mdxparse.FunCall;
import com.tonbeller.jpivot.olap.mdxparse.Lexer;
import com.tonbeller.jpivot.olap.mdxparse.Literal;
import com.tonbeller.jpivot.olap.mdxparse.ParsedQuery;
import com.tonbeller.jpivot.olap.mdxparse.parser;
import com.tonbeller.jpivot.olap.model.Dimension;
import com.tonbeller.jpivot.olap.model.Hierarchy;
import com.tonbeller.jpivot.olap.model.Level;
import com.tonbeller.jpivot.olap.model.Member;
import com.tonbeller.jpivot.olap.model.OlapDiscoverer;
import com.tonbeller.jpivot.olap.model.OlapException;
import com.tonbeller.jpivot.olap.model.OlapItem;
import com.tonbeller.jpivot.olap.model.OlapModel;
import com.tonbeller.jpivot.olap.model.Result;
import com.tonbeller.jpivot.olap.navi.SortRank;
import com.tonbeller.jpivot.olap.query.ExpBean;
import com.tonbeller.jpivot.olap.query.MdxOlapModel;
import com.tonbeller.jpivot.olap.query.PositionNodeBean;
import com.tonbeller.jpivot.olap.query.Quax;
import com.tonbeller.jpivot.olap.query.QuaxBean;
import com.tonbeller.jpivot.olap.query.QueryAdapter;
import com.tonbeller.jpivot.util.TreeNode;
/**
* Model for XMLA
*/
public class XMLA_Model extends MdxOlapModel implements OlapModel, QueryAdapter.QueryAdapterHolder {
static Logger logger = Logger.getLogger(XMLA_Model.class);
private String ID = null;
private String uri = null; //"http://TBNTSRV3/XML4A/msxisapi.dll";
private String user = null;
private String password = null;
private String catalog = null; //"Foodmart 2000";
private String dataSource = null; // "Provider=MSOLAP.2;Data Source=local";
private String mdxQuery;
private String currentMdx;
private ParsedQuery pQuery = null;
private XMLA_Result result = null;
private List aDimensions = new ArrayList();
private List aHierarchies = new ArrayList();
private List aLevels = new ArrayList();
private List aMeasures = new ArrayList();
private List aMembers = new ArrayList();
private XMLA_QueryAdapter queryAdapter = null;
private String cube = null; // save cube name
private boolean isNewCube = false;
private XMLA_SOAP soap = null;
private boolean isInitialized = false;
private Locale loc = null;
// Cell properties are encoded as FONT_SIZE values
private Map calcMeasurePropMap;
/** default constructor
*/
public XMLA_Model() {
//System.setProperty("http.proxyHost", "localhost"); // "proxy.tonbeller.com"
//System.setProperty("http.proxyPort", "80");
this.mdxQuery = null;
this.currentMdx = null;
addModelChangeListener(new ModelChangeListener() {
public void modelChanged(ModelChangeEvent e) {
result = null; // will force re-execution of query
}
public void structureChanged(ModelChangeEvent e) {
result = null; // will force re-execution of query
}
});
}
/**
*
* @see javax.servlet.http.HttpSessionBindingListener#valueBound(HttpSessionBindingEvent)
*/
public void initialize() throws OlapException {
logger.info(this);
boolean logInfo = logger.isInfoEnabled();
if (catalog == null)
throw new OlapException("XMLA Model requires catalog specification");
// do we have a special locale setting?
// if yes, promote it to the connection
loc = getLocale(); // Locale.GERMANY
if (loc != null) {
if (logInfo) {
String msg = "Locale language=" + loc.getLanguage() + " Country=" + loc.getCountry();
logger.info(msg);
}
}
if (dataSource != null && dataSource.length() > 0)
soap = new XMLA_SOAP(uri, user, password, dataSource);
else
// discover yourself
soap = new XMLA_SOAP(uri, user, password);
if (logInfo) {
List dsprops = soap.discoverDSProps();
for (Iterator iter = dsprops.iterator(); iter.hasNext();) {
OlapItem oi = (OlapItem) iter.next();
Map pmap = oi.getProperties();
logger.info("Property: " + oi.getName());
for (Iterator iterator = pmap.keySet().iterator(); iterator.hasNext();) {
Object keyo = iterator.next();
logger.info(keyo + "=" + pmap.get(keyo));
}
}
}
parse(mdxQuery);
queryAdapter = new XMLA_QueryAdapter(this);
XMLA_SortRank sortExt = (XMLA_SortRank) getExtension(SortRank.ID);
if (sortExt != null)
sortExt.reset();
isInitialized = true;
// as initialization is complete, notify extensions
Map extMap = getExtensions();
Collection extensions = extMap.values();
for (Iterator iter = extensions.iterator(); iter.hasNext();) {
Extension extension = (Extension) iter.next();
extension.modelInitialized();
}
initCubeMetaData();
isNewCube = false;
calcMeasurePropMap = new HashMap();
}
/**
* Sets the mdxQuery.
* @param mdxQuery The mdxQuery to set
*/
public void setMdxQuery(String mdxQuery) {
this.mdxQuery = mdxQuery;
this.currentMdx = mdxQuery.replace('\r', ' ');
if (logger.isInfoEnabled())
logger.info("setMdxQuery:" + mdxQuery);
}
/**
* Let Mondrian parse and execute the query
* @see com.tonbeller.jpivot.olap.model.OlapModel#getResult()
* @return Result of Query Execution
*/
public synchronized Result getResult() throws OlapException {
if (result != null)
return result;
if (!isInitialized) {
logger.fatal("Model not initialized");
throw new OlapException("Model not initialized");
}
// initialize cube meta data
if (isNewCube)
initCubeMetaData();
isNewCube = false;
queryAdapter.onExecute();
long lBefore = System.currentTimeMillis();
logger.debug(currentMdx);
XMLA_Result res = new XMLA_Result(this, soap, catalog, currentMdx);
long lTime = System.currentTimeMillis() - lBefore;
logger.debug("Time for executeQuery(ms)=" + lTime);
// no exception gotten
result = res;
queryAdapter.afterExecute(result);
return result;
}
//dsf
public synchronized Result getDrillResult() throws OlapException {
if (result != null)
return result;
if (!isInitialized) {
logger.fatal("Model not initialized");
throw new OlapException("Model not initialized");
}
// initialize cube meta data
if (isNewCube)
initCubeMetaData();
isNewCube = false;
// dsf : call onExecuteDrill
queryAdapter.onExecuteDrill();
long lBefore = System.currentTimeMillis();
logger.debug(currentMdx);
XMLA_Result res = new XMLA_Result(this, soap, catalog, currentMdx, true);
long lTime = System.currentTimeMillis() - lBefore;
logger.debug("Time for executeQuery(ms)=" + lTime);
// no exception gotten
result = res;
queryAdapter.afterExecute(result);
return result;
}
/**
* get the MDX for the user to edit
* @return current MDX statement
* @see com.tonbeller.jpivot.olap.query.MdxOlapModel#getCurrentMdx()
*/
public String getCurrentMdx() {
if (queryAdapter != null)
return queryAdapter.getCurrentMdx();
else
return this.mdxQuery;
}
/**
* set the mdx entered by the user.
* @task error handling: restore mdx in case of error
* @throws OlapException if the syntax is invalid
* @param mdxQuery
*/
public void setUserMdx(String mdxQuery) throws OlapException {
if (this.currentMdx.equals(mdxQuery))
return;
parse(mdxQuery);
this.mdxQuery = mdxQuery;
result = null;
queryAdapter = new XMLA_QueryAdapter(this);
XMLA_SortRank sortExt = (XMLA_SortRank) getExtension(SortRank.ID);
if (sortExt != null)
sortExt.reset();
if (logger.isInfoEnabled())
logger.info("setUserMdx =" + mdxQuery);
this.currentMdx = mdxQuery.replace('\r', ' ');
}
/**
* Returns the mdxQuery.
* @return String
*/
String getMdxQuery() {
return mdxQuery;
}
/**
* Sets the currentMdx.
* @param currentMdx The currentMdx to set
*/
void setCurrentMdx(String currentMdx) {
this.currentMdx = currentMdx.replaceAll("\r", "");
}
/**
*
* @see com.tonbeller.jpivot.olap.model.OlapModel#getDimensions()
*/
public Dimension[] getDimensions() {
return (Dimension[]) aDimensions.toArray(new Dimension[0]);
}
/**
* @see com.tonbeller.jpivot.olap.model.OlapModel#getMeasures()
*/
public Member[] getMeasures() {
return (Member[]) aMeasures.toArray(new Member[0]);
}
/**
* session terminated, closing connections etc
* @task close connection here
*/
public void destroy() {
super.destroy();
}
public Object getRootDecoree() {
return this;
}
/**
* lookup Dimension by unique name
* @param name
* @return Dimension
*/
XMLA_Dimension lookupDimByUName(String uName) {
for (Iterator iter = aDimensions.iterator(); iter.hasNext();) {
XMLA_Dimension dim = (XMLA_Dimension) iter.next();
if (dim.getUniqueName().equals(uName))
return dim;
}
return null;
}
/**
* lookup hierarchy by unique name
* @param name
* @return Hierarchy
*/
XMLA_Hierarchy lookupHierByUName(String uName) {
for (Iterator iter = aHierarchies.iterator(); iter.hasNext();) {
XMLA_Hierarchy hier = (XMLA_Hierarchy) iter.next();
if (hier.getUniqueName().equals(uName))
return hier;
}
return null;
}
/**
* lookup level by unique name
* @param name
* @return level
*/
XMLA_Level lookupLevelByUName(String uName) {
for (Iterator iter = aLevels.iterator(); iter.hasNext();) {
XMLA_Level lev = (XMLA_Level) iter.next();
if (lev.getUniqueName().equals(uName))
return lev;
}
return null;
}
/**
* lookup member by unique name
* @param name
* @return Member
*/
public Member lookupMemberByUName(String uName) {
for (Iterator iter = aMembers.iterator(); iter.hasNext();) {
XMLA_Member mem = (XMLA_Member) iter.next();
if (mem.getUniqueName().equals(uName))
return mem;
}
return null;
}
/**
* add all members for an hierarchy
* @param hier
*/
/*
protected void addMembers(XMLA_Hierarchy hier) throws OlapException {
if (hier.isMembersGotten())
return;
try {
discoverMembers(hier.getUniqueName());
} catch (SOAPException ex) {
throw new OlapException("SOAP Error getting members");
}
}
*/
/** add single member
*/
void addMember(XMLA_Member mem) {
aMembers.add(mem);
}
/** remove single member
*/
public void removeMember(XMLA_Member mem) {
if (aMembers.contains(mem))
aMembers.remove(mem);
}
/**
* create a Memento bean object holding current state.
* @return Memento current state
*/
public Object getBookmarkState(int levelOfDetail) {
try {
XMLA_Memento memento = new XMLA_Memento();
memento.setVersion(XMLA_Memento.CURRENT_VERSION);
memento.setUri(uri);
memento.setDataSource(dataSource);
memento.setCatalog(catalog);
memento.setUser(user);
memento.setPassword(password);
// set the MDX query string
// When the state is reset, this mdx will be parsed as the
// startup query.
memento.setMdxQuery(currentMdx);
boolean useQuax = queryAdapter.isUseQuax();
memento.setUseQuax(useQuax);
if (useQuax) {
XMLA_Quax[] quaxes = (XMLA_Quax[]) queryAdapter.getQuaxes();
QuaxBean[] quaxBeans = new QuaxBean[quaxes.length];
for (int i = 0; i < quaxes.length; i++) {
quaxBeans[i] = new QuaxBean();
beanFromQuax(quaxBeans[i], quaxes[i]);
} // for i quaxes
// set quaxes to memento
memento.setQuaxes(quaxBeans);
}
// axes swapped
memento.setAxesSwapped(queryAdapter.isSwapAxes());
// sorting
XMLA_SortRank sortExt = (XMLA_SortRank) getExtension(SortRank.ID);
if (sortExt != null)
storeSort(sortExt, memento);
// calc measure property assignment
if (calcMeasurePropMap != null)
memento.setCalcMeasurePropMap(calcMeasurePropMap);
return memento;
} catch (OlapException e) {
logger.error(null, e);
throw new RuntimeException(e);
}
}
/**
* restore state from Memento.
* @param Object state bean to be restored
*/
public void setBookmarkState(Object state) {
XMLA_Memento memento = (XMLA_Memento) state;
mdxQuery = memento.getMdxQuery();
try {
if (isInitialized) {
// already initialized, only new query adapter needed
parse(mdxQuery);
queryAdapter = new XMLA_QueryAdapter(this);
XMLA_SortRank sortExt = (XMLA_SortRank) getExtension(SortRank.ID);
if (sortExt != null)
sortExt.reset();
isNewCube = false;
} else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -