📄 mondrianmodel.java
字号:
* add Dimension to Hashtable, if not already there
*
* @param monDimension -
* the "key" is the Mondrian Dimension
* @return the corresponding dimension
*/
private void addDimension(mondrian.olap.Dimension monDimension) {
String uniqueName = monDimension.getUniqueName();
if (!hDimensions.containsKey(uniqueName)) {
MondrianDimension dimension = new MondrianDimension(monDimension, this);
hDimensions.put(uniqueName, dimension);
// make sure, that all hierarchies are initialized
mondrian.olap.Hierarchy[] monHiers = monDimension.getHierarchies();
for (int i = 0; i < monHiers.length; i++) {
this.addHierarchy(monHiers[i], dimension);
}
}
}
/**
* add Hierarchy to Hashtable, if not already there
*
* @param monHierarchy -
* the "key" is the Mondrian Hierarchy
* @return the corresponding hierarchy
*/
private void addHierarchy(mondrian.olap.Hierarchy monHierarchy, MondrianDimension dimension) {
String uniqueName = monHierarchy.getUniqueName();
if (!hHierarchies.containsKey(uniqueName)) {
MondrianHierarchy hierarchy = new MondrianHierarchy(monHierarchy, dimension, this);
hHierarchies.put(uniqueName, hierarchy);
// make sure, that all levels are initialized
SchemaReader scr = monConnection.getSchemaReader();
mondrian.olap.Level[] monLevels = scr.getHierarchyLevels(monHierarchy);
for (int i = 0; i < monLevels.length; i++) {
this.addLevel(monLevels[i], hierarchy);
}
}
}
/**
* add Level to Hashtable, if not already there
*
* @param monLevel -
* the "key" is the Mondrian Level
* @return the corresponding level
*/
protected void addLevel(mondrian.olap.Level monLevel, MondrianHierarchy hierarchy) {
String uniqueName = monLevel.getUniqueName();
if (!hLevels.containsKey(uniqueName)) {
MondrianLevel level = new MondrianLevel(monLevel, hierarchy, this);
hLevels.put(uniqueName, level);
}
}
/**
* add Member to Hashtable, if not already there
*
* @param monMember -
* the "key" is the Mondrian Member
* @return the corresponding member
*/
public MondrianMember addMember(mondrian.olap.Member monMember) {
String uniqueName = monMember.getUniqueName();
if (hMembers.containsKey(uniqueName)) {
return (MondrianMember) hMembers.get(uniqueName);
} else {
mondrian.olap.Level monLevel = monMember.getLevel();
MondrianLevel level = this.lookupLevel(monLevel.getUniqueName());
MondrianMember member = new MondrianMember(monMember, level, this);
hMembers.put(uniqueName, member);
if (monMember.isMeasure())
aMeasures.add(member);
return member;
}
}
/**
* remove Member from Hashtable (for a calculated member)
*
* @param monMember -
* the "key" is the Mondrian Member
* @return the corresponding member
*/
public void removeMember(String uniqueName) {
if (hMembers.containsKey(uniqueName)) {
MondrianMember m = (MondrianMember) hMembers.get(uniqueName);
if (aMeasures.contains(m))
aMeasures.remove(m);
hMembers.remove(uniqueName);
}
}
/**
* find the Dimension.
*
* @param uniqueName
* is the search key (
* @return the corresponding MondrianDimension
*/
public MondrianDimension lookupDimension(String uniqueName) {
return (MondrianDimension) hDimensions.get(uniqueName);
}
/**
* find the Hierarchy in the dimensions.
*
* @param uniqueName
* is the search key
* @return the corresponding hierarchy
*/
public MondrianHierarchy lookupHierarchy(String uniqueName) {
return (MondrianHierarchy) hHierarchies.get(uniqueName);
}
/**
* find member in the Olap Hierarchy.
*
* @param uniqueName
* is the search key (Mondrian member unique name)
* @return the corresponding member
*/
public Member lookupMemberByUName(String uniqueName) {
// if the unique name was stored in a memento,
// it is possible, that
// - the member was not loaded yet
// - the member was removed from the schema meanwhile
MondrianMember m = (MondrianMember) hMembers.get(uniqueName);
if (m != null)
return m;
final SchemaReader scr = this.getConnection().getSchemaReader();
String[] uniqueNameParts = Util.explode(uniqueName);
/*
* Pattern pat = Pattern.compile("\\[([^\\]]+)\\]"); Matcher mat =
* pat.matcher(uniqueName); int i = 0; ArrayList aName = new ArrayList();
* while (mat.find()) { String group = mat.group(1); aName.add(group); }
* String[] uniqueNameParts = (String[])aName.toArray(new String[0]);
*/
Cube cube = queryAdapter.getMonQuery().getCube();
mondrian.olap.Member monMember = (mondrian.olap.Member) Util.lookupCompound(scr, cube,
uniqueNameParts, false, Category.Member);
if (monMember != null)
return addMember(monMember);
if (monMember == null) {
// there's still a chance to find the member
// as a calculated member in a formula
Formula[] formulas = queryAdapter.getMonQuery().getFormulas();
for (int i = 0; i < formulas.length; i++) {
monMember = formulas[i].getMdxMember();
if (uniqueName.equals(monMember.getUniqueName()))
return addMember(monMember);
}
}
return null;
}
/**
* find level in the Olap Hierarchy.
*
* @param monLevel
* is the search key (Mondrian level)
* @return the corresponding level
*/
public MondrianLevel lookupLevel(String uniqueName) {
return (MondrianLevel) hLevels.get(uniqueName);
}
/**
* @return true if dimension and all of its hierachies can be
* accessed according to role
*/
private boolean canAccess(mondrian.olap.Dimension dim) {
Role role = this.monConnection.getRole();
if (!role.canAccess(dim))
return false;
mondrian.olap.Hierarchy[] hiers = dim.getHierarchies();
for (int i = 0; i < hiers.length; i++) {
if (role.canAccess(hiers[i]))
return true;
}
return false;
}
/**
* reset the model Hashtables.
*/
private void resetMetaData(mondrian.olap.Query monQuery) {
this.hDimensions = new HashMap();
this.hHierarchies = new HashMap();
this.hLevels = new HashMap();
this.hMembers = new HashMap();
this.aMeasures = new ArrayList();
// initialize meta data
mondrian.olap.Cube cube = monQuery.getCube();
mondrian.olap.Dimension[] monDims = cube.getDimensions();
for (int i = 0; i < monDims.length; i++) {
// Is the dimension accessable?
if (canAccess(monDims[i]))
this.addDimension(monDims[i]);
}
SchemaReader sr = cube.getSchemaReader(null);
for (int i = 0; i < monDims.length; i++) {
mondrian.olap.Hierarchy[] monHiers = monDims[i].getHierarchies();
for (int j = 0; j < monHiers.length; j++) {
List calcMembers = sr.getCalculatedMembers(monHiers[j]);
for (Iterator it = calcMembers.iterator(); it.hasNext();) {
this.addMember((mondrian.olap.Member) it.next());
}
}
}
//long l3 = System.currentTimeMillis();
//System.out.println("Time for create meta data(ms)=" + (l3-l2));
}
/**
* get the Mondrian Connection
*
* @return The Mondrian Connection
*/
protected mondrian.olap.Connection getConnection() {
return monConnection;
}
/**
* get the MDX for the user to edit
*
* @return current MDX statement
* @see MdxOlapModel.getCurrentMdx()
*/
public String getCurrentMdx() {
// if the model was changed, due to ModelChangeListener,
// then the current MDX is not really "current"
if (result != null)
return currentMdx;
else if (queryAdapter == null) {
return mdxQuery;
} else {
// get new result, this will update the mdx
try {
getResult();
} catch (Exception e) {
logger.error("unexpected Exeption getResult " + e.toString());
throw new RuntimeException(e);
}
return currentMdx;
}
}
/**
* 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
*/
boolean setUserMdx(String mdxQuery) throws OlapException {
if (this.currentMdx.equals(mdxQuery))
return false;
String saveMdx = this.mdxQuery;
this.mdxQuery = mdxQuery;
if (logger.isInfoEnabled())
logger.info("setUserMdx =" + mdxQuery);
mondrian.olap.Query monQuery = null;
try {
monQuery = parseMDX();
} catch (OlapException e) {
logger.error("setUserMdx failed " + e.getMessage());
// parse failed, restore old mdx
this.mdxQuery = saveMdx;
throw e; // re-throw
}
resetMetaData(monQuery); // reset the model data
queryAdapter = new MondrianQueryAdapter(this, monQuery);
// no exception gotten
MondrianSortRank sortExt = (MondrianSortRank) getExtension(SortRank.ID);
if (sortExt != null)
sortExt.reset();
result = null;
this.currentMdx = mdxQuery.replace('\r', ' ');
return true;
}
/**
* Returns the mdxQuery.
*
* @return String
*/
protected String getMdxQuery() {
return mdxQuery;
}
public Object getRootDecoree() {
return this;
}
/**
* session terminated, closing connections etc
*/
public void destroy() {
logger.info(null);
super.destroy();
if (monConnection != null) {
if (logger.isDebugEnabled())
logger.debug("MondrianModel: closing connection " + monConnection);
monConnection.close();
monConnection = null;
}
this.sessionId = null;
}
/**
* Sets the currentMdx.
*
* @param currentMdx
* The currentMdx to set
*/
protected void setCurrentMdx(String currentMdx) {
//this.currentMdx = currentMdx.replace('\r', ' ');
this.currentMdx = currentMdx.replaceAll("\r", "");
}
/**
* Returns the monConnection.
*
* @return mondrian.olap.Connection
*/
protected mondrian.olap.Connection getMonConnection() {
return monConnection;
}
/**
* Get jdbcDriver.
*
* @return jdbcDriver
*/
protected String getJdbcDriver() {
return jdbcDriver;
}
/**
* Get connectString.
*
* @return connectString.
*/
protected String getConnectString() {
return connectString;
}
/**
* create a Memento bean object holding current state.
*
* @return MondrianMemento current state
*/
public Object getBookmarkState(int levelOfDetail) {
if (this.result == null)
return null;
try {
if (levelOfDetail == Bookmarkable.EXTENSIONAL)
return getExtensionalBookmarkState();
return getIntensionalBookmarkState();
} catch (OlapException e) {
logger.error(null, e);
throw new RuntimeException(e);
}
}
/**
* creates a bookmark that will contail as much detail as possible. But this
* bookmark may not work when the data in the cube have changed.
*/
private Object getExtensionalBookmarkState() throws OlapException {
MondrianMemento memento = createMemento();
// 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) {
MondrianQuax[] quaxes = (MondrianQuax[]) queryAdapter.getQuaxes();
MondrianQuaxBean[] quaxBeans = new MondrianQuaxBean[quaxes.length];
for (int i = 0; i < quaxes.length; i++) {
quaxBeans[i] = new MondrianQuaxBean();
beanFromQuax(quaxBeans[i], quaxes[i]);
} // for i quaxes
// set quaxes to memento
memento.setQuaxes(quaxBeans);
}
return memento;
}
/**
* creates a bookmark that will contail only those data, that are independent
* of the data in the cube. This bookmark can be restored even after
* cube data has changed.
*/
private Object getIntensionalBookmarkState() throws OlapException {
MondrianMemento memento = createMemento();
memento.setUseQuax(true);
MondrianAxis[] axes = (MondrianAxis[]) result.getAxes();
MondrianQuaxBean[] quaxBeans = new MondrianQuaxBean[axes.length];
for (int i = 0; i < axes.length; i++)
quaxBeans[i] = intensionalQuaxBeanFromAxis(axes[i]);
memento.setQuaxes(quaxBeans);
// create the appropriate mdx query
// calculated measures will be adopted if they
// only deal with measures.
String newMdx = intensionalMdx(quaxBeans);
memento.setMdxQuery(newMdx);
return memento;
}
/**
* create intensional MDX query
*/
private String intensionalMdx(MondrianQuaxBean[] quaxBeans) {
String saveMdx = this.currentMdx;
Query cloneQuery = queryAdapter.getMonQuery().safeClone();
MondrianQuax quaxes[] = new MondrianQuax[quaxBeans.length];
for (int i = 0; i < quaxes.length; i++) {
MondrianQuax q = (MondrianQuax) queryAdapter.getQuaxes()[i];
QueryAxis a = queryAdapter.getMonQuery().axes[i];
quaxes[i] = new MondrianQuax(q.getOrdinal(), a, this);
}
try {
quaxesFromBeans(quaxes, quaxBeans);
} catch (OlapException e) {
logger.error(null, e);
throw new IllegalArgumentException(e.toString());
}
MondrianQuax saveQuaxes[] = (MondrianQuax[]) queryAdapter.getQuaxes();
queryAdapter.setQuaxes(quaxes);
Query mQuery = queryAdapter.getMonQuery();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -