/* Copyright 2013 The jeo project. All rights reserved. * * 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. */ package io.jeo.vector; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.osgeo.proj4j.CoordinateReferenceSystem; /** * Describes the structure of a {@link Feature} object. * <p> * A schema is am immutable collection of named {@link Field} objects, any of which may be a * geometry field. * </p> * @author Justin Deoliveira, OpenGeo */ public class Schema implements Iterable<Field> { /** schema name */ String name; /** schema namespace */ String uri; /** crs of the schema */ CoordinateReferenceSystem crs; /** list of fields */ List<Field> fields; /** * Returns a new schema builder. * * @param name The name of the schema. */ public static SchemaBuilder build(String name) { return new SchemaBuilder(name); } /** * Constructs a new Schema. * * @param name Name of the schema. * @param fields List of fields */ public Schema(String name, List<Field> fields) { this(name, null, fields); } /** * Constructs a new Schema. * * @param name Name of the schema. * @param uri Namespace of the schema. * @param fields List of fields */ public Schema(String name, String uri, List<Field> fields) { this.name = name; this.uri = uri; this.fields = Collections.unmodifiableList(fields); } /** * Constructs a new Schema. * * @param name Name of the schema. * @param uri Namespace of the schema. * @param crs Projection of the schema. * @param fields List of fields */ public Schema(String name, String uri, CoordinateReferenceSystem crs, List<Field> fields) { this.name = name; this.uri = uri; this.crs = crs; this.fields = Collections.unmodifiableList(fields); } /** * Name of the schema. */ public String name() { return name; } /** * Namespace uri of the schema. * <p> * May be <code>null</code> * </p> */ public String uri() { return uri; } /** * Derived geometry field of the schema. * <p> * This method returns the first field that returns true from {@link Field#geometry()}. If * no such field is found <code>null</code> is returned. * </p> */ public Field geometry() { //TODO: store the derived result for (Field f : this) { if (f.geometry()) { return f; } } return null; } /** * Derived coordinate reference system for the schema. * <p> * If the schemas {@link #crs} field is set it is returned, other this method delegates to * <code>geometry().crs()</code>. * </p> * @return The coordinate reference system object, or <code>null</code> if not available or * no geometry field exists. */ public CoordinateReferenceSystem crs() { if (crs != null) { return crs; } Field g = geometry(); return g != null ? g.crs() : null; } /** * The immutable list of fields for the schema. */ public List<Field> fields() { return fields; } /** * Returns the field of the schema with the specified name, or <code>null</code> if no such * field exists. * * @param name The field name. */ public Field field(String name) { int i = indexOf(name); return i != -1 ? fields.get(i) : null; } /** * Returns the index of the field in the schema with the specified name, or <code>-1</code> if * no such field exists. * * @param name The field name. * * @return The index position, or <code>-1</code> */ public int indexOf(String name) { //TODO: potentially add an index of name to field for (int i = 0; i < fields.size(); i++) { Field f = fields.get(i); if (f.name().equals(name)) { return i; } } return -1; } /** * Number of fields in the schema. */ public int size() { return fields.size(); } /** * Iterator over the fields of the schema. */ @Override public Iterator<Field> iterator() { return fields.iterator(); } @Override public String toString() { StringBuilder sb = new StringBuilder(name).append("["); if (!fields.isEmpty()) { for (Field f : fields) { sb.append(f).append(","); } sb.setLength(sb.length()-1); } return sb.toString(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((fields == null) ? 0 : fields.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((uri == null) ? 0 : uri.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Schema other = (Schema) obj; if (fields == null) { if (other.fields != null) return false; } else if (!fields.equals(other.fields)) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (uri == null) { if (other.uri != null) return false; } else if (!uri.equals(other.uri)) return false; return true; } }