001/* 002 * (C) Copyright 2017 Nuxeo (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Florent Guillaume 018 */ 019package org.nuxeo.ecm.core.query.sql.model; 020 021import java.util.ArrayList; 022import java.util.Arrays; 023import java.util.List; 024import java.util.Map.Entry; 025 026import org.nuxeo.ecm.core.query.QueryParseException; 027 028/** 029 * Transforms a query into the same query, doing a copy in the process. 030 * <p> 031 * Can be used as a base class for more complex transformations. 032 * 033 * @since 9.10 034 */ 035public class IdentityQueryTransformer implements QueryTransformer { 036 037 @Override 038 public SQLQuery transform(SQLQuery node) { 039 SelectClause select = transform(node.select); 040 FromClause from = transform(node.from); 041 WhereClause where = transform(node.where); 042 GroupByClause groupBy = transform(node.groupBy); 043 HavingClause having = transform(node.having); 044 OrderByClause orderBy = transform(node.orderBy); 045 long limit = transformLimit(node.limit); 046 long offset = transformOffset(node.offset); 047 return new SQLQuery(select, from, where, groupBy, having, orderBy, limit, offset); 048 } 049 050 @Override 051 public SelectClause transform(SelectClause node) { 052 return new SelectClause(transform(node.elements), node.distinct); 053 } 054 055 @Override 056 public SelectList transform(SelectList node) { 057 SelectList list = new SelectList(); 058 for (Entry<String, Operand> es : node.entrySet()) { 059 list.put(es.getKey(), transform(es.getValue())); 060 } 061 return list; 062 } 063 064 @Override 065 public FromClause transform(FromClause node) { 066 return new FromClause(transform(node.elements)); 067 } 068 069 @Override 070 public FromList transform(FromList node) { 071 FromList list = new FromList(); 072 list.putAll(node); 073 return list; 074 } 075 076 @Override 077 public WhereClause transform(WhereClause node) { 078 return new WhereClause(transform(node.predicate)); 079 } 080 081 @Override 082 public GroupByClause transform(GroupByClause node) { 083 if (node == null) { 084 return null; 085 } 086 String[] elements = node.elements; 087 if (elements != null) { 088 return new GroupByClause(Arrays.asList(elements)); 089 } else { 090 return new GroupByClause(); 091 } 092 } 093 094 @Override 095 public HavingClause transform(HavingClause node) { 096 if (node == null) { 097 return null; 098 } 099 return new HavingClause(transform(node.predicate)); 100 } 101 102 @Override 103 public OrderByClause transform(OrderByClause node) { 104 if (node == null) { 105 return null; 106 } 107 return new OrderByClause(transform(node.elements)); 108 } 109 110 @Override 111 public OrderByList transform(OrderByList node) { 112 OrderByList list = new OrderByList(null); // stupid constructor 113 list.clear(); 114 for (OrderByExpr value : node) { 115 list.add(transform(value)); 116 } 117 return list; 118 } 119 120 @Override 121 public OrderByExpr transform(OrderByExpr node) { 122 return new OrderByExpr(transform(node.reference), node.isDescending); 123 } 124 125 @Override 126 public long transformLimit(long limit) { 127 return limit; 128 } 129 130 @Override 131 public long transformOffset(long offset) { 132 return offset; 133 } 134 135 @Override 136 public Operand transform(Operand node) { 137 if (node instanceof Literal) { 138 return transform((Literal) node); 139 } else if (node instanceof LiteralList) { 140 return transform((LiteralList) node); 141 } else if (node instanceof Function) { 142 return transform((Function) node); 143 } else if (node instanceof Expression) { 144 return transform((Expression) node); 145 } else if (node instanceof Reference) { 146 return transform((Reference) node); 147 } else { 148 throw new QueryParseException("Unknown operand: " + node); 149 } 150 } 151 152 @Override 153 public Expression transform(Expression node) { 154 Expression expr = new Expression(transform(node.lvalue), transform(node.operator), transform(node.rvalue)); 155 expr.info = node.info; 156 return expr; 157 } 158 159 @Override 160 public Expression transform(MultiExpression node) { 161 List<Operand> list = new ArrayList<>(node.values.size()); 162 for (Operand o : node.values) { 163 list.add(transform(o)); 164 } 165 MultiExpression expr = new MultiExpression(transform(node.operator), list); 166 expr.info = node.info; 167 return expr; 168 } 169 170 @Override 171 public Operator transform(Operator node) { 172 return node; 173 } 174 175 @Override 176 public Reference transform(Reference node) { 177 Reference ref = new Reference(node.name, node.cast, node.esHint); 178 ref.info = node.info; 179 return ref; 180 } 181 182 @Override 183 public ReferenceList transform(ReferenceList node) { 184 ReferenceList list = new ReferenceList(); 185 for (Reference ref : node) { 186 list.add(transform(ref)); 187 } 188 return list; 189 } 190 191 @Override 192 public Operand transform(Function node) { 193 return new Function(node.name, transform(node.args)); 194 } 195 196 @Override 197 public OperandList transform(OperandList node) { 198 OperandList list = new OperandList(); 199 for (Operand oper : node) { 200 list.add(transform(oper)); 201 } 202 return list; 203 } 204 205 @Override 206 public Literal transform(Literal node) { 207 if (node instanceof BooleanLiteral) { 208 return transform((BooleanLiteral) node); 209 } else if (node instanceof DateLiteral) { 210 return transform((DateLiteral) node); 211 } else if (node instanceof DoubleLiteral) { 212 return transform((DoubleLiteral) node); 213 } else if (node instanceof IntegerLiteral) { 214 return transform((IntegerLiteral) node); 215 } else if (node instanceof StringLiteral) { 216 return transform((StringLiteral) node); 217 } else { 218 throw new QueryParseException("Unknown literal: " + node); 219 } 220 } 221 222 @Override 223 public LiteralList transform(LiteralList node) { 224 LiteralList list = new LiteralList(); 225 for (Literal lit : node) { 226 list.add(transform(lit)); 227 } 228 return list; 229 } 230 231 @Override 232 public Literal transform(BooleanLiteral node) { 233 return node; 234 } 235 236 @Override 237 public Literal transform(DateLiteral node) { 238 return node; 239 } 240 241 @Override 242 public Literal transform(DoubleLiteral node) { 243 return node; 244 } 245 246 @Override 247 public Literal transform(IntegerLiteral node) { 248 return node; 249 } 250 251 @Override 252 public Literal transform(StringLiteral node) { 253 return node; 254 } 255 256}