/*
* Copyright 2015, The Querydsl Team (http://www.querydsl.com/team)
*
* 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.querydsl.core.types;
import java.util.Arrays;
import java.util.List;
/**
* {@code ToStringVisitor} is used for toString() serialization in {@link Expression} implementations.
*
* @author tiwe
*/
public final class ToStringVisitor implements Visitor<String,Templates> {
public static final ToStringVisitor DEFAULT = new ToStringVisitor();
private ToStringVisitor() { }
@Override
public String visit(Constant<?> e, Templates templates) {
return e.getConstant().toString();
}
@Override
public String visit(FactoryExpression<?> e, Templates templates) {
final StringBuilder builder = new StringBuilder();
builder.append("new ").append(e.getType().getSimpleName()).append("(");
boolean first = true;
for (Expression<?> arg : e.getArgs()) {
if (!first) {
builder.append(", ");
}
builder.append(arg.accept(this, templates));
first = false;
}
builder.append(")");
return builder.toString();
}
@Override
public String visit(Operation<?> o, Templates templates) {
final Template template = templates.getTemplate(o.getOperator());
if (template != null) {
final int precedence = templates.getPrecedence(o.getOperator());
final StringBuilder builder = new StringBuilder();
for (Template.Element element : template.getElements()) {
final Object rv = element.convert(o.getArgs());
if (rv instanceof Expression) {
if (precedence > -1 && rv instanceof Operation) {
if (precedence < templates.getPrecedence(((Operation<?>) rv).getOperator())) {
builder.append("(");
builder.append(((Expression<?>) rv).accept(this, templates));
builder.append(")");
continue;
}
}
builder.append(((Expression<?>) rv).accept(this, templates));
} else {
builder.append(rv.toString());
}
}
return builder.toString();
} else {
return "unknown operation with operator " + o.getOperator().name() + " and args " + o.getArgs();
}
}
@Override
public String visit(ParamExpression<?> param, Templates templates) {
return "{" + param.getName() + "}";
}
@Override
public String visit(Path<?> p, Templates templates) {
final Path<?> parent = p.getMetadata().getParent();
final Object elem = p.getMetadata().getElement();
if (parent != null) {
Template pattern = templates.getTemplate(p.getMetadata().getPathType());
if (pattern != null) {
final List<?> args = Arrays.asList(parent, elem);
final StringBuilder builder = new StringBuilder();
for (Template.Element element : pattern.getElements()) {
Object rv = element.convert(args);
if (rv instanceof Expression) {
builder.append(((Expression<?>) rv).accept(this, templates));
} else {
builder.append(rv.toString());
}
}
return builder.toString();
} else {
throw new IllegalArgumentException("No pattern for " + p.getMetadata().getPathType());
}
} else {
return elem.toString();
}
}
@Override
public String visit(SubQueryExpression<?> expr, Templates templates) {
return expr.getMetadata().toString();
}
@Override
public String visit(TemplateExpression<?> expr, Templates templates) {
final StringBuilder builder = new StringBuilder();
for (Template.Element element : expr.getTemplate().getElements()) {
Object rv = element.convert(expr.getArgs());
if (rv instanceof Expression) {
builder.append(((Expression<?>) rv).accept(this, templates));
} else {
builder.append(rv.toString());
}
}
return builder.toString();
}
}