// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.sdk.internal.wip;
import java.util.regex.Pattern;
import org.json.simple.JSONValue;
/**
* Builder for fully qualified name strings.
*/
public class WipExpressionBuilder {
/**
* Holds a value short name and optionally a qualified name builder.
*/
public interface ValueNameBuilder {
String getShortName();
/**
* @return value qualified name builder or null if there's no qualified name for the value
*/
QualifiedNameBuilder getQualifiedNameBuilder();
}
/**
* Builds a qualified name of some value.
*/
public interface QualifiedNameBuilder {
void append(StringBuilder output);
/**
* @return whether the qualified name should be enclosed before putting inside a bigger
* expression
*/
boolean needsParentheses();
}
/**
* Builds a qualified name of a property of some object.
*/
interface PropertyNameBuilder {
void build(String name, StringBuilder output);
/**
* @return whether the qualified name should be enclosed before putting inside a bigger
* expression
*/
boolean needsParentheses();
}
/**
* Combines property name with a {@link PropertyNameBuilder}.
*/
static ValueNameBuilder createValueOfPropertyNameBuilder(final String propertyName,
final PropertyNameBuilder propertyNameBuilder) {
final QualifiedNameBuilder qualifiedNameBuilder;
if (propertyNameBuilder == null) {
qualifiedNameBuilder = null;
} else {
qualifiedNameBuilder = new QualifiedNameBuilder() {
@Override public boolean needsParentheses() {
return propertyNameBuilder.needsParentheses();
}
@Override public void append(StringBuilder output) {
propertyNameBuilder.build(propertyName, output);
}
};
}
return new ValueNameBuilder() {
@Override public String getShortName() {
return propertyName;
}
@Override public QualifiedNameBuilder getQualifiedNameBuilder() {
return qualifiedNameBuilder;
}
};
}
static ValueNameBuilder createRootName(final String name, final boolean needsParentheses) {
final QualifiedNameBuilder qualifiedNameBuilder = new QualifiedNameBuilder() {
@Override
public void append(StringBuilder output) {
output.append(name);
}
@Override
public boolean needsParentheses() {
return needsParentheses;
}
};
return new ValueNameBuilder() {
@Override public String getShortName() {
return name;
}
@Override public QualifiedNameBuilder getQualifiedNameBuilder() {
return qualifiedNameBuilder;
}
};
}
public static ValueNameBuilder createRootNameNoDerived(final String name) {
return new ValueNameBuilder() {
@Override public String getShortName() {
return name;
}
@Override public QualifiedNameBuilder getQualifiedNameBuilder() {
return null;
}
};
}
/**
* Builder for a qualified name of some object.
*/
static class ObjectPropertyNameBuilder implements PropertyNameBuilder {
private final QualifiedNameBuilder objectNameBuilder;
ObjectPropertyNameBuilder(QualifiedNameBuilder objectNameBuilder) {
this.objectNameBuilder = objectNameBuilder;
}
@Override
public void build(String name, StringBuilder output) {
buildParentRef(output);
if (ALL_DIGITS.matcher(name).matches()) {
output.append("[").append(name).append("]");
} else {
// TODO(peter.rybin): check that name is really a valid identifier.
boolean isNameSimple = name.indexOf(' ') != -1;
if (isNameSimple) {
output.append(".").append(name);
} else {
output.append("[\"").append(JSONValue.escape(name)).append("\"]");
}
}
}
private void buildParentRef(StringBuilder output) {
if (objectNameBuilder.needsParentheses()) {
output.append('(');
objectNameBuilder.append(output);
output.append(')');
} else {
objectNameBuilder.append(output);
}
}
@Override
public boolean needsParentheses() {
return false;
}
}
static final Pattern ALL_DIGITS = Pattern.compile("\\d+");
}