org.geotools.data.Join Maven / Gradle / Ivy
Show all versions of gt-main Show documentation
/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2011, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.data;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.geotools.factory.CommonFactoryFinder;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory;
import org.opengis.filter.expression.PropertyName;
/**
* Represents the joining of two feature types within a {@link Query}.
*
* The Join class is similar to Query in that it allows one to specify a FeatureType name, a set
* of properties, and a filter. A Join must specify:
*
*
* - A type name that references the feature type to join to, see {@link #getTypeName()}
*
- A join filter that describes how to join, see {@link #getJoinFilter()}
*
*
* Optionally a Join may also specify:
*
*
* - A set of property names constraining the attributes of joined features, see {@link
* #getProperties()}
*
- A secondary filter used to constrained features from the joined feature type, see {@link
* #getFilter()}
*
- An alias for the joined feature type, which can be used in the join filter to disambiguate
* attributes of the feature types being joined, see {@link #getAlias()}
*
- A join type specifying what type of join (inner, outer, etc...) should be performed, see
* {@link #getType()}
*
*
* @author Justin Deoliveira, OpenGeo
* @since 8.0
*/
public class Join {
/** filter factory */
static final FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);
/** type of join */
public static enum Type {
INNER,
OUTER;
}
/** join type */
Type type;
/** the feature type name being joined to */
String typeName;
/** attributes to fetch for this feature type */
List properties = Query.ALL_PROPERTIES;
/** the join predicate */
Filter join;
/** additional predicate against the target of the join */
Filter filter;
/** The alias to be used for the typeName in this join */
String alias;
/**
* Constructs a join.
*
* @param typeName The name of the feature type to join to.
* @param join The filter specifying the join condition between the two feature types being
* joined.
*/
public Join(String typeName, Filter join) {
this.typeName = typeName;
this.join = join;
this.type = Type.INNER;
this.properties = Query.ALL_PROPERTIES;
this.filter = Filter.INCLUDE;
this.alias = null;
}
/** Constructs a join from another. */
public Join(Join other) {
this.typeName = other.getTypeName();
this.join = other.getJoinFilter();
this.filter = other.getFilter();
this.type = other.getType();
this.properties = other.getProperties();
this.filter = other.getFilter();
this.alias = other.getAlias();
}
/**
* The name of the feature type being joined to.
*
* This name may be the same as the name of the primary feature type, this is how a self join
* is specified.
*/
public String getTypeName() {
return typeName;
}
/**
* The filter defining the join condition between the primary feature type and the feature type
* being joined to.
*
*
This filter should be a comparison operator whose contents are two {@link PropertyName}
* instances. For example:
*
*
* new Join("theOtherType", propertyIsEqualTo(propertyName("foo"), propertyName("bar")));
*
*
* In instances where the two property names involved in the join are the same a prefix or alias
* must be used to differentiate:
*
*
* Join j = new Join("theOtherType", propertyIsEqualTo(propertyName("foo"), propertyName("other.bar")));
* j.alias("other");
*
*/
public Filter getJoinFilter() {
return join;
}
/**
* Sets the join type.
*
* @see #getType()
*/
public void setType(Type type) {
this.type = type;
}
/**
* The type of the join.
*
* {@link Type#INNER} is the default join type.
*/
public Type getType() {
return type;
}
/**
* List of properties specifying which attributes of joined features to obtain.
*
*
This method has the same purpose as {@link Query#getProperties()}.
*/
public List getProperties() {
if (properties == Query.ALL_PROPERTIES) {
return properties;
}
return Collections.unmodifiableList(properties);
}
/**
* Sets list of properties specifying which attributes of joined features to obtain.
*
* This method has the same purpose as {@link Query#setProperties(List)}.
*/
public void setProperties(List properties) {
this.properties = properties;
}
/**
* List of property names specifying which attributes of joined features to obtain.
*
* This method has the same purpose as {@link Query#getPropertyNames()}.
*/
public String[] getPropertyNames() {
if (properties == Query.ALL_PROPERTIES) {
return Query.ALL_NAMES;
}
String[] names = new String[properties.size()];
for (int i = 0; i < names.length; i++) {
names[i] = properties.get(i).getPropertyName();
}
return names;
}
/**
* Sets the filter used to constrain which features from the joined feature type to return.
*
* @see #getFilter()
*/
public void setFilter(Filter filter) {
this.filter = filter;
}
/**
* Filter used to constrain which features from the joined feature type to return.
*
*
This filter must only reference attributes from the joined feature type, and not of any
* other feature types involved in the join.
*/
public Filter getFilter() {
return filter;
}
/**
* Sets an alias for the feature type being joined to.
*
* @see #getAlias()
*/
public void setAlias(String alias) {
this.alias = alias;
}
/**
* An alias for the feature type being joined to.
*
*
This method is useful in cases where the two feature types being joined contain attributes
* identically named, or in cases where a self join is being performed:
*
*
* Join j = new Join("theOtherType", PropertyIsEqualTo(PropertyName("foo"), PropertyName("other.foo")));
* j.setAlias("other");
*
*
* @see #getJoinFilter()
*/
public String getAlias() {
return alias;
}
/**
* Convenience method that returns the attribute name to be used for this join.
*
* Convenience for:
*
* return getAlias() != null ? getAlias() : getTypeName();
*
*
*/
public String attributeName() {
return getAlias() != null ? getAlias() : getTypeName();
}
/** Chaining method for {@link #getProperties()} */
public Join properties(String... properties) {
this.properties = new ArrayList();
for (String p : properties) {
this.properties.add(ff.property(p));
}
return this;
}
/** Chaining method for {@link #setFilter(Filter)} */
public Join filter(Filter filter) {
setFilter(filter);
return this;
}
/** Chaining method for {@link #setAlias(String)} */
public Join alias(String alias) {
setAlias(alias);
return this;
}
/** Chaining method for {@link #setType(Type)} */
public Join type(Type type) {
setType(type);
return this;
}
}