/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2009-2010, Geomatys * * 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.geotoolkit.data.query; import java.util.Date; import java.util.HashSet; import java.util.Set; import org.geotoolkit.factory.Hints; import org.opengis.util.GenericName; import org.opengis.filter.Filter; import org.opengis.filter.sort.SortBy; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.apache.sis.internal.feature.AttributeConvention; /** * Query builder, convenient utility class to build queries. * * @author Johann Sorel (Geomatys) * @module */ public final class QueryBuilder { private static final String[] ONLY_ID_PROPERTIES = new String[]{ AttributeConvention.IDENTIFIER_PROPERTY.toString() }; private Source source = null; private String typeName = null; private Filter filter = Filter.INCLUDE; private String[] properties = null; private SortBy[] sortBy = null; private CoordinateReferenceSystem crs = null; private int startIndex = 0; private Integer maxFeatures = null; private Hints hints = null; private double[] resolution = null; private String language = Query.GEOTK_QOM; private Object version = null; public QueryBuilder(){ } public QueryBuilder(final Query query){ copy(query); } public QueryBuilder(final String name){ setTypeName(name); } public void reset(){ typeName = null; filter = Filter.INCLUDE; properties = null; sortBy = null; crs = null; startIndex = 0; maxFeatures = null; resolution = null; hints = null; version = null; } public void copy(final Query query){ this.crs = query.getCoordinateSystemReproject(); this.resolution = (query.getResolution()==null)?null:query.getResolution().clone(); this.filter = query.getFilter(); this.hints = query.getHints(); this.maxFeatures = query.getMaxFeatures(); this.properties = query.getPropertyNames(); this.sortBy = query.getSortBy(); this.startIndex = query.getStartIndex(); this.typeName = query.getTypeName(); this.source = query.getSource(); this.version = query.getVersionDate(); if(this.version==null) this.version = query.getVersionLabel(); this.language = query.getLanguage(); } public String getTypeName() { return typeName; } public void setTypeName(final GenericName typeName) { this.typeName = typeName.toString(); this.source = null; } public void setTypeName(final String typeName) { this.typeName = typeName; this.source = null; } public void setSource(final Source source){ this.source = source; this.typeName = null; } public Source getSource(){ if(source == null){ return new DefaultSelector(null, typeName, "s1"); }else{ return source; } } public Filter getFilter() { return filter; } public void setFilter(final Filter filter) { this.filter = filter; } public String[] getProperties() { return properties; } public void setProperties(final String[] properties) { this.properties = properties; } public SortBy[] getSortBy() { return sortBy; } public void setSortBy(final SortBy[] sortBy) { this.sortBy = sortBy; } public int getStartIndex() { return startIndex; } public void setStartIndex(final int startIndex) { this.startIndex = startIndex; } public Integer getMaxFeatures() { return maxFeatures; } public void setMaxFeatures(final Integer maxFeatures) { this.maxFeatures = maxFeatures; } public CoordinateReferenceSystem getCRS() { return crs; } public void setCRS(final CoordinateReferenceSystem crs) { this.crs = crs; } public void setResolution(final double[] resolution) { this.resolution = resolution; } public double[] getResolution() { return resolution; } public void setVersionLabel(String label) { this.version = label; } public String getVersionLabel() { if(version instanceof String){ return (String)version; } return null; } public void setVersionDate(Date version) { this.version = version; } public Date getVersionDate() { if(version instanceof Date){ return (Date)version; } return null; } public Hints getHints() { return hints; } public void setHints(final Hints hints) { this.hints = hints; } public Query buildQuery(){ final Source cs = (source == null) ? new DefaultSelector(null, typeName, "s1") : source; checkSource(cs,null); if(cs instanceof TextStatement){ return new DefaultQuery(language, (TextStatement)cs); }else{ return new DefaultQuery(cs, filter, properties, sortBy, crs, startIndex, maxFeatures, resolution, version, hints); } } /** * Verify that we don't have several selectors with the same name. */ private static void checkSource(final Source s, Set<String> selectors){ if(selectors == null){ selectors = new HashSet<String>(); } if(s instanceof Join){ final Join j = (Join) s; checkSource(j.getLeft(), selectors); checkSource(j.getRight(), selectors); }else if(s instanceof Selector){ final String selectName = ((Selector) s).getSelectorName(); if(selectors.contains(selectName)){ throw new IllegalStateException("Source has several selector with the same name = " + selectName); }else{ selectors.add(selectName); } }else if(s instanceof TextStatement){ //can't check this }else{ throw new IllegalStateException("Source type is unknowned : " + s + "\n valid types ares Join and Selector"); } } /** * Create a simple query with only a filter parameter. * * @param name * @param filter * @return Immutable query */ public static Query filtered(final String name, final Filter filter){ final QueryBuilder builder = new QueryBuilder(); builder.setTypeName(name); builder.setFilter(filter); return builder.buildQuery(); } /** * Create a simple query with only a sorted parameter. * * @param name * @param filter * @return Immutable query */ public static Query sorted(final String name, final SortBy ... sorts){ final QueryBuilder builder = new QueryBuilder(); builder.setTypeName(name); builder.setSortBy(sorts); return builder.buildQuery(); } /** * Implements a query that will fetch all features from a source. This * query should retrieve all properties, with no maxFeatures, no * filtering, and the default featureType. */ public static Query all(final GenericName name){ return new DefaultQuery(new DefaultSelector(null, name.toString(), "s1")); } /** * Implements a query that will fetch all features from a source. This * query should retrieve all properties, with no maxFeatures, no * filtering, and the default featureType. */ public static Query all(final String name){ return new DefaultQuery(new DefaultSelector(null, name, "s1")); } /** * Implements a query that will fetch all features from a source. This * query should retrieve all properties, with no maxFeatures, no * filtering, and the default featureType. */ public static Query all(final Source source){ return new DefaultQuery(source); } /** * Create a query in the defined language. * * @param language * @param statement * @param name * @return Query */ public static Query language(final String language, final String statement, final String name){ return new DefaultQuery(language, statement,name); } /** * Implements a query that will fetch all the FeatureIDs from a source. * This query should retrive no properties, with no maxFeatures, no * filtering, and the a featureType with no attributes. */ public static Query fids(final String name){ return new DefaultQuery(new DefaultSelector(null, name, "s1"), ONLY_ID_PROPERTIES); } /** * Create a simple query with only a reproject crs. * * @param name * @param filter * @return Immutable query */ public static Query reprojected(final String name, final CoordinateReferenceSystem crs){ final QueryBuilder builder = new QueryBuilder(); builder.setTypeName(name); builder.setCRS(crs); return builder.buildQuery(); } /** * * @param sortBy array or null * @return true is the given array of sort by operand is equal to natural sort by */ public static boolean isNaturalSortBy(SortBy[] sortBy){ if(sortBy == null || sortBy.length == 0){ return true; } for(SortBy sb : sortBy){ if(sb != SortBy.NATURAL_ORDER){ return false; } } return true; } }