Java tutorial
/* * #%L * Protempa Framework * %% * Copyright (C) 2012 - 2013 Emory University * %% * 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. * #L% */ package org.protempa.query; import java.io.Serializable; import java.util.Arrays; import java.util.UUID; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.builder.ToStringBuilder; import org.protempa.PropositionDefinition; import org.protempa.ProtempaUtil; import org.protempa.backend.dsb.filter.Filter; /** * Base query implementation. * * Queries are serializable provided that any filters that are set are also * serializable (see {@link #setFilters(org.protempa.dsb.filter.Filter)}). * * @author Andrew Post */ public class Query implements Serializable { public static QueryMode DEFAULT_QUERY_MODE = QueryMode.REPLACE; private static final long serialVersionUID = -9007995369064299652L; private static final PropositionDefinition[] EMPTY_PROP_DEF_ARRAY = new PropositionDefinition[0]; private final String[] keyIds; private final Filter filters; private final String[] propIds; private final And<String>[] termIds; private final PropositionDefinition[] propDefs; private String name; private String username; private QueryMode queryMode; /** * Creates new Query instance with a default identifier. * * @param keyIds An array of key IDs. If this is null then the query will * include all keyIDs. * @param filters A chain of filters. The first filter's getAnd method * returns the second filter in the chain or null. * @param propIds The proposition IDs that the query will try to derive. * @param termIds */ public Query(String[] keyIds, Filter filters, String[] propIds, And<String>[] termIds, PropositionDefinition[] propDefs, QueryMode queryMode) { this(null, keyIds, filters, propIds, termIds, propDefs, queryMode); } /** * Creates new Query instance. * * @param id An identifier for this query. If <code>null</code>, a default * identifier is assigned. * @param keyIds An array of key IDs. If this is null then the query will * include all keyIDs. * @param filters A chain of filters. The first filter's getAnd method * returns the second filter in the chain or null. * @param propIds The proposition IDs that the query will try to derive. * @param termIds */ public Query(String id, String[] keyIds, Filter filters, String[] propIds, And<String>[] termIds, PropositionDefinition[] propDefs, QueryMode queryMode) { this(id, null, keyIds, filters, propIds, termIds, propDefs, queryMode); } public Query(String id, String username, String[] keyIds, Filter filters, String[] propIds, And<String>[] termIds, PropositionDefinition[] propDefs, QueryMode queryMode) { if (keyIds == null) { keyIds = ArrayUtils.EMPTY_STRING_ARRAY; } if (propIds == null) { propIds = ArrayUtils.EMPTY_STRING_ARRAY; } if (termIds == null) { // Type safety: The expression of type And[] needs unchecked // conversion to conform to And<String>[] termIds = new And[0]; } if (propDefs == null) { propDefs = EMPTY_PROP_DEF_ARRAY; } ProtempaUtil.checkArrayForNullElement(keyIds, "keyIds"); ProtempaUtil.checkArrayForNullElement(propIds, "propIds"); ProtempaUtil.checkArrayForNullElement(termIds, "termIds"); ProtempaUtil.checkArrayForNullElement(propDefs, "propDefs"); this.keyIds = keyIds.clone(); this.filters = filters; this.propIds = propIds.clone(); ProtempaUtil.internAll(this.propIds); this.termIds = termIds.clone(); this.propDefs = propDefs.clone(); if (id == null) { id = UUID.randomUUID().toString(); } this.name = id; if (queryMode == null) { this.queryMode = DEFAULT_QUERY_MODE; } else { this.queryMode = queryMode; } this.username = username; } /** * Gets the filters to be applied to this query. * * @return a {@link Filter}. */ public final Filter getFilters() { return this.filters; } /** * Returns the key ids to be queried. An array of length 0 means that all * key ids will be queried. * * @return a {@link String[]}. Never returns * <code>null</code>. */ public final String[] getKeyIds() { return this.keyIds.clone(); } /** * Returns the proposition ids to be queried. An array of length 0 means * that all proposition ids will be queried. * * @param propIds a {@link String[]}. Never returns * <code>null</code>. */ public final String[] getPropositionIds() { return this.propIds.clone(); } /** * Gets the term ids to be queried in disjunctive normal form. PROTEMPA will * navigate these terms' subsumption hierarchy, find proposition definitions * that have been annotated with each term, and add those to the query. * <code>And</code>'d term ids will only match a proposition definition if * it is annotated with all of the specified term ids (or terms in their * subsumption hierarchies). * * @return a {@link String[]} of term ids representing disjunctive normal * form. */ public final And<String>[] getTermIds() { return this.termIds.clone(); } /** * Returns an optional set of user-specified proposition definitions. * * @return an array of {@link PropositionDefinition}s. */ public final PropositionDefinition[] getPropositionDefinitions() { return this.propDefs.clone(); } /** * Returns this query's identifier. Guaranteed not <code>null</code>. * * @return an identifier {@link String}. */ public final String getName() { return name; } public String getUsername() { return username; } /** * @return an array that references all of the filters in the chain of * filters. */ Filter[] getFiltersArray() { if (filters == null) { return new Filter[0]; } return filters.filterChainToArray(); } public QueryMode getQueryMode() { return queryMode; } @Override public int hashCode() { final int prime = 31; int result = prime + (this.filters != null ? this.filters.hashCode() : 0); result = prime * result + Arrays.hashCode(this.keyIds); result = prime * result + Arrays.hashCode(this.propIds); result = prime * result + Arrays.hashCode(this.termIds); result = prime * result + Arrays.hashCode(this.propDefs); result = prime * result + this.queryMode.hashCode(); result = prime * result + (this.username != null ? this.username.hashCode() : 0); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Query other = (Query) obj; if (this.filters == null) { if (other.filters != null) { return false; } } else if (!this.filters.equals(other.filters)) { return false; } if (!Arrays.equals(this.keyIds, other.keyIds)) { return false; } if (!Arrays.equals(this.propIds, other.propIds)) { return false; } if (!Arrays.equals(this.termIds, other.termIds)) { return false; } if (!Arrays.equals(this.propDefs, other.propDefs)) { return false; } if (!this.queryMode.equals(other.queryMode)) { return false; } if (this.username != null ? !this.username.equals(other.username) : other.username != null) { return false; } return true; } @Override public String toString() { return ToStringBuilder.reflectionToString(this); } }