/* * #! * Ontopia Engine * #- * Copyright (C) 2001 - 2013 The Ontopia 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 net.ontopia.persistence.query.jdo; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import net.ontopia.utils.OntopiaRuntimeException; import net.ontopia.utils.StringUtils; /** * INTERNAL: JDOQL complete query. Represents a complete JDO query. */ public class JDOQuery { protected JDOExpressionIF filter; protected boolean distinct = false; protected int limit = -1; protected int offset = -1; protected Map params; protected List param_names; protected Map variables; protected List select = new ArrayList(); // never empty protected List orderby; public JDOQuery() { } public boolean isSetQuery() { return (getFilter() instanceof JDOSetOperation); } public boolean getDistinct() { return distinct; } public void setDistinct(boolean distinct) { this.distinct = distinct; } public int getLimit() { return limit; } public void setLimit(int limit) { this.limit = limit; } public int getOffset() { return offset; } public void setOffset(int offset) { this.offset = offset; } public List getParameterNames() { if (param_names == null) return Collections.EMPTY_LIST; else return param_names; } public boolean hasParameterName(String name) { if (params == null) return false; return params.containsKey(name); } public Class getParameterType(String name) { // Complain if parameter is unknown if (params == null || !params.containsKey(name)) throw new OntopiaRuntimeException("Parameter with name '" + name + "' does not exist."); return (Class)params.get(name); } public void addParameter(String name, Class klass) { if (klass == null) throw new NullPointerException("JDO parameter class must not be null."); // Must be unique. Hides candidate class fields. Not 'this'. checkExistingName(name); if (params == null) params = new HashMap(); params.put(name, klass); if (param_names == null) param_names = new ArrayList(); param_names.add(name); } public int getVariableCount() { return (variables == null ? 0 : variables.size()); } public Collection getVariableNames() { if (variables == null) return Collections.EMPTY_SET; else return variables.keySet(); } public boolean hasVariableName(String name) { if (variables == null) return false; return variables.containsKey(name); } public Class getVariableType(String name) { // Complain if unknown variable if (variables == null || !variables.containsKey(name)) throw new OntopiaRuntimeException("JDO variable '" + name + "' does not exist."); return (Class)variables.get(name); } public void addVariable(String name, Class klass) { if (klass == null) throw new NullPointerException("The class of JDO variable '" + name + "' must not be null."); // Must be unique and not conflict with parameter names. Hides // candidate class fields. Not 'this'. checkExistingName(name); if (variables == null) variables = new HashMap(); variables.put(name, klass); } protected void checkExistingName(String name) throws RuntimeException { if (params != null && params.containsKey(name)) throw new OntopiaRuntimeException("Parameter with name '" + name + "' already exists."); if (variables != null && variables.containsKey(name)) throw new OntopiaRuntimeException("Variable with name '" + name + "' already exists."); } public JDOExpressionIF getFilter() { return filter; } public void setFilter(JDOExpressionIF filter) { this.filter = filter; } public List getSelect() { return select; } public String[] getSelectedColumnNames() { String[] colnames = new String[select.size()]; for (int i=0; i < colnames.length; i++) { Object selected = select.get(i); if (selected instanceof JDOVariable) colnames[i] = ((JDOVariable)selected).getName(); else if (selected instanceof JDOAggregate) colnames[i] = ((JDOVariable)((JDOAggregate)selected).getValue()).getName(); else throw new OntopiaRuntimeException("Not able to figure out column name."); } return colnames; } public void addSelect(JDOValueIF value) { select.add(value); } public void addSelect(JDOAggregateIF aggregate) { select.add(aggregate); } public List getOrderBy() { if (orderby == null) return Collections.EMPTY_LIST; else return orderby; } public void addOrderBy(JDOOrderBy job) { if (orderby == null) orderby = new ArrayList(); orderby.add(job); } public void addAscending(JDOValueIF value) { addOrderBy(new JDOOrderBy(value, JDOOrderBy.ASCENDING)); } public void addDescending(JDOValueIF value) { addOrderBy(new JDOOrderBy(value, JDOOrderBy.DESCENDING)); } public void addAscending(JDOAggregateIF aggregate) { addOrderBy(new JDOOrderBy(aggregate, JDOOrderBy.ASCENDING)); } public void addDescending(JDOAggregateIF aggregate) { addOrderBy(new JDOOrderBy(aggregate, JDOOrderBy.DESCENDING)); } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("select "); if (getDistinct()) sb.append("distinct "); if (select == null || select.isEmpty()) sb.append("*"); else StringUtils.join(select, ", ", sb); if (getFilter() != null) { sb.append(" from "); sb.append(getFilter()); } List _orderby = getOrderBy(); if (!_orderby.isEmpty()) { sb.append(" order by "); StringUtils.join(_orderby, ", ", sb); } return sb.toString(); } }