// 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+"); }