/* * 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.stanbol.entityhub.core.query; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.apache.stanbol.entityhub.servicesapi.query.Constraint; import org.apache.stanbol.entityhub.servicesapi.query.FieldQuery; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Default implementation of the FieldQuery interface. Note that the getter methods are defined as final. So * implementations that need to overwrite some functionality need to use the sets provided by this * implementation to store selected fields and field constraints. * * @author Rupert Westenthaler * */ public class FieldQueryImpl implements Cloneable, FieldQuery { @SuppressWarnings("unused") private static final Logger log = LoggerFactory.getLogger(FieldQueryImpl.class); private final Map<String,Constraint> queryConstraint = new HashMap<String,Constraint>(); private final Map<String,Constraint> unmodQueryElements = Collections.unmodifiableMap(queryConstraint); private final Set<String> selected = new HashSet<String>(); private final Set<String> unmodSelected = Collections.unmodifiableSet(selected); private Integer limit; private int offset; public FieldQueryImpl() { super(); } public void addSelectedField(String field) { if (field != null) { selected.add(field); } } public void addSelectedFields(Collection<String> fields) { if (fields != null) { selected.addAll(fields); } } public void removeSelectedField(String field) { if (field != null) { selected.remove(field); } } public void removeSelectedFields(Collection<String> fields) { if (fields != null) { selected.removeAll(fields); } } public final Set<String> getSelectedFields() { return unmodSelected; } public void setConstraint(String field, Constraint constraint) { if (null == field || field.isEmpty()) throw new IllegalArgumentException( "Parameter Field MUST NOT be NULL nor empty!"); if (constraint == null) { queryConstraint.remove(field); } else { queryConstraint.put(field, constraint); } } /** * Calls {@link #setConstraint(String, Constraint)} with <code>null</code> as {@link Constraint}. So * overwrite the setConstraint Method if needed. * * @see org.apache.stanbol.entityhub.core.query.FieldConstraint#removeConstraint(java.lang.String) */ public final void removeConstraint(String field) { setConstraint(field, null); } /* * (non-Javadoc) * * @see org.apache.stanbol.entityhub.core.query.FieldQuery#isConstraint(java. lang.String) */ public final boolean isConstrained(String field) { return queryConstraint.containsKey(field); } /* * (non-Javadoc) * * @see org.apache.stanbol.entityhub.core.query.FieldQuery#getConstraint(java .lang.String) */ public final Constraint getConstraint(String field) { return queryConstraint.get(field); } /* * (non-Javadoc) * * @see org.apache.stanbol.entityhub.core.query.FieldQuery#getConstraints() */ @Override public Set<Entry<String,Constraint>> getConstraints() { return unmodQueryElements.entrySet(); } @Override public final Iterator<Entry<String,Constraint>> iterator() { return unmodQueryElements.entrySet().iterator(); } @Override public String toString() { StringBuilder query = new StringBuilder(); query.append(String.format("Query Constraints (%d)\n", this.queryConstraint.size())); for (Entry<String,Constraint> entry : this.queryConstraint.entrySet()) { query.append(String.format("[key:: %s][%s]\n", entry.getKey(), entry.getValue().toString())); } query.append(String.format("unmod Query Elements (%d)\n", this.unmodQueryElements.size())); for (Entry<String,Constraint> entry : this.unmodQueryElements.entrySet()) { query.append(String.format("[key:: %s][%s]\n", entry.getKey(), entry.getValue().toString())); } query.append(String.format("Selected (%d)\n", this.selected.size())); for (String entry : this.selected) { query.append(String.format("[%s]", entry)); } query.append(String.format("unmod Selected (%d)\n", this.unmodSelected.size())); for (String entry : this.unmodSelected) { query.append(String.format("[%s]", entry)); } query.append(String.format("[limit :: %d]\n", this.limit)); query.append(String.format("[offset :: %d]\n", this.offset)); return query.toString(); } @Override public FieldQuery clone() { return copyTo(new FieldQueryImpl()); } /** * Uses the public API to clone the state of this instance to the instance provided as parameter. * * @param <C> * An implementation of the FieldQuery interface * @param copyTo * An instance to copy the state of this on. * @return The parsed instance */ public <C extends FieldQuery> C copyTo(C copyTo) { copyTo.removeAllConstraints(); copyTo.removeAllSelectedFields(); for (Entry<String,Constraint> entry : queryConstraint.entrySet()) { // we need not to copy keys or values, because everything is // immutable copyTo.setConstraint(entry.getKey(), entry.getValue()); } copyTo.addSelectedFields(selected); copyTo.setLimit(limit); copyTo.setOffset(offset); return copyTo; } @Override public void removeAllConstraints() { queryConstraint.clear(); } @Override public void removeAllSelectedFields() { selected.clear(); } @Override public final String getQueryType() { return FieldQuery.TYPE; } @Override public final Integer getLimit() { return limit; } @Override public final int getOffset() { return offset; } @Override public final void setLimit(Integer limit) { if (limit != null && limit.intValue() < 1) { limit = null; } this.limit = limit; } @Override public final void setOffset(int offset) { if (offset < 0) { offset = 0; } this.offset = offset; } @Override public int hashCode() { return queryConstraint.hashCode() + selected.hashCode() + offset + (limit != null ? limit : 0); } @Override public boolean equals(Object obj) { if (obj instanceof FieldQuery && ((FieldQuery) obj).getConstraints().equals(getConstraints()) && ((FieldQuery) obj).getSelectedFields().equals(getSelectedFields()) && ((FieldQuery) obj).getOffset() == getOffset()) { if (limit != null) { return limit.equals(((FieldQuery) obj).getLimit()); } else { return ((FieldQuery) obj).getLimit() == null; } } else { return false; } } }