📄 cubecursor.java
字号:
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/**
* Title: XELOPES Data Mining Library
* Description: The XELOPES library is an open platform-independent and data-source-independent library for Embedded Data Mining.
* Copyright: Copyright (c) 2002 Prudential Systems Software GmbH
* Company: ZSoft (www.zsoft.ru), Prudsys (www.prudsys.com)
* @author Michael Thess
* @version 1.2
*/
package com.prudsys.pdm.Olap.Cursor;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import javax.olap.OLAPException;
import javax.olap.cursor.Blob;
import javax.olap.cursor.Clob;
import javax.olap.cursor.Time;
import javax.olap.cursor.Timestamp;
import com.prudsys.pdm.Core.CategoricalAttribute;
import com.prudsys.pdm.Core.Category;
import com.prudsys.pdm.Core.MiningAttribute;
import com.prudsys.pdm.Core.MiningDataSpecification;
import com.prudsys.pdm.Core.MiningException;
import com.prudsys.pdm.Core.NumericAttribute;
import com.prudsys.pdm.Cwm.JMIList;
import com.prudsys.pdm.Input.MiningInputStream;
import com.prudsys.pdm.Input.MiningStoredData;
import com.prudsys.pdm.Input.MiningVector;
import com.prudsys.pdm.Input.Multidimensional.MultidimensionalStream;
import com.prudsys.pdm.Input.Multidimensional.OrderAttribute;
import com.prudsys.pdm.Input.Multidimensional.SelectAttribute;
import com.prudsys.pdm.Input.Predicates.CompoundPredicate;
import com.prudsys.pdm.Input.Predicates.Predicate;
import com.prudsys.pdm.Olap.OlapEngine;
import com.prudsys.pdm.Olap.Metadata.Cube;
import com.prudsys.pdm.Olap.Metadata.Dimension;
import com.prudsys.pdm.Olap.Metadata.Measure;
import com.prudsys.pdm.Olap.Metadata.MeasureDimension;
import com.prudsys.pdm.Olap.Query.Core.CubeView;
import com.prudsys.pdm.Olap.Query.Core.DimensionStepManager;
import com.prudsys.pdm.Olap.Query.Core.DimensionView;
import com.prudsys.pdm.Olap.Query.Core.EdgeView;
import com.prudsys.pdm.Utils.IntVector;
/**
* Cube cursor access class.
*/
public class CubeCursor extends Cursor implements javax.olap.cursor.CubeCursor
{
// -----------------------------------------------------------------------
// Variables declarations
// -----------------------------------------------------------------------
/** List of ordinate edge cursors owned by this cube cursor. */
protected JMIList ordinateEdge = new JMIList();
/** List of page edge cursors owned by this cube cursor. */
protected JMIList pageEdge = new JMIList();
/** Reference to CubeView. */
protected CubeView cubeView;
/** Mining input stream containing query result as table. */
protected MultidimensionalStream aggregStream;
/** Selection on table attributes from ordinate edge cursors. */
protected MiningVector ordinateSelect;
/** Mining input stream of selected vectors at current cursor position. */
protected MiningStoredData pageStream = new MiningStoredData();
// -----------------------------------------------------------------------
// Constructors
// -----------------------------------------------------------------------
/**
* Empty constructor.
*/
public CubeCursor() {
}
/**
* Creates cube cursor and executes query.
*
* @param cubeView accociate cube view
* @exception OLAPException cannot execute query
*/
public CubeCursor(CubeView cubeView) throws OLAPException {
this.cubeView = cubeView;
// Execute query
executeQuery();
// Create ordinate edge cursors:
createOrdinateEdge();
// Create page edge cursors:
createPageEdge();
}
// -----------------------------------------------------------------------
// Query execution methods
// -----------------------------------------------------------------------
/**
* Executes OLAP query using the multidimensional stream.
*
* @throws OLAPException couldn't execute query
*/
private void executeQuery() throws OLAPException {
OlapEngine olapEngine = cubeView.getOlapEngine();
Cube cube = cubeView.getCube();
// Find ordinate dimensions:
Vector ordinateDimensions = new Vector();
for (int i = 0; i < cubeView.getOrdinateEdge().size(); i++) {
EdgeView edgeView = (EdgeView) cubeView.getOrdinateEdge().get(i);
for (int j = 0; j < edgeView.getDimensionView().size(); j++) {
DimensionView dimView = (DimensionView) edgeView.getDimensionView().get(j);
ordinateDimensions.addElement( dimView.getDimension() );
}
}
if ( ordinateDimensions.size() == 0 )
throw new OLAPException("no ordinate dimensions defined");
// Find measure dimension:
MeasureDimension measureDimension = null;
Iterator it = cubeView.getPageEdge().iterator();
for (int i = 0; i < cubeView.getPageEdge().size(); i++) {
EdgeView edgeView = (EdgeView) it.next();
for (int j = 0; j < edgeView.getDimensionView().size(); j++) {
DimensionView dimView = (DimensionView) edgeView.getDimensionView().get(j);
Dimension dim = (Dimension) dimView.getDimension();
if (dim instanceof MeasureDimension)
measureDimension = (MeasureDimension) dim;
}
}
if ( measureDimension == null )
throw new OLAPException("no measure dimension defined");
// Run query:
try {
MultidimensionalStream multiStream = olapEngine.getMultiStream();
MiningDataSpecification multiMetaData = multiStream.getMetaData();
multiStream.reset();
// Get all attributes of ordinate dimensions:
Vector ordinateAttributes = new Vector();
IntVector ordinateIndexes = new IntVector();
for (int i = 0; i < ordinateDimensions.size(); i++) {
Dimension dim = (Dimension) ordinateDimensions.elementAt(i);
if (dim.getNumberOfDimensionAttributes() == 0)
throw new OLAPException("dimension '" + dim.getName() + "' without attribute");
MiningAttribute ma = dim.getDimensionAttribute(0);
ordinateAttributes.addElement(ma);
int ind = multiMetaData.getAttributeIndex(ma);
if (ind < 0)
throw new OLAPException("dimension '" + dim.getName() + "' with invalid attribute '" + ma.getName() + "'");
ordinateIndexes.addElement(ind);
}
int nOrdAtt = ordinateAttributes.size();
// Create ordinate selection vector (required for cursor updates):
double[] oval = new double[nOrdAtt];
MiningDataSpecification ordMetaData = new MiningDataSpecification("ordMetaData");
for (int i = 0; i < ordinateAttributes.size(); i++) {
MiningAttribute ma = (MiningAttribute) ordinateAttributes.elementAt(i);
ordMetaData.addMiningAttribute(ma);
oval[i] = Category.MISSING_VALUE;
}
ordinateSelect = new MiningVector(oval);
ordinateSelect.setMetaData(ordMetaData);
// Add all ordinate attributes to ordering:
for (int i = 0; i < ordinateAttributes.size(); i++) {
MiningAttribute ma = (MiningAttribute) ordinateAttributes.elementAt(i);
OrderAttribute oAtt = new OrderAttribute(ma.getName(), OrderAttribute.DOWN);
multiStream.addOrdering(oAtt);
}
// Find selection predicates:
Vector selPredicates = new Vector();
for (int i = 0; i < cubeView.getOrdinateEdge().size(); i++) {
EdgeView edgeView = (EdgeView) cubeView.getOrdinateEdge().get(i);
for (int j = 0; j < edgeView.getDimensionView().size(); j++) {
DimensionView dimView = (DimensionView) edgeView.getDimensionView().get(j);
for (int k = 0; k < dimView.getDimensionStepManager().size(); k++) {
DimensionStepManager dsm = (DimensionStepManager) dimView.getDimensionStepManager().iterator().next();;
Predicate predicate = dsm.getPredicate();
if (predicate != null)
selPredicates.addElement(predicate);
}
}
}
int nPred = selPredicates.size();
// Run selections and ordering:
if ( nPred > 0 ) {
CompoundPredicate cp = new CompoundPredicate(CompoundPredicate.AND, nPred);
for (int i = 0; i < nPred; i++)
cp.setPredicate( (Predicate) selPredicates.elementAt(i), i);
multiStream.runSelectionsPredicate(cp);
}
// Run just ordering:
else {
multiStream.runOrdering();
}
// Create aggregated meta data:
MiningDataSpecification aggMetaData = new MiningDataSpecification("attMetaData");
for (int i = 0; i < nOrdAtt; i++) {
MiningAttribute oAtt = (MiningAttribute) ordinateAttributes.elementAt(i);
aggMetaData.addMiningAttribute(oAtt);
}
// Get all measures and measure attributes:
Vector measures = measureDimension.getDimensionAttributes();
int nMeasAtt = measures.size();
if (nMeasAtt == 0)
throw new OLAPException("measure dimension '" + measureDimension.getName() + "' without measures");
Vector measureAttributes = new Vector();
for (int i = 0; i < nMeasAtt; i++) {
Measure meas = (Measure) measures.elementAt(i);
NumericAttribute measAtt = new NumericAttribute( meas.getName() );
measureAttributes.addElement(measAtt);
aggMetaData.addMiningAttribute(measAtt);
}
int nAggAtt = aggMetaData.getAttributesNumber();
// Create aggregated stream:
MiningStoredData aggStream = new MiningStoredData();
aggStream.setMetaData(aggMetaData);
// Traverse multi stream and calculate aggregates:
boolean firstLine = true; // first line
int[] prevKeys = new int[nOrdAtt]; // previous ordinate keys
int[] ordKeys = new int[nOrdAtt]; // current ordinate keys
MiningStoredData msd = new MiningStoredData(); // for aggregate calculations
msd.setMetaData(multiMetaData);
multiStream.reset();
while ( multiStream.next() ) {
// Get vector:
MiningVector mv = multiStream.read();
for (int i = 0; i < nOrdAtt; i++)
ordKeys[i] = (int) mv.getValue( ordinateIndexes.IntegerAt(i) );
// First line:
if (firstLine) {
System.arraycopy(ordKeys, 0, prevKeys, 0, nOrdAtt);
firstLine = false;
}
// New aggregate:
if ( !compIntArrays(nOrdAtt, ordKeys, prevKeys) ) {
// Add aggregate vector to aggregate stream:
double[] values = new double[nAggAtt];
for (int i = 0; i < nOrdAtt; i++)
values[i] = prevKeys[i];
measureDimension.setInputStream(msd);
measureDimension.calcStatistics();
for (int i = 0; i < nMeasAtt; i++) {
Measure meas = (Measure) measures.elementAt(i);
double val = meas.measureValue();
values[nOrdAtt+i] = val;
}
MiningVector mv2 = new MiningVector(values);
mv2.setMetaData(aggMetaData);
aggStream.add(mv2);
System.arraycopy(ordKeys, 0, prevKeys, 0, nOrdAtt);
msd.clear();
}
msd.add(mv);
}
if (!firstLine) {
// Add aggregate vector to aggregate stream:
double[] values = new double[nAggAtt];
for (int i = 0; i < nOrdAtt; i++)
values[i] = prevKeys[i];
measureDimension.setInputStream(msd);
measureDimension.calcStatistics();
for (int i = 0; i < nMeasAtt; i++) {
Measure meas = (Measure) measures.elementAt(i);
double val = meas.measureValue();
values[nOrdAtt+i] = val;
}
MiningVector mv2 = new MiningVector(values);
mv2.setMetaData(aggMetaData);
aggStream.add(mv2);
}
// Create multidimensional aggregate stream:
aggStream.reset();
aggregStream = new MultidimensionalStream(aggStream);
aggregStream.readMultidimensionalStreamData();
aggregStream.reset();
}
catch (MiningException ex) {
throw new OLAPException( ex.toString() );
}
}
/**
* Compares two arrays of integers of same length.
*
* @param n comon length of both arrays
* @param a1 first array to compare
* @param a2 second array to compare
* @return true is arrays are equal, false otherwise
*/
private boolean compIntArrays(int n, int[] a1, int[] a2) {
for (int i = 0; i < n; i++)
if (a1[i] != a2[i]) return false;
return true;
}
/**
* Returns result of query as flat table. The result is delivered as
* mining input stream where the columns correspond to all attributes
* of the ordinate dimensions and measures.
*
* @return query result as flat table
*/
public MiningInputStream getResultTable() {
return aggregStream;
}
// -----------------------------------------------------------------------
// Copy result for cursor access
// -----------------------------------------------------------------------
/**
* Creates ordinate edges for rows and columns.
*
* @throws OLAPException couldn't create ordinate edge
*/
private void createOrdinateEdge() throws OLAPException {
try {
MiningDataSpecification aggMetaData = aggregStream.getMetaData();
for (int i = 0; i < cubeView.getOrdinateEdge().size(); i++) {
EdgeView edgeView = (EdgeView) cubeView.getOrdinateEdge().get(i);
// Create new edge cursor
// Create edge meta data:
MiningDataSpecification edgeMetaData = new MiningDataSpecification("edgeMetaData");
IntVector edgeIndexes = new IntVector();
for (int j = 0; j < edgeView.getDimensionView().size(); j++) {
DimensionView dimView = (DimensionView) edgeView.getDimensionView().get(j);
Dimension dim = (Dimension) dimView.getDimension();
MiningAttribute ma = dim.getDimensionAttribute(0);
edgeMetaData.addMiningAttribute(ma);
int ind = aggMetaData.getAttributeIndex(ma);
edgeIndexes.addElement(ind);
}
int nEdgeAtt = edgeMetaData.getAttributesNumber();
// Create edge stream:
MiningStoredData edgeTable = new MiningStoredData();
edgeTable.setMetaData(edgeMetaData);
Hashtable usedKeys = new Hashtable();
aggregStream.reset();
while ( aggregStream.next() ) {
// Get vector:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -