001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2004-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.feature;
017:
018: import java.util.Iterator;
019: import java.util.List;
020:
021: /**
022: * Class to handle more than one occurance of an attribute. There may be
023: * better ways to do this, but this seems to work.
024: *
025: * @author Chris Holmes
026: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/feature/MultiAttributeType.java $
027: * @version $Id: MultiAttributeType.java 20651 2006-07-21 07:51:54Z jgarnett $
028: */
029: public class MultiAttributeType extends DefaultAttributeType {
030: /** Number of instances of this attribute in the schema. */
031: private int maxOccur = 1;
032:
033: /** The AttributeType to check each object of the list against. */
034: private AttributeType validator;
035:
036: /** The minimum number of occurances of this attribute to validate. */
037: private int minOccur = 1;
038:
039: /**
040: * Constructor with validator.
041: *
042: * @param validator Name of this attribute.
043: */
044: public MultiAttributeType(AttributeType validator) {
045: super (validator.getName(), List.class, false, 1, 1, null);
046: this .validator = validator;
047: }
048:
049: /**
050: * Constructor with validator and maxOccurs
051: *
052: * @param validator Name of this attribute.
053: * @param maxOccur Number of instances of this attribute in the schema.
054: */
055: public MultiAttributeType(AttributeType validator, int maxOccur) {
056: this (validator);
057: this .maxOccur = maxOccur;
058: }
059:
060: /**
061: * Constructor with validator, minOccurs and maxOccurs
062: *
063: * @param validator Name of this attribute.
064: * @param maxOccur Number of instances of this attribute in the schema.
065: * @param minOccur Class type of this attribute.
066: */
067: public MultiAttributeType(AttributeType validator, int maxOccur,
068: int minOccur) {
069: this (validator, maxOccur);
070: this .minOccur = minOccur;
071: }
072:
073: /**
074: * Gets the maxOccur of this attribute.
075: *
076: * @return MaxOccur.
077: */
078: public int getMaxOccurs() {
079: return maxOccur;
080: }
081:
082: /**
083: * Gets the minimum number of elements that pass the validator that must be
084: * in the list to validate.
085: *
086: * @return MaxOccur.
087: */
088: public int getMinOccurs() {
089: return minOccur;
090: }
091:
092: /**
093: * Returns whether the attribute is a geometry. Should this be false? Even
094: * if the attributes are geometries? Because this itself isn't actually a
095: * geometry, so it can't be used as a geometry.
096: *
097: * @return true if the attribute's type is a geometry.
098: */
099: public boolean isGeometry() {
100: return false;
101: }
102:
103: /**
104: * Returns a clone of this object.
105: *
106: * @return a copy of this attribute type.
107: *
108: * @throws CloneNotSupportedException if clone is not supported.
109: */
110: public Object clone() throws CloneNotSupportedException {
111: return super .clone();
112: }
113:
114: /**
115: * Whether the tested object is a Feature and its attributes validate
116: * against the featureType. An IllegalArgumentException reporting the
117: * error in validation is thrown if validation fails..
118: *
119: * @param attribute The object to be tested for validity.
120: *
121: * @throws IllegalArgumentException if the object does not validate.
122: */
123: public void validate(Object attribute)
124: throws IllegalArgumentException {
125: super .validate(attribute);
126:
127: if (attribute instanceof List) {
128: int occurs = ((List) attribute).size();
129:
130: if (occurs < minOccur) {
131: String mesg = "The list of attributes is " + occurs
132: + " long."
133: + " It must not be less than minOccurs: "
134: + minOccur;
135: throw new IllegalArgumentException(mesg);
136: }
137:
138: if (occurs > maxOccur) {
139: String mesg = "The list of attributes is " + occurs
140: + " long."
141: + " It must not be greater than maxOccurs: "
142: + maxOccur;
143: throw new IllegalArgumentException(mesg);
144: }
145:
146: for (Iterator iter = ((List) attribute).iterator(); iter
147: .hasNext();) {
148: validator.validate(iter.next());
149: }
150: } else {
151: //REVISIT: allow just one if it's not in a list?
152: String msg = attribute.getClass().getName()
153: + " is not an accetable"
154: + " class for a multiAttributeType. Must be of type List";
155:
156: throw new IllegalArgumentException(msg);
157: }
158: }
159:
160: /**
161: * If a single object is passed in then it is parsed into a list with just
162: * it as the element. If an array is passed in then it is turned into a
163: * list.
164: *
165: * @param value the object to attempt parsing of.
166: *
167: * @return <code>value</code> converted to the preferred storage of this
168: * <code>AttributeType</code>. If no parsing was possible then
169: * the same object is returned.
170: *
171: * @throws IllegalArgumentException if parsing is attempted and is
172: * unsuccessful.
173: *
174: * @task REVISIT: implement this method as described in this comment.
175: */
176: public Object parse(Object value) throws IllegalArgumentException {
177: return value;
178: }
179:
180: /**
181: * Gets a representation of this object as a string.
182: *
183: * @return A representation of this object as a string
184: */
185: public String toString() {
186: StringBuffer returnString = new StringBuffer(
187: "MultiAttributeType [ ");
188:
189: returnString.append("name=").append(name).append(',');
190: returnString.append("type=").append(type.getName()).append(',');
191: returnString.append("maxOccurs=").append(maxOccur).append(',');
192: returnString.append("minOccur=").append(minOccur).append(" ]");
193:
194: return returnString.toString();
195: }
196: }
|