/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.googlecode.android_scripting.language;
import com.googlecode.android_scripting.rpc.MethodDescriptor;
import com.googlecode.android_scripting.rpc.ParameterDescriptor;
import java.util.HashMap;
import java.util.Map;
/**
* Represents the programming language supported by the SL4A.
*
*/
public class Language {
private final static Map<Character, String> AUTO_CLOSE_MAP = buildAutoCloseMap('[', "[]", '{',
"{}", '(', "()", '\'', "''", '"', "\"\"");
/** Returns the initial template for newly created script. */
public String getContentTemplate() {
StringBuilder content = new StringBuilder(getImportStatement());
if (content.length() != 0) {
content.append('\n');
}
content.append(getRpcReceiverDeclaration(getDefaultRpcReceiver()));
return content.toString();
}
/** Returns the Android package import statement. */
protected String getImportStatement() {
return "";
}
/** Returns the RPC receiver declaration. */
protected String getRpcReceiverDeclaration(String rpcReceiver) {
return "";
}
/** Returns the default RPC receiver name. */
protected String getDefaultRpcReceiver() {
return "droid";
}
/**
* Returns the string containing opening and closing tokens if the input is an opening token.
* Returns {@code null} otherwise.
*/
public String autoClose(char token) {
return AUTO_CLOSE_MAP.get(token);
}
/** Returns the RPC call text with given parameter values. */
public final String getRpcText(String content, MethodDescriptor rpc, String[] values) {
return getMethodCallText(getRpcReceiverName(content), rpc.getName(),
rpc.getParameterValues(values));
}
/** Returns the RPC receiver found in the given script. */
protected String getRpcReceiverName(String content) {
return getDefaultRpcReceiver();
}
/** Returns the method call text in the language. */
protected String getMethodCallText(String receiver, String method,
ParameterDescriptor[] parameters) {
StringBuilder result =
new StringBuilder().append(getApplyReceiverText(receiver)).append(getApplyOperatorText())
.append(method).append(getLeftParametersText());
String separator = "";
for (ParameterDescriptor parameter : parameters) {
result.append(separator).append(getValueText(parameter));
separator = getParameterSeparator();
}
result.append(getRightParametersText());
return result.toString();
}
/** Returns the apply receiver text. */
protected String getApplyReceiverText(String receiver) {
return receiver;
}
/** Returns the apply operator text. */
protected String getApplyOperatorText() {
return ".";
}
/** Returns the text to the left of the parameters. */
protected String getLeftParametersText() {
return "(";
}
/** Returns the text to the right of the parameters. */
protected String getRightParametersText() {
return ")";
}
/** Returns the parameter separator text. */
protected String getParameterSeparator() {
return ", ";
}
/** Returns the text of the quotation. */
protected String getQuote() {
return "\"";
}
/** Returns the text of the {@code null} value. */
protected String getNull() {
return "null";
}
/** Returns the text of the {{@code true} value. */
protected String getTrue() {
return "true";
}
/** Returns the text of the false value. */
protected String getFalse() {
return "false";
}
/** Returns the parameter value suitable for code generation. */
protected String getValueText(ParameterDescriptor parameter) {
if (parameter.getValue() == null) {
return getNullValueText();
} else if (parameter.getType().equals(String.class)) {
return getStringValueText(parameter.getValue());
} else if (parameter.getType().equals(Boolean.class)) {
return getBooleanValueText(parameter.getValue());
} else {
return parameter.getValue();
}
}
/** Returns the null value suitable for code generation. */
private String getNullValueText() {
return getNull();
}
/** Returns the string parameter value suitable for code generation. */
protected String getStringValueText(String value) {
// TODO(igorkarp): do not quote expressions once they could be detected.
return getQuote() + value + getQuote();
}
/** Returns the boolean parameter value suitable for code generation. */
protected String getBooleanValueText(String value) {
if (value.equals(Boolean.TRUE.toString())) {
return getTrue();
} else if (value.equals(Boolean.FALSE.toString())) {
return getFalse();
} else {
// If it is neither true nor false it is must be an expression.
return value;
}
}
private static Map<Character, String> buildAutoCloseMap(char c1, String s1, char c2, String s2,
char c3, String s3, char c4, String s4, char c5, String s5) {
Map<Character, String> map = new HashMap<Character, String>(5);
map.put(c1, s1);
map.put(c2, s2);
map.put(c3, s3);
map.put(c4, s4);
map.put(c5, s5);
return map;
}
}