/* * Copyright 2001-2008 Geert Bevin (gbevin[remove] at uwyn dot com) * Licensed under the Apache License, Version 2.0 (the "License") * $Id: QueryParameters.java 3918 2008-04-14 17:35:35Z gbevin $ */ package com.uwyn.rife.database.queries; import java.util.*; import com.uwyn.rife.database.exceptions.DatabaseException; import com.uwyn.rife.database.queries.QueryParameterType; import com.uwyn.rife.tools.ArrayUtils; public class QueryParameters implements Cloneable { private AbstractParametrizedQuery mQuery = null; private Map<QueryParameterType, Object> mParameters = null; private List<String> mCombinedParameters = null; private String[] mCombinedParametersArray = null; public QueryParameters(AbstractParametrizedQuery query) { if (null == query) throw new IllegalArgumentException("query can't be null"); mQuery = query; } public QueryParameters getNewInstance() { return new QueryParameters(mQuery); } public int getNumberOfTypes() { if (null == mParameters) { return 0; } return mParameters.size(); } public void clear() { mParameters = null; mCombinedParameters = null; mCombinedParametersArray = null; } public boolean hasParameter(QueryParameterType type, String value) { if (null == type || null == value || null == mParameters) { return false; } if (!mParameters.containsKey(type)) { return false; } if (type.isSingular()) { return value.equals(mParameters.get(type)); } else { List<String> list = (List<String>)mParameters.get(type); if (null == list) { return false; } return list.contains(value); } } public Set<String> getDistinctNames() { if (null == mParameters || 0 == mParameters.size()) { return null; } HashSet<String> names = new HashSet<String>(); for (Map.Entry<QueryParameterType, Object> entry : mParameters.entrySet()) { if (entry.getKey().isSingular()) { names.add((String)entry.getValue()); } else { names.addAll((List<String>)entry.getValue()); } } return names; } public List<String> getOrderedNames() { if (null == mCombinedParameters) { ArrayList<String> combined_parameters = null; if (mParameters != null && mParameters.size() > 0) { if (mParameters.containsKey(QueryParameterType.FIELD)) { combined_parameters = new ArrayList<String>(); for (String parameter : (List<String>)mParameters.get(QueryParameterType.FIELD)) { // add the parameter to the combined list combined_parameters.add(parameter); } } if (mParameters.containsKey(QueryParameterType.TABLE)) { if (null == combined_parameters) { combined_parameters = new ArrayList<String>(); } for (String parameter : (List<String>)mParameters.get(QueryParameterType.TABLE)) { // add the parameter to the combined list combined_parameters.add(parameter); } } if (mParameters.containsKey(QueryParameterType.WHERE)) { if (null == combined_parameters) { combined_parameters = new ArrayList<String>(); } for (String parameter : (List<String>)mParameters.get(QueryParameterType.WHERE)) { // add the parameter to the combined list combined_parameters.add(parameter); } } if (mParameters.containsKey(QueryParameterType.UNION)) { if (null == combined_parameters) { combined_parameters = new ArrayList<String>(); } for (String parameter : (List<String>)mParameters.get(QueryParameterType.UNION)) { // add the parameter to the combined list combined_parameters.add(parameter); } } if (mParameters.containsKey(QueryParameterType.LIMIT) || mParameters.containsKey(QueryParameterType.OFFSET)) { if (mQuery.isLimitBeforeOffset()) { if (mParameters.containsKey(QueryParameterType.LIMIT)) { if (null == combined_parameters) { combined_parameters = new ArrayList<String>(); } // get the parameter value String value = (String)mParameters.get(QueryParameterType.LIMIT); // add the parameter to the combined list combined_parameters.add(value); } if (mParameters.containsKey(QueryParameterType.OFFSET)) { if (null == combined_parameters) { combined_parameters = new ArrayList<String>(); } // get the parameter value String value = (String)mParameters.get(QueryParameterType.OFFSET); // add the parameter to the combined list combined_parameters.add(value); } } else { if (mParameters.containsKey(QueryParameterType.OFFSET)) { if (null == combined_parameters) { combined_parameters = new ArrayList<String>(); } // get the parameter value String value = (String)mParameters.get(QueryParameterType.OFFSET); // add the parameter to the combined list combined_parameters.add(value); } if (mParameters.containsKey(QueryParameterType.LIMIT)) { if (null == combined_parameters) { combined_parameters = new ArrayList<String>(); } // get the parameter value String value = (String)mParameters.get(QueryParameterType.LIMIT); // add the parameter to the combined list combined_parameters.add(value); } } } } mCombinedParameters = combined_parameters; mCombinedParametersArray = null; } return mCombinedParameters; } private void addVirtualIndexMapping(QueryParameters virtualParameters, Map<Integer, Integer> map, int[] parameterIndex, int[] realIndex, QueryParameterType type, String parameter) { if (virtualParameters.hasParameter(type, parameter)) { map.put(parameterIndex[0], -1); } else { map.put(parameterIndex[0], realIndex[0]); realIndex[0]++; } parameterIndex[0]++; } public Map<Integer, Integer> getVirtualIndexMapping(QueryParameters virtualParameters) { Map<Integer, Integer> map = null; if (mParameters != null && mParameters.size() > 0 && virtualParameters != null && virtualParameters.getNumberOfTypes() > 0) { map = new HashMap<Integer, Integer>(); int[] parameter_index = new int[] {1}; int[] real_index = new int[] {1}; if (mParameters.containsKey(QueryParameterType.FIELD)) { for (String parameter : (List<String>)mParameters.get(QueryParameterType.FIELD)) { addVirtualIndexMapping(virtualParameters, map, parameter_index, real_index, QueryParameterType.FIELD, parameter); } } if (mParameters.containsKey(QueryParameterType.TABLE)) { for (String parameter : (List<String>)mParameters.get(QueryParameterType.TABLE)) { addVirtualIndexMapping(virtualParameters, map, parameter_index, real_index, QueryParameterType.TABLE, parameter); } } if (mParameters.containsKey(QueryParameterType.WHERE)) { for (String parameter : (List<String>)mParameters.get(QueryParameterType.WHERE)) { addVirtualIndexMapping(virtualParameters, map, parameter_index, real_index, QueryParameterType.WHERE, parameter); } } if (mParameters.containsKey(QueryParameterType.UNION)) { for (String parameter : (List<String>)mParameters.get(QueryParameterType.UNION)) { addVirtualIndexMapping(virtualParameters, map, parameter_index, real_index, QueryParameterType.UNION, parameter); } } if (mParameters.containsKey(QueryParameterType.LIMIT) || mParameters.containsKey(QueryParameterType.OFFSET)) { if (mQuery.isLimitBeforeOffset()) { if (mParameters.containsKey(QueryParameterType.LIMIT)) { String parameter = (String)mParameters.get(QueryParameterType.LIMIT); addVirtualIndexMapping(virtualParameters, map, parameter_index, real_index, QueryParameterType.LIMIT, parameter); } if (mParameters.containsKey(QueryParameterType.OFFSET)) { String parameter = (String)mParameters.get(QueryParameterType.OFFSET); addVirtualIndexMapping(virtualParameters, map, parameter_index, real_index, QueryParameterType.OFFSET, parameter); } } else { if (mParameters.containsKey(QueryParameterType.OFFSET)) { String parameter = (String)mParameters.get(QueryParameterType.OFFSET); addVirtualIndexMapping(virtualParameters, map, parameter_index, real_index, QueryParameterType.OFFSET, parameter); } if (mParameters.containsKey(QueryParameterType.LIMIT)) { String parameter = (String)mParameters.get(QueryParameterType.LIMIT); addVirtualIndexMapping(virtualParameters, map, parameter_index, real_index, QueryParameterType.LIMIT, parameter); } } } } return map; } public String[] getOrderedNamesArray() { if (null == mParameters || 0 == mParameters.size()) { return null; } if (null == mCombinedParametersArray) { String[] array = new String[0]; for (String parameter_name : getOrderedNames()) { array = ArrayUtils.join(array, parameter_name); } mCombinedParametersArray = array; } return mCombinedParametersArray; } private void clearCombinedParameters() { mCombinedParameters = null; mCombinedParametersArray = null; } public void clearTypedParameters(QueryParameterType type) { if (null == type) throw new IllegalArgumentException("the parameter type can't be null"); if (null == mParameters) { return; } mParameters.remove(type); clearCombinedParameters(); } public <T> T getTypedParameters(QueryParameterType type) { if (null == type) throw new IllegalArgumentException("the parameter type can't be null"); if (null == mParameters) { return null; } return (T)mParameters.get(type); } public void addTypedParameters(QueryParameterType type, List<String> parameters) { if (null == type) throw new IllegalArgumentException("the parameter type can't be null"); if (type.isSingular()) throw new IllegalArgumentException("the parameter type '"+type+"' only supports a singular value"); // don't add empty parameters if (null == parameters || 0 == parameters.size()) { return; } // obtain the existing typed parameters List<String> typed_parameters = null; if (null == mParameters) { mParameters = new HashMap<QueryParameterType, Object>(); } else { typed_parameters = (List<String>)mParameters.get(type); } // initialize the typed parameters collection if it didn't exist before boolean new_collection = false; if (null == typed_parameters) { typed_parameters = new ArrayList<String>(); new_collection = true; } // add the new parameters typed_parameters.addAll(parameters); if (new_collection) { mParameters.put(type, typed_parameters); } // clear the already calculated combined parameters clearCombinedParameters(); } public void addTypedParameter(QueryParameterType type, String value) { if (null == type) throw new IllegalArgumentException("the parameter type can't be null"); if (value != null) { // initialize the parameters map if it doesn't exist yet if (null == mParameters) { mParameters = new HashMap<QueryParameterType, Object>(); } // remove the table-field separator dot if (value.indexOf(".") != -1) { value = value.substring(value.lastIndexOf(".")+1); } } // check if the parameter is singular if (type.isSingular()) { // empty singular parameters clear out the key if (null == value) { if (null == mParameters) { return; } mParameters.remove(type); } // store the singular parameter else { mParameters.put(type, value); } } else { // don't add empty parameters if (null == value) { return; } // obtain the existing typed parameters List<String> typed_parameters = (List<String>)mParameters.get(type); // initialize the typed parameters collection if it didn't exist before boolean new_collection = false; if (null == typed_parameters) { typed_parameters = new ArrayList<String>(); new_collection = true; } // add the new parameters typed_parameters.add(value); // store the new collection if it has been allocated if (new_collection) { mParameters.put(type, typed_parameters); } } // clear the already calculated combined parameters clearCombinedParameters(); } public QueryParameters clone() { QueryParameters new_instance = null; try { new_instance = (QueryParameters)super.clone(); } catch (CloneNotSupportedException e) { throw new DatabaseException(e); } if (new_instance != null) { if (mCombinedParameters != null) { new_instance.mCombinedParameters = new ArrayList<String>(); new_instance.mCombinedParameters.addAll(mCombinedParameters); } if (mParameters != null) { new_instance.mParameters = new HashMap<QueryParameterType, Object>(); for (Map.Entry<QueryParameterType, Object> entry : mParameters.entrySet()) { if (entry.getKey().isSingular()) { new_instance.mParameters.put(entry.getKey(), entry.getValue()); } else { List<String> values = new ArrayList<String>(); values.addAll((List<String>)entry.getValue()); new_instance.mParameters.put(entry.getKey(), values); } } } } return new_instance; } }