util.java
来自「数据仓库展示程序」· Java 代码 · 共 1,344 行 · 第 1/4 页
JAVA
1,344 行
* "[part1].[part2]". If the names contain "]" they are escaped as "]]".
*/
public static String implode(String[] names) {
StringBuffer sb = new StringBuffer(64);
for (int i = 0; i < names.length; i++) {
if (i > 0) {
sb.append(".");
}
quoteMdxIdentifier(names[i], sb);
}
return sb.toString();
}
public static String makeFqName(String name) {
return quoteMdxIdentifier(name);
}
public static String makeFqName(OlapElement parent, String name) {
if (parent == null) {
return Util.quoteMdxIdentifier(name);
} else {
StringBuffer buf = new StringBuffer(64);
buf.append(parent.getUniqueName());
buf.append('.');
Util.quoteMdxIdentifier(name, buf);
return buf.toString();
}
}
public static String makeFqName(String parentUniqueName, String name) {
if (parentUniqueName == null) {
return quoteMdxIdentifier(name);
} else {
StringBuffer buf = new StringBuffer(64);
buf.append(parentUniqueName);
buf.append('.');
Util.quoteMdxIdentifier(name, buf);
return buf.toString();
}
}
/**
* Resolves a name such as
* '[Products].[Product Department].[Produce]' by resolving the
* components ('Products', and so forth) one at a time.
*
* @param schemaReader Schema reader, supplies access-control context
* @param parent Parent element to search in
* @param names Exploded compound name, such as {"Products",
* "Product Department", "Produce"}
* @param failIfNotFound If the element is not found, determines whether
* to return null or throw an error
* @param category Type of returned element, a {@link Category} value;
* {@link Category#Unknown} if it doesn't matter.
* @pre parent != null
* @post !(failIfNotFound && return == null)
* @see #explode
*/
public static OlapElement lookupCompound(
SchemaReader schemaReader,
OlapElement parent,
String[] names,
boolean failIfNotFound,
int category) {
Util.assertPrecondition(parent != null, "parent != null");
if (LOGGER.isDebugEnabled()) {
StringBuffer buf = new StringBuffer(64);
buf.append("Util.lookupCompound: ");
buf.append("parent.name=");
buf.append(parent.getName());
buf.append(", category=");
buf.append(Category.instance.getName(category));
buf.append(", names=");
quoteMdxIdentifier(names, buf);
LOGGER.debug(buf.toString());
}
// First look up a member from the cache of calculated members
// (cubes and queries both have them).
switch (category) {
case Category.Member:
case Category.Unknown:
Member member = schemaReader.getCalculatedMember(names);
if (member != null) {
return member;
}
}
// Likewise named set.
switch (category) {
case Category.Set:
case Category.Unknown:
NamedSet namedSet = schemaReader.getNamedSet(names);
if (namedSet != null) {
return namedSet;
}
}
// Now resolve the name one part at a time.
for (int i = 0; i < names.length; i++) {
String name = names[i];
final OlapElement child = schemaReader.getElementChild(parent, name);
if (child == null) {
if (LOGGER.isDebugEnabled()) {
StringBuffer buf = new StringBuffer(64);
buf.append("Util.lookupCompound: ");
buf.append("parent.name=");
buf.append(parent.getName());
buf.append(" has no child with name=");
buf.append(name);
LOGGER.debug(buf.toString());
}
if (failIfNotFound) {
throw MondrianResource.instance().MdxChildObjectNotFound.ex(
name, parent.getQualifiedName());
} else {
return null;
}
}
parent = child;
}
if (LOGGER.isDebugEnabled()) {
StringBuffer buf = new StringBuffer(64);
buf.append("Util.lookupCompound: ");
buf.append("found child.name=");
buf.append(parent.getName());
buf.append(", child.class=");
buf.append(parent.getClass().getName());
LOGGER.debug(buf.toString());
}
switch (category) {
case Category.Dimension:
if (parent instanceof Dimension) {
return parent;
} else if (parent instanceof Hierarchy) {
return parent.getDimension();
} else if (failIfNotFound) {
throw Util.newError("Can not find dimension '" + implode(names) + "'");
} else {
return null;
}
case Category.Hierarchy:
if (parent instanceof Hierarchy) {
return parent;
} else if (parent instanceof Dimension) {
return parent.getHierarchy();
} else if (failIfNotFound) {
throw Util.newError("Can not find hierarchy '" + implode(names) + "'");
} else {
return null;
}
case Category.Level:
if (parent instanceof Level) {
return parent;
} else if (failIfNotFound) {
throw Util.newError("Can not find level '" + implode(names) + "'");
} else {
return null;
}
case Category.Member:
if (parent instanceof Member) {
return parent;
} else if (failIfNotFound) {
throw MondrianResource.instance().MdxCantFindMember.ex(implode(names));
} else {
return null;
}
case Category.Unknown:
assertPostcondition(parent != null, "return != null");
return parent;
default:
throw newInternal("Bad switch " + category);
}
}
public static OlapElement lookup(Query q, String[] nameParts) {
return (OlapElement) lookup(q, nameParts, false);
}
/**
* Converts an identifier into an expression by resolving its parts into
* an OLAP object (dimension, hierarchy, level or member) within the
* context of a query.
*
* <p>If <code>allowProp</code> is true, also allows property references
* from valid members, for example
* <code>[Measures].[Unit Sales].FORMATTED_VALUE</code>.
* In this case, the result will be a {@link FunCall}.
*
* @param q Query expression belongs to
* @param nameParts Parts of the identifier
* @param allowProp Whether to allow property references
* @return OLAP object or property reference
*/
public static Exp lookup(
Query q, String[] nameParts, boolean allowProp) {
// First, look for a calculated member defined in the query.
final String fullName = quoteMdxIdentifier(nameParts);
// Look for any kind of object (member, level, hierarchy,
// dimension) in the cube. Use a schema reader without restrictions.
final SchemaReader schemaReader = q.getSchemaReader(false);
OlapElement olapElement = schemaReader.lookupCompound(
q.getCube(), nameParts, false, Category.Unknown);
if (olapElement != null) {
Role role = q.getConnection().getRole();
if (!role.canAccess(olapElement)) {
olapElement = null;
}
}
if (olapElement == null) {
if (allowProp &&
nameParts.length > 1) {
String[] namePartsButOne = new String[nameParts.length - 1];
System.arraycopy(nameParts, 0,
namePartsButOne, 0,
nameParts.length - 1);
final String propertyName = nameParts[nameParts.length - 1];
olapElement = schemaReader.lookupCompound(
q.getCube(), namePartsButOne, false, Category.Member);
if (olapElement != null &&
isValidProperty((Member) olapElement, propertyName)) {
return new FunCall(
propertyName, Syntax.Property, new Exp[] {
olapElement});
}
}
throw MondrianResource.instance().MdxChildObjectNotFound.ex(
fullName, q.getCube().getQualifiedName());
}
return olapElement;
}
/**
* Finds a root member of a hierarchy with a given name.
*
* @param hierarchy
* @param memberName
* @return Member, or null if not found
*/
public static Member lookupHierarchyRootMember(SchemaReader reader,
Hierarchy hierarchy,
String memberName) {
// Lookup member at first level.
Member[] rootMembers = reader.getHierarchyRootMembers(hierarchy);
for (int i = 0; i < rootMembers.length; i++) {
if (rootMembers[i].getName().equalsIgnoreCase(memberName)) {
return rootMembers[i];
}
}
// If the first level is 'all', lookup member at second level. For
// example, they could say '[USA]' instead of '[(All
// Customers)].[USA]'.
return (rootMembers.length == 1 && rootMembers[0].isAll())
? lookupMemberChildByName(reader, rootMembers[0], memberName)
: null;
}
/**
* Finds a named level in this hierarchy. Returns null if there is no
* such level.
*/
public static Level lookupHierarchyLevel(Hierarchy hierarchy, String s) {
final Level[] levels = hierarchy.getLevels();
for (int i = 0; i < levels.length; i++) {
if (levels[i].getName().equalsIgnoreCase(s)) {
return levels[i];
}
}
return null;
}
/**
* Finds a child of a member with a given name.
*/
public static Member lookupMemberChildByName(
SchemaReader reader, Member member, String memberName) {
Member[] children = reader.getMemberChildren(member);
// TODO: Linear search may be a performance problem.
for (int i = 0; i < children.length; i++){
final Member child = children[i];
if (Util.equals(child.getName(), memberName)) {
return child;
}
}
return null;
}
/**
* Finds the zero based ordinal of a Member among its siblings.
*/
public static int getMemberOrdinalInParent(SchemaReader reader,
Member member) {
Member parent = member.getParentMember();
Member[] siblings = (parent == null)
? reader.getHierarchyRootMembers(member.getHierarchy())
: reader.getMemberChildren(parent);
for (int i = 0; i < siblings.length; i++) {
if (siblings[i] == member) {
return i;
}
}
throw Util.newInternal(
"could not find member " + member + " amongst its siblings");
}
/**
* returns the first descendant on the level underneath parent.
* If parent = [Time].[1997] and level = [Time].[Month], then
* the member [Time].[1997].[Q1].[1] will be returned
*/
public static Member getFirstDescendantOnLevel(SchemaReader reader,
Member parent,
Level level) {
Member m = parent;
while (m.getLevel() != level) {
Member[] children = reader.getMemberChildren(m);
m = children[0];
}
return m;
}
/**
* Returns whether a string is null or empty.
*/
public static boolean isEmpty(String s) {
return (s == null) || (s.length() == 0);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?