package org.gcube.common.clients.queries; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.gcube.common.clients.delegates.ProxyPlugin; import org.gcube.common.clients.exceptions.DiscoveryException; /** * Partial implementation of {@link Query}s. * * @author Fabio Simeoni * * @param the type of service addresses * @param the type of query results */ public abstract class AbstractQuery implements Query { private final ProxyPlugin plugin; private final Map conditions = new HashMap(); //default matcher does not filter out any result private ResultMatcher matcher = new ResultMatcher() { @Override public boolean match(R doc) { return true; } }; /** * Creates an instance with a {@link ISFacade}, a {@link PluginAdapter}, and a type of IS queries * @param facade the facade * @param plugin the plugin * @param queryClass the query type */ protected AbstractQuery(ProxyPlugin plugin) { this.plugin = plugin; } /** * Adds a condition to the query. * @param property an expression that identifies a property of service endpoints * @param value the value of the property */ public void addCondition(String property, String value) { this.conditions.put(property,value); } /** * Sets an {@link ResultMatcher} for the query. * @param matcher the matcher. */ public void setMatcher(ResultMatcher matcher) { this.matcher=matcher; } @Override public final List fire() throws DiscoveryException { //delegate actual execution to subclass-specific mechanisms List results = fire(conditions); //from results to addresses List endpoints = new ArrayList(); for (R result : results) try { if (matcher.match(result)) //should we include this? ask matcher endpoints.add(address(result)); //extract address } catch(IllegalArgumentException e) { //skip result, this is just a signal from subclasses }; return endpoints; } /** * Executes the query through implementation-specific means. * @param conditions the conditions to apply on the query prior to its execution * @return the query results * @throws DiscoveryException if the query could not be executed */ protected abstract List fire(Map conditions) throws DiscoveryException; /** * Returns an endpoint address from a query result. * @param result the result * @return the address * @throws IllegalArgumentException if an address cannot be derived from the result */ protected abstract A address(R result) throws IllegalArgumentException; /** * Returns the {@link ProxyPlugin}. * @return the plugin */ protected ProxyPlugin plugin() { return plugin; } //queries are value objects based on properties @Override public final boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; AbstractQuery other = (AbstractQuery) obj; if (conditions == null) { if (other.conditions != null) return false; } else if (!conditions.equals(other.conditions)) return false; return true; } @Override public final int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((conditions == null) ? 0 : conditions.hashCode()); return result; } @Override public final String toString() { return conditions.toString(); } }