package com.c2c.query;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import com.c2c.data.DataQueryFeatureSource;
import com.vividsolutions.jts.geom.Point;
import org.geotools.data.FeatureSource;
import org.olap4j.Cell;
import org.olap4j.CellSet;
import org.olap4j.OlapConnection;
import org.olap4j.OlapStatement;
import org.olap4j.Position;
import org.olap4j.metadata.Member;
import org.olap4j.metadata.Property;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.MultiPolygon;
/**
* Makes the OLAP request and builds a {@link FeatureSource} from the
* results using the {@link FeatureSourceBuilder}
*
* @author jeichar
*/
public class DataQuery extends AbstractQuery<DataQueryFeatureSource> {
private final String mdx;
public DataQuery(String jdbcConnection, String catalogDefFile, String mdx) {
super(jdbcConnection, catalogDefFile);
this.mdx = mdx;
}
public static String getUniqueId(String longName) {
MessageDigest digest = null;
try {
digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
digest.update(longName.getBytes());
StringBuffer uniqueId = new StringBuffer();
for (byte b : digest.digest()) {
int i1 = (0xff & b);
int i2 = (int) i1 / 16;
uniqueId.append((char) (i2 + 65));
uniqueId.append((char) (i1 - (i2 * 16) + 65));
}
return uniqueId.toString();
}
private String constructAttributeName(List<Member> members) {
StringBuilder dataIndex = new StringBuilder();
for (Member m : members) {
if (dataIndex.length() > 0) {
dataIndex.append("_");
}
dataIndex.append(getUniqueId((String) m.getPropertyValue(Property.StandardMemberProperty.MEMBER_UNIQUE_NAME)));
}
return dataIndex.toString();
}
private void addMembers(DataQueryFeatureSource dataQueryFeatures, String type, List<Member> members) {
for (Member m : members) {
String dimensionUniqueName = (String) m.getPropertyValue(Property.StandardMemberProperty.DIMENSION_UNIQUE_NAME);
String levelUniqueName = (String) m.getPropertyValue(Property.StandardMemberProperty.LEVEL_UNIQUE_NAME);
String memberName = (String) m.getPropertyValue(Property.StandardMemberProperty.MEMBER_NAME);
String memberUniqueName = (String) m.getPropertyValue(Property.StandardMemberProperty.MEMBER_UNIQUE_NAME);
dataQueryFeatures.addMember(type, dimensionUniqueName, levelUniqueName, memberName, memberUniqueName);
}
}
@Override
protected DataQueryFeatureSource doExecute(OlapConnection connection) throws Exception {
OlapStatement statement = connection.createStatement();
CellSet cellSet = statement.executeOlapQuery(mdx);
DataQueryFeatureSource dataQueryFeatures = new DataQueryFeatureSource(mdx);
DataQueryResults results = new DataQueryResults();
// FIXME: Member names should be returned by GetMetadata only
// results.addSpec(new DataAttributeDef("row_data_index", String.class));
for (Position row : cellSet.getAxes().get(1)) {
for (Member m : row.getMembers()) {
String dimensionName = (String) m.getPropertyValue(Property.StandardMemberProperty.DIMENSION_UNIQUE_NAME);
results.addSpec(new DataAttributeDef(dimensionName, String.class));
}
break;
}
for (Position column : cellSet.getAxes().get(0)) {
addMembers(dataQueryFeatures, "columns", column.getMembers());
results.addSpec(new DataAttributeDef(constructAttributeName(column.getMembers()), Double.class));
}
results.addSpec(new DataAttributeDef("geom", MultiPolygon.class));
results.setDefaultGeomAttName("geom");
results.addSpec(new DataAttributeDef("point", Point.class));
List<DataAttribute> feature;
for (Position row : cellSet.getAxes().get(1)) {
feature = new ArrayList<DataAttribute>();
Geometry geom = null;
Geometry point = null;
for (Member m : row.getMembers()) {
for (Property p : m.getProperties()) {
final String name = p.getName();
if (name.equals("geom")) {
Geometry g = (Geometry) m.getPropertyValue(p);
if (geom == null) {
geom = g;
} else {
geom = geom.intersection(g);
}
}
if (name.equals("pointgeom")) {
if (point == null) {
point = (Point) m.getPropertyValue(p);
}
}
}
String dimensionName = (String) m.getPropertyValue(Property.StandardMemberProperty.DIMENSION_UNIQUE_NAME);
String memberName = (String) m.getPropertyValue(Property.StandardMemberProperty.MEMBER_NAME);
feature.add(new DataAttribute(dimensionName, memberName));
}
for (Position column : cellSet.getAxes().get(0)) {
final Cell cell = cellSet.getCell(column, row);
feature.add(new DataAttribute(constructAttributeName(column.getMembers()),
(Double) cell.getValue()));
}
feature.add(new DataAttribute("geom", geom));
feature.add(new DataAttribute("point", point));
results.addData(feature);
addMembers(dataQueryFeatures, "rows", row.getMembers());
}
dataQueryFeatures.buildFeatureSource(results);
return dataQueryFeatures;
}
}