/* $Id: QueryDescription.java 988245 2010-08-23 18:39:35Z kwright $ */ /** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.manifoldcf.core.database; import org.apache.manifoldcf.core.interfaces.*; import java.util.*; /** This object is immutable, and is used as a description for a cached query. */ public class QueryDescription extends org.apache.manifoldcf.core.cachemanager.BaseDescription { public static final String _rcsid = "@(#)$Id: QueryDescription.java 988245 2010-08-23 18:39:35Z kwright $"; // Store an id for the transaction, not the actual transaction handle. // We don't want to hold onto the actual open database handle! protected String databaseName; protected String query; protected List parameters; protected String criticalSectionName = null; protected String cacheClassName; protected StringSet keys; protected int maxReturn; protected ResultSpecification spec; protected ILimitChecker returnLimit; public QueryDescription(String databaseName, String query, List parameters, String cacheClassName, StringSet cacheKeys, int maxReturn, ResultSpecification spec, ILimitChecker returnLimit) { super(cacheClassName); this.databaseName = databaseName; this.query = query; this.parameters = null; if (parameters != null) { this.parameters = listClone(parameters); } keys = cacheKeys; this.maxReturn = maxReturn; this.spec = spec; if (returnLimit != null) { if (returnLimit.doesCompareWork()) this.returnLimit = returnLimit.duplicate(); else { this.returnLimit = returnLimit; // Also turn off caching keys = null; } } else this.returnLimit = null; } public String getQuery() { return query; } public List getParameters() { if (parameters == null) return null; return listClone(parameters); } public int getMaxReturn() { return maxReturn; } public ResultSpecification getResultSpecification() { return spec; } public ILimitChecker getReturnLimit() { return returnLimit; } public int hashCode() { int rval = databaseName.hashCode() + query.hashCode(); if (parameters != null) rval += parameters.hashCode(); if (cacheClassName != null) rval += cacheClassName.hashCode(); rval += maxReturn; if (spec != null) rval += spec.hashCode(); if (returnLimit != null && returnLimit.doesCompareWork()) rval += returnLimit.hashCode(); return rval; } public boolean equals(Object o) { if (!(o instanceof QueryDescription)) return false; QueryDescription other = (QueryDescription)o; // System.out.println("Matching query descriptions: "+this.getCriticalSectionName()+" against: "+other.getCriticalSectionName()); if (parameters == null || other.parameters == null) { if (parameters != null || other.parameters != null) return false; } else { if (!parameters.equals(other.parameters)) return false; } if (cacheClassName == null || other.cacheClassName == null) { if (cacheClassName != null || other.cacheClassName != null) return false; } else { if (!cacheClassName.equals(other.cacheClassName)) return false; } if (spec == null || other.spec == null) { if (spec != null || other.spec != null) return false; } else { if (!spec.equals(other.spec)) return false; } if (returnLimit == null || other.returnLimit == null) { if (returnLimit != null || other.returnLimit != null) return false; } else { if (returnLimit.doesCompareWork() == false || other.returnLimit.doesCompareWork() == false) return false; if (!returnLimit.equals(other.returnLimit)) return false; } if (databaseName == null || other.databaseName == null) { if (databaseName != null || other.databaseName != null) return false; } else { if (!databaseName.equals(other.databaseName)) return false; } return query.equals(other.query) && maxReturn == other.maxReturn; } /** Get the cache keys for an object (which may or may not exist yet in * the cache). This method is called in order for cache manager to throw the correct locks. * @return the object's cache keys, or null if the object should not * be cached. */ public StringSet getObjectKeys() { return keys; } public String getCriticalSectionName() { if (criticalSectionName == null) { StringBuilder sb = new StringBuilder(); if (databaseName != null) sb.append(databaseName); sb.append("-").append(getClass().getName()).append("-"); if (cacheClassName != null) sb.append(cacheClassName).append("-"); sb.append(query).append("-"); sb.append(Integer.toString(maxReturn)).append("-"); if (parameters != null) { int i = 0; while (i < parameters.size()) { sb.append(parameters.get(i++)).append("-"); } } // For the return specification, we can be specific. if (spec != null) sb.append(":").append(spec.toString()); // For return limit, we really can't be very specific. The critical section will therefore interact all // limited queries with out distinction about the kind of limit. if (returnLimit != null && returnLimit.doesCompareWork()) sb.append(":limited"); criticalSectionName = sb.toString(); } return criticalSectionName; } protected static List listClone(List list) { List rval = new ArrayList(list.size()); for (Object o : list) { rval.add(o); } return rval; } }