JsonFunction.java
/*-
* #%L
* JSQLParser library
* %%
* Copyright (C) 2004 - 2019 JSQLParser
* %%
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
* #L%
*/
package net.sf.jsqlparser.expression;
import java.util.ArrayList;
import java.util.Objects;
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
/**
* @author <a href="mailto:andreas@manticore-projects.com">Andreas Reichel</a>
*/
public class JsonFunction extends ASTNodeAccessImpl implements Expression {
private final ArrayList<JsonKeyValuePair> keyValuePairs = new ArrayList<>();
private final ArrayList<JsonFunctionExpression> expressions = new ArrayList<>();
private JsonFunctionType functionType;
private JsonAggregateOnNullType onNullType;
private JsonAggregateUniqueKeysType uniqueKeysType;
public ArrayList<JsonKeyValuePair> getKeyValuePairs() {
return keyValuePairs;
}
public ArrayList<JsonFunctionExpression> getExpressions() {
return expressions;
}
public JsonKeyValuePair getKeyValuePair(int i) {
return keyValuePairs.get(i);
}
public JsonFunctionExpression getExpression(int i) {
return expressions.get(i);
}
public boolean add(JsonKeyValuePair keyValuePair) {
return keyValuePairs.add(keyValuePair);
}
public void add(int i, JsonKeyValuePair keyValuePair) {
keyValuePairs.add(i, keyValuePair);
}
public boolean add(JsonFunctionExpression expression) {
return expressions.add(expression);
}
public void add(int i, JsonFunctionExpression expression) {
expressions.add(i, expression);
}
public boolean isEmpty() {
return keyValuePairs.isEmpty();
}
public JsonAggregateOnNullType getOnNullType() {
return onNullType;
}
public void setOnNullType(JsonAggregateOnNullType onNullType) {
this.onNullType = onNullType;
}
public JsonFunction withOnNullType(JsonAggregateOnNullType onNullType) {
this.setOnNullType(onNullType);
return this;
}
public JsonAggregateUniqueKeysType getUniqueKeysType() {
return uniqueKeysType;
}
public void setUniqueKeysType(JsonAggregateUniqueKeysType uniqueKeysType) {
this.uniqueKeysType = uniqueKeysType;
}
public JsonFunction withUniqueKeysType(JsonAggregateUniqueKeysType uniqueKeysType) {
this.setUniqueKeysType(uniqueKeysType);
return this;
}
public JsonFunctionType getType() {
return functionType;
}
public void setType(JsonFunctionType type) {
this.functionType =
Objects.requireNonNull(type,
"The Type of the JSON Aggregate Function must not be null");
}
public void setType(String typeName) {
this.functionType = JsonFunctionType.valueOf(
Objects.requireNonNull(typeName,
"The Type of the JSON Aggregate Function must not be null")
.toUpperCase());
}
public JsonFunction withType(JsonFunctionType type) {
this.setType(type);
return this;
}
public JsonFunction withType(String typeName) {
this.setType(typeName);
return this;
}
@Override
public <T, S> T accept(ExpressionVisitor<T> expressionVisitor, S context) {
return expressionVisitor.visit(this, context);
}
// avoid countless Builder --> String conversion
public StringBuilder append(StringBuilder builder) {
switch (functionType) {
case OBJECT:
appendObject(builder);
break;
case POSTGRES_OBJECT:
appendPostgresObject(builder);
break;
case MYSQL_OBJECT:
appendMySqlObject(builder);
break;
case ARRAY:
appendArray(builder);
break;
default:
// this should never happen really
}
return builder;
}
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
public StringBuilder appendObject(StringBuilder builder) {
builder.append("JSON_OBJECT( ");
int i = 0;
for (JsonKeyValuePair keyValuePair : keyValuePairs) {
if (i > 0) {
builder.append(", ");
}
if (keyValuePair.isUsingValueKeyword()) {
if (keyValuePair.isUsingKeyKeyword()) {
builder.append("KEY ");
}
builder.append(keyValuePair.getKey()).append(" VALUE ")
.append(keyValuePair.getValue());
} else {
builder.append(keyValuePair.getKey()).append(":").append(keyValuePair.getValue());
}
if (keyValuePair.isUsingFormatJson()) {
builder.append(" FORMAT JSON");
}
i++;
}
if (onNullType != null) {
switch (onNullType) {
case NULL:
builder.append(" NULL ON NULL");
break;
case ABSENT:
builder.append(" ABSENT On NULL");
break;
default:
// this should never happen
}
}
if (uniqueKeysType != null) {
switch (uniqueKeysType) {
case WITH:
builder.append(" WITH UNIQUE KEYS");
break;
case WITHOUT:
builder.append(" WITHOUT UNIQUE KEYS");
break;
default:
// this should never happen
}
}
builder.append(" ) ");
return builder;
}
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
public StringBuilder appendPostgresObject(StringBuilder builder) {
builder.append("JSON_OBJECT( ");
for (JsonKeyValuePair keyValuePair : keyValuePairs) {
builder.append(keyValuePair.getKey());
if (keyValuePair.getValue() != null) {
builder.append(", ").append(keyValuePair.getValue());
}
}
builder.append(" ) ");
return builder;
}
public StringBuilder appendMySqlObject(StringBuilder builder) {
builder.append("JSON_OBJECT( ");
int i = 0;
for (JsonKeyValuePair keyValuePair : keyValuePairs) {
if (i > 0) {
builder.append(", ");
}
builder.append(keyValuePair.getKey());
builder.append(", ").append(keyValuePair.getValue());
i++;
}
builder.append(" ) ");
return builder;
}
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
public StringBuilder appendArray(StringBuilder builder) {
builder.append("JSON_ARRAY( ");
int i = 0;
for (JsonFunctionExpression expr : expressions) {
if (i > 0) {
builder.append(", ");
}
expr.append(builder);
i++;
}
if (onNullType != null) {
switch (onNullType) {
case NULL:
builder.append(" NULL ON NULL ");
break;
case ABSENT:
builder.append(" ABSENT ON NULL ");
break;
default:
// "ON NULL" was omitted
}
}
builder.append(") ");
return builder;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
return append(builder).toString();
}
}