001: package org.geotools.feature.iso;
002:
003: import java.util.ArrayList;
004: import java.util.Collection;
005: import java.util.Date;
006: import java.util.Iterator;
007:
008: import junit.framework.TestCase;
009:
010: import org.geotools.util.GTContainer;
011: import org.opengis.feature.Attribute;
012: import org.opengis.feature.ComplexAttribute;
013: import org.opengis.feature.Feature;
014: import org.opengis.feature.FeatureFactory;
015: import org.opengis.feature.GeometryAttribute;
016: import org.opengis.feature.Property;
017: import org.opengis.feature.type.AssociationType;
018: import org.opengis.feature.type.AttributeDescriptor;
019: import org.opengis.feature.type.AttributeType;
020: import org.opengis.feature.type.ComplexType;
021: import org.opengis.feature.type.FeatureCollectionType;
022: import org.opengis.feature.type.FeatureType;
023: import org.opengis.feature.type.GeometryType;
024: import org.opengis.feature.type.PropertyDescriptor;
025: import org.picocontainer.defaults.DefaultPicoContainer;
026:
027: import com.vividsolutions.jts.geom.Coordinate;
028: import com.vividsolutions.jts.geom.GeometryFactory;
029: import com.vividsolutions.jts.geom.Point;
030:
031: /**
032: * This test cases is set up to exercise the "Data" system.
033: * <p>
034: * We will be making use of the same abstractions defined during the
035: * TypeBuilderTest (so if you get an error during setup you can debug over there
036: * first).
037: * </p>
038: * To review here is the type model we will be using during these tests: /**
039: * Defines a simple setup of Address, Fullname, Person and then defines a
040: * collection of Person as a Country.
041: *
042: * <pre><code>
043: * +--------------------+
044: * | Address (Complex) |
045: * +--------------------+
046: * | attention: Fullname|
047: * | suite: Number |
048: * | street: Text |
049: * | city: Text |
050: * | province: Text |
051: * | code: Number |
052: * +--------------------+
053: * |0..2
054: * |
055: * |
056: * +-------------------+ +-------------------+
057: * | Person (Feature) | | Fullname (Complex)|
058: * +-------------------+ 1+-------------------+
059: * |location: Location |-------|first: Text |
060: * |name: Fullname | |last: Text |
061: * |home: Address | +-------------------+
062: * |work: Address |
063: * |birthdat: Date |
064: * +-------------------+
065: * *|
066: * |population:Citizen
067: * |
068: * +----------------------------+
069: * | Country (FeatureCollection)|
070: * +----------------------------+
071: * | currency: Text |
072: * +----------------------------+
073: * </code></pre>
074: *
075: * </p>
076: * <p>
077: *
078: * @author Jody
079: */
080: public class DataSystemTest extends TestCase {
081: static final String URI = "gopher://localhost/test/";
082:
083: private DefaultPicoContainer gt;
084:
085: private TypeBuilder builder;
086:
087: private FeatureFactory factory;
088:
089: private AttributeType TEXT;
090:
091: private AttributeType NUMBER;
092:
093: private ComplexType FULLNAME;
094:
095: private ComplexType ADDRESS;
096:
097: private AttributeType DATE;
098:
099: private GeometryType LOCATION;
100:
101: private FeatureType PERSON;
102:
103: private AssociationType CITIZEN;
104:
105: private FeatureCollectionType COUNTRY;
106:
107: protected void setUp() throws Exception {
108: super .setUp();
109: //
110: // Container
111: //
112: gt = GTContainer.normal(); // ah so easy!
113: //
114: // Type Fixture
115: //
116: builder = (TypeBuilder) gt
117: .getComponentInstance(TypeBuilder.class);
118: builder.setNamespaceURI(URI);
119: builder.setName("Text");
120: builder.setBinding(String.class);
121:
122: TEXT = builder.attribute();
123: NUMBER = builder.name("Number").bind(Integer.class).attribute();
124:
125: FULLNAME = builder.name("Fullname").attribute("first", TEXT)
126: .attribute("last", TEXT).complex();
127:
128: builder.setName("Address");
129: builder.attribute("attention", FULLNAME);
130: builder.attribute("suite", NUMBER);
131: builder.attribute("street", TEXT);
132: builder.attribute("city", TEXT);
133: builder.attribute("province", TEXT);
134: builder.attribute("code", NUMBER);
135: ADDRESS = builder.complex();
136:
137: DATE = builder.name("Date").bind(Date.class).attribute();
138: LOCATION = builder.name("Location").bind(Point.class)
139: .geometry();
140:
141: builder.setName("Person");
142: builder.attribute("location", LOCATION);
143: builder.attribute("name", FULLNAME);
144: builder.attribute("home", ADDRESS);
145: builder.attribute("work", ADDRESS);
146: builder.attribute("birthday", DATE);
147: builder.setDefaultGeometry("location");
148: PERSON = builder.feature();
149:
150: CITIZEN = builder.name("Citizen").referenceType(PERSON)
151: .association();
152:
153: COUNTRY = builder.name("Country").attribute("currency", TEXT)
154: .member("population", CITIZEN).collection();
155: //
156: // Factory
157: //
158: factory = (FeatureFactory) gt
159: .getComponentInstanceOfType(FeatureFactory.class);
160: }
161:
162: /**
163: * Simple lookup method, the kinda thing that should belong in Types utility
164: * class
165: *
166: * @param type
167: * complex type from which we want a descriptor
168: * @param name
169: * text to match against local part of descriptor name
170: * @return Descriptor with getName().getLocalPart() equals name
171: */
172: PropertyDescriptor association(ComplexType type, String name) {
173: for (Iterator i = type.getProperties().iterator(); i.hasNext();) {
174: PropertyDescriptor descriptor = (PropertyDescriptor) i
175: .next();
176: if (name.equalsIgnoreCase(descriptor.getName()
177: .getLocalPart())) {
178: return descriptor;
179: }
180: }
181: return null;
182: }
183:
184: AttributeDescriptor attribute(ComplexType type, String name) {
185: for (Iterator i = type.attributes().iterator(); i.hasNext();) {
186: AttributeDescriptor descriptor = (AttributeDescriptor) i
187: .next();
188: if (name.equalsIgnoreCase(descriptor.getName()
189: .getLocalPart())) {
190: return descriptor;
191: }
192: }
193: return null;
194: }
195:
196: public void testAttribute() {
197: Attribute first = factory.createAttribute("Jody", attribute(
198: FULLNAME, "first"), null);
199:
200: assertNotNull(first);
201: assertEquals(attribute(FULLNAME, "first"), first
202: .getDescriptor());
203: assertEquals(TEXT, first.getType());
204:
205: assertEquals("Jody", first.getValue());
206:
207: }
208:
209: Collection properties(Property property) {
210: Collection properties = new ArrayList();
211: properties.add(property);
212: return properties;
213: }
214:
215: Collection properties(Property property1, Property property2) {
216: Collection properties = new ArrayList();
217: properties.add(property1);
218: properties.add(property2);
219: return properties;
220: }
221:
222: Collection properties(Property property1, Property property2,
223: Property property3) {
224: Collection properties = new ArrayList();
225: properties.add(property1);
226: properties.add(property2);
227: properties.add(property3);
228: return properties;
229: }
230:
231: Collection properties(Property[] array) {
232: Collection properties = new ArrayList();
233: for (int i = 0; i < array.length; i++) {
234: properties.add(array[i]);
235: }
236: return properties;
237: }
238:
239: /** Tests using ComplexType */
240: public void testSimpleComplexAttribute() {
241: Attribute first = factory.createAttribute("Jody", attribute(
242: FULLNAME, "first"), null);
243: Attribute last = factory.createAttribute("Garnett", attribute(
244: FULLNAME, "last"), null);
245:
246: ComplexAttribute fullname = factory.createComplexAttribute(
247: properties(first, last), FULLNAME, null);
248:
249: assertNotNull(fullname);
250: Collection contents = (Collection) fullname.getValue();
251: assertTrue(contents.contains(first));
252: assertTrue(contents.contains(last));
253: }
254:
255: /** Creates using FULLNAME using ADDRESS descriptor "attention" */
256: ComplexAttribute createFullname(ComplexType context, String entry,
257: String aName) {
258: int split = aName.indexOf(" ");
259: String first = aName.substring(0, split);
260: String last = aName.substring(split + 1);
261:
262: Attribute firstName = factory.createAttribute(first, attribute(
263: FULLNAME, "first"), null);
264: Attribute lastName = factory.createAttribute(last, attribute(
265: FULLNAME, "last"), null);
266: return factory.createComplexAttribute(properties(firstName,
267: lastName), attribute(context, entry), null);
268: }
269:
270: /** Tests ADDRESS using ComplexType directly */
271: public void testCompountComplexAttribute() {
272: ComplexAttribute attention = createFullname(ADDRESS,
273: "attention", "Jody Garnett");
274: Attribute suite = factory.createAttribute(new Integer(3),
275: attribute(ADDRESS, "suite"), null);
276: Attribute street = factory.createAttribute("645 Battery",
277: attribute(ADDRESS, "street"), null);
278: Attribute city = factory.createAttribute("Victora", attribute(
279: ADDRESS, "city"), null);
280: Attribute province = factory.createAttribute(
281: "British Columbia", attribute(ADDRESS, "province"),
282: null);
283: Attribute code = factory.createAttribute(new Integer(1234),
284: attribute(ADDRESS, "code"), null);
285: ComplexAttribute address = factory.createComplexAttribute(
286: properties(new Property[] { attention, suite, street,
287: city, province, code }), ADDRESS, null);
288:
289: assertNotNull(address);
290: Collection contents = (Collection) address.getValue();
291: assertTrue(contents.contains(city));
292: }
293:
294: /** Creates using PERSON and either "work" or "home" descriptor */
295: ComplexAttribute createPersonAddress(String location) {
296: ComplexAttribute attention = createFullname(ADDRESS,
297: "attention", "Jody Garnett");
298: Attribute suite = factory.createAttribute(new Integer(3),
299: attribute(ADDRESS, "suite"), null);
300: Attribute street = factory.createAttribute("645 Battery",
301: attribute(ADDRESS, "street"), null);
302: Attribute city = factory.createAttribute("Victora", attribute(
303: ADDRESS, "city"), null);
304: Attribute province = factory.createAttribute(
305: "British Columbia", attribute(ADDRESS, "province"),
306: null);
307: Attribute code = factory.createAttribute(new Integer(1234),
308: attribute(ADDRESS, "code"), null);
309: return factory.createComplexAttribute(
310: properties(new Property[] { attention, suite, street,
311: city, province, code }), attribute(PERSON,
312: location), null);
313: }
314:
315: public void testGeometryAttribute() {
316: GeometryFactory gf = (GeometryFactory) gt
317: .getComponentInstance(GeometryFactory.class);
318:
319: // NB: we can only create geometry attirbute as part of a feature!
320: GeometryAttribute location = factory.createGeometryAttribute(gf
321: .createPoint(new Coordinate(0, 0)), attribute(PERSON,
322: "location"), null, null);
323:
324: assertNotNull(location);
325: assertEquals(0, ((Point) location.getValue()).getX(), 0);
326: }
327:
328: public GeometryAttribute createLocation() {
329: GeometryFactory gf = (GeometryFactory) gt
330: .getComponentInstance(GeometryFactory.class);
331: return factory.createGeometryAttribute(gf
332: .createPoint(new Coordinate(0, 0)), attribute(PERSON,
333: "location"), null, null);
334: }
335:
336: public void testFeature() {
337: ComplexAttribute home = createPersonAddress("home");
338: ComplexAttribute work = createPersonAddress("work");
339: GeometryAttribute location = createLocation();
340: ComplexAttribute name = createFullname(PERSON, "name",
341: "Jody Garnett");
342: Attribute date = factory.createAttribute(new Date(), attribute(
343: PERSON, "birthday"), null);
344: Feature person = factory.createFeature(
345: properties(new Property[] { location, name, home, work,
346: date }), PERSON, null);
347:
348: assertNotNull(person);
349: Collection contents = (Collection) person.getValue();
350: assertTrue(contents.contains(name));
351: }
352:
353: Feature createPerson(String aName, String fid) {
354: ComplexAttribute home = createPersonAddress("home");
355: ComplexAttribute work = createPersonAddress("work");
356: GeometryAttribute location = createLocation();
357: ComplexAttribute name = createFullname(PERSON, "name", aName);
358: Attribute date = factory.createAttribute(new Date(), attribute(
359: PERSON, "birthday"), null);
360: return factory.createFeature(properties(new Property[] {
361: location, name, home, work, date }), PERSON, fid);
362: }
363:
364: public void testFeatureCollection() {
365: assertNotNull(COUNTRY);
366: Attribute currency = factory.createAttribute("dollars",
367: attribute(COUNTRY, "currency"), null);
368:
369: //TODO: explicit cast as FeatureCollection lost its ability to report content size
370: FeatureCollectionImpl canada = (FeatureCollectionImpl) factory
371: .createFeatureCollection(properties(currency), COUNTRY,
372: null);
373: Feature justin = createPerson("Justin DeOlivera", "#2");
374: Feature jody = createPerson("Jody Garnett", "#1");
375:
376: canada.add(jody);
377: canada.add(justin);
378:
379: assertEquals(2, canada.size());
380: }
381: }
|