001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.commons.betwixt.introspection;
019:
020: import java.util.List;
021:
022: import org.apache.commons.betwixt.AbstractTestCase;
023: import org.apache.commons.betwixt.ElementDescriptor;
024: import org.apache.commons.betwixt.XMLBeanInfo;
025: import org.apache.commons.betwixt.XMLIntrospector;
026: import org.apache.commons.betwixt.examples.rss.Channel;
027:
028: /**
029: * Tests for the new, more declarative style of introspection.
030: * @author <a href='http://jakarta.apache.org/'>Jakarta Commons Team</a>
031: * @version $Revision: 438373 $
032: */
033: public class TestDeclarativeIntrospection extends AbstractTestCase {
034: public TestDeclarativeIntrospection(String name) {
035: super (name);
036: }
037:
038: /** Tests whether a standard property's ElementDescriptor is hollow (as expected) */
039: public void testStandardPropertyIsHollow() throws Exception {
040: XMLIntrospector introspector = new XMLIntrospector();
041: introspector.getConfiguration()
042: .setAttributesForPrimitives(true);
043: XMLBeanInfo out = introspector.introspect(CompanyBean.class);
044:
045: ElementDescriptor companyBeanDescriptor = out
046: .getElementDescriptor();
047: ElementDescriptor[] childDescriptors = companyBeanDescriptor
048: .getElementDescriptors();
049: assertEquals("Correct number of child descriptors", 1,
050: childDescriptors.length);
051:
052: ElementDescriptor addressDescriptor = childDescriptors[0];
053: assertEquals("standard property is hollow", true,
054: addressDescriptor.isHollow());
055: }
056:
057: /** Tests whether a simple element's ElementDescriptor is hollow */
058: public void testSimpleElementIsHollow() throws Exception {
059: XMLIntrospector introspector = new XMLIntrospector();
060: introspector.getConfiguration().setAttributesForPrimitives(
061: false);
062: XMLBeanInfo out = introspector.introspect(CompanyBean.class);
063:
064: ElementDescriptor companyBeanDescriptor = out
065: .getElementDescriptor();
066: ElementDescriptor[] childDescriptors = companyBeanDescriptor
067: .getElementDescriptors();
068: assertEquals("Correct number of child descriptors", 2,
069: childDescriptors.length);
070:
071: ElementDescriptor nameDescriptor = null;
072: for (int i = 0, size = childDescriptors.length; i < size; i++) {
073: if ("name".equals(childDescriptors[i].getLocalName())) {
074: nameDescriptor = childDescriptors[i];
075: }
076: }
077:
078: assertNotNull(
079: "Expected to find an element descriptor for 'name'",
080: nameDescriptor);
081: assertFalse("Expected simple element not to be hollow",
082: nameDescriptor.isHollow());
083: }
084:
085: public void testWrappedCollective() throws Exception {
086: XMLIntrospector introspector = new XMLIntrospector();
087: introspector.getConfiguration().setWrapCollectionsInElement(
088: true);
089: introspector.getConfiguration()
090: .setAttributesForPrimitives(true);
091: XMLBeanInfo out = introspector.introspect(PhoneBookBean.class);
092:
093: // with wrapped collective, we expect a spacer element descriptor
094: // (for the collective) containing a single collective descriptor
095: ElementDescriptor phoneBookBeanDescriptor = out
096: .getElementDescriptor();
097: ElementDescriptor[] phoneBookChildDescriptors = phoneBookBeanDescriptor
098: .getElementDescriptors();
099: assertEquals("Expected single wrapping descriptor", 1,
100: phoneBookChildDescriptors.length);
101:
102: ElementDescriptor wrappingDescriptor = phoneBookChildDescriptors[0];
103: assertNull("Spacer should not have an updater",
104: wrappingDescriptor.getUpdater());
105: assertEquals("Wrapper element name should match getter",
106: "numbers", wrappingDescriptor.getQualifiedName());
107:
108: ElementDescriptor[] wrappingChildDescriptors = wrappingDescriptor
109: .getElementDescriptors();
110: assertEquals("Expected single child for wrapping descriptor",
111: 1, wrappingChildDescriptors.length);
112:
113: ElementDescriptor hollowPhoneNumberDescriptor = wrappingChildDescriptors[0];
114: assertTrue("Expected wrapped descriptor to be hollow",
115: hollowPhoneNumberDescriptor.isHollow());
116: assertEquals(
117: "Expected the collective property type to be a list",
118: List.class, hollowPhoneNumberDescriptor
119: .getPropertyType());
120: assertEquals(
121: "Expected the singular property type to be the phone number",
122: PhoneNumberBean.class, hollowPhoneNumberDescriptor
123: .getSingularPropertyType());
124:
125: assertEquals("Collective element name should match adder",
126: "number", hollowPhoneNumberDescriptor
127: .getQualifiedName());
128:
129: }
130:
131: public void testUnwrappedCollective() throws Exception {
132: XMLIntrospector introspector = new XMLIntrospector();
133: introspector.getConfiguration().setWrapCollectionsInElement(
134: false);
135: introspector.getConfiguration()
136: .setAttributesForPrimitives(true);
137: XMLBeanInfo out = introspector.introspect(PhoneBookBean.class);
138:
139: // with wrapped collective, we expect a spacer element descriptor
140: // (for the collective) containing a single collective descriptor
141: ElementDescriptor phoneBookBeanDescriptor = out
142: .getElementDescriptor();
143: ElementDescriptor[] phoneBookChildDescriptors = phoneBookBeanDescriptor
144: .getElementDescriptors();
145: assertEquals("Expected single child descriptor", 1,
146: phoneBookChildDescriptors.length);
147:
148: ElementDescriptor hollowPhoneNumberDescriptor = phoneBookChildDescriptors[0];
149:
150: assertTrue(
151: "Expected collective element descriptor to be hollow",
152: hollowPhoneNumberDescriptor.isHollow());
153: assertEquals(
154: "Expected the collective property type to be a list",
155: List.class, hollowPhoneNumberDescriptor
156: .getPropertyType());
157: assertEquals(
158: "Expected the singular property type to be the phone number",
159: PhoneNumberBean.class, hollowPhoneNumberDescriptor
160: .getSingularPropertyType());
161: assertEquals("Collective element name should match adder",
162: "number", hollowPhoneNumberDescriptor
163: .getQualifiedName());
164: }
165:
166: public void testUnwrappedMap() throws Exception {
167: XMLIntrospector introspector = new XMLIntrospector();
168: introspector.getConfiguration().setWrapCollectionsInElement(
169: false);
170: introspector.getConfiguration()
171: .setAttributesForPrimitives(true);
172: XMLBeanInfo out = introspector
173: .introspect(DateFormatterBean.class);
174:
175: ElementDescriptor formatterDescriptor = out
176: .getElementDescriptor();
177: ElementDescriptor[] formatterChildDescriptors = formatterDescriptor
178: .getElementDescriptors();
179:
180: assertEquals("Only one top level child", 1,
181: formatterChildDescriptors.length);
182:
183: ElementDescriptor entryDescriptor = formatterChildDescriptors[0];
184: assertEquals("Must be called entry", "entry", entryDescriptor
185: .getLocalName());
186: assertFalse("Is not hollow", entryDescriptor.isHollow());
187: assertNull("No updater for entry spacer", entryDescriptor
188: .getUpdater());
189:
190: ElementDescriptor[] entryChildDesciptors = entryDescriptor
191: .getElementDescriptors();
192: assertEquals("Entry has two children", 2,
193: entryChildDesciptors.length);
194:
195: ElementDescriptor keyDescriptor = entryChildDesciptors[0];
196: assertEquals("Must be called key", "key", keyDescriptor
197: .getLocalName());
198: assertTrue("Is not simple therefore hollow", keyDescriptor
199: .isHollow());
200: assertNotNull("Key should have an updater", keyDescriptor
201: .getUpdater());
202:
203: ElementDescriptor valueDescriptor = entryChildDesciptors[1];
204: assertEquals("Must be called key", "value", valueDescriptor
205: .getLocalName());
206: assertTrue("Is not simple therefore hollow", valueDescriptor
207: .isHollow());
208: assertNotNull("Value should have an updater", valueDescriptor
209: .getUpdater());
210: }
211:
212: public void testWrappedMap() throws Exception {
213: XMLIntrospector introspector = new XMLIntrospector();
214: introspector.getConfiguration().setWrapCollectionsInElement(
215: true);
216: introspector.getConfiguration()
217: .setAttributesForPrimitives(true);
218: XMLBeanInfo out = introspector
219: .introspect(DateFormatterBean.class);
220:
221: ElementDescriptor formatterDescriptor = out
222: .getElementDescriptor();
223: ElementDescriptor[] formatterChildDescriptors = formatterDescriptor
224: .getElementDescriptors();
225:
226: assertEquals("Only one top level child", 1,
227: formatterChildDescriptors.length);
228:
229: ElementDescriptor spacerDescriptor = formatterChildDescriptors[0];
230: assertEquals("Spacer must be called formats", "formats",
231: spacerDescriptor.getLocalName());
232: assertFalse("Is not hollow", spacerDescriptor.isHollow());
233: assertNull("No updater for entry spacer", spacerDescriptor
234: .getUpdater());
235:
236: ElementDescriptor[] spacerChildDescriptors = spacerDescriptor
237: .getElementDescriptors();
238: assertEquals("Only one top level child", 1,
239: spacerChildDescriptors.length);
240:
241: ElementDescriptor entryDescriptor = spacerChildDescriptors[0];
242: assertEquals("Must be called entry", "entry", entryDescriptor
243: .getLocalName());
244: assertFalse("Is not hollow", entryDescriptor.isHollow());
245: assertNull("No updater for entry spacer", entryDescriptor
246: .getUpdater());
247:
248: ElementDescriptor[] entryChildDesciptors = entryDescriptor
249: .getElementDescriptors();
250: assertEquals("Entry has two children", 2,
251: entryChildDesciptors.length);
252:
253: ElementDescriptor keyDescriptor = entryChildDesciptors[0];
254: assertEquals("Must be called key", "key", keyDescriptor
255: .getLocalName());
256: assertTrue("Is not simple therefore hollow", keyDescriptor
257: .isHollow());
258: assertNotNull("Key should have an updater", keyDescriptor
259: .getUpdater());
260:
261: ElementDescriptor valueDescriptor = entryChildDesciptors[1];
262: assertEquals("Must be called key", "value", valueDescriptor
263: .getLocalName());
264: assertTrue("Is not simple therefore hollow", valueDescriptor
265: .isHollow());
266: assertNotNull("Value should have an updater", valueDescriptor
267: .getUpdater());
268: }
269:
270: public void testIsSimpleForPrimitives() throws Exception {
271: XMLIntrospector introspector = new XMLIntrospector();
272: introspector.getConfiguration().setWrapCollectionsInElement(
273: true);
274: introspector.getConfiguration().setAttributesForPrimitives(
275: false);
276: XMLBeanInfo out = introspector
277: .introspect(PhoneNumberBean.class);
278:
279: // the bean is mapped to a complex type structure and so should not be simple
280: ElementDescriptor phoneNumberDescriptor = out
281: .getElementDescriptor();
282:
283: assertFalse("Phone number descriptor is complex",
284: phoneNumberDescriptor.isSimple());
285:
286: ElementDescriptor[] phoneNumberChildDescriptors = phoneNumberDescriptor
287: .getElementDescriptors();
288: assertEquals("Expected three child elements", 3,
289: phoneNumberChildDescriptors.length);
290:
291: // all children should be simple
292: assertTrue("Descriptor " + phoneNumberChildDescriptors[0]
293: + " should be simple", phoneNumberChildDescriptors[0]
294: .isSimple());
295: assertTrue("Descriptor " + phoneNumberChildDescriptors[1]
296: + " should be simple", phoneNumberChildDescriptors[1]
297: .isSimple());
298: assertTrue("Descriptor " + phoneNumberChildDescriptors[2]
299: + " should be simple", phoneNumberChildDescriptors[2]
300: .isSimple());
301: }
302:
303: public void testSimpleForRSS() throws Exception {
304: XMLIntrospector introspector = new XMLIntrospector();
305: introspector.getConfiguration().setWrapCollectionsInElement(
306: true);
307: introspector.getConfiguration().setAttributesForPrimitives(
308: false);
309: XMLBeanInfo out = introspector.introspect(Channel.class);
310:
311: ElementDescriptor channelDescriptor = out
312: .getElementDescriptor();
313: ElementDescriptor[] childNodesOfRSS = channelDescriptor
314: .getElementDescriptors();
315: assertEquals("RSS has only one child, channel", 1,
316: childNodesOfRSS.length);
317: ElementDescriptor[] childNodesOfChannel = childNodesOfRSS[0]
318: .getElementDescriptors();
319:
320: boolean matched = false;
321: for (int i = 0, size = childNodesOfChannel.length; i < size; i++) {
322: if ("item".equals(childNodesOfChannel[i].getLocalName())) {
323: matched = true;
324: }
325: }
326: assertTrue("Local element named item", matched);
327:
328: for (int i = 0, size = childNodesOfChannel.length; i < size; i++) {
329: if ("title".equals(childNodesOfChannel[i].getLocalName())) {
330: assertFalse("Title is not hollow",
331: childNodesOfChannel[i].isHollow());
332: } else if ("item".equals(childNodesOfChannel[i]
333: .getLocalName())) {
334: assertTrue("Item is hollow", childNodesOfChannel[i]
335: .isHollow());
336: } else if ("textinput".equals(childNodesOfChannel[i]
337: .getLocalName())) {
338: assertTrue("TextInput is hollow",
339: childNodesOfChannel[i].isHollow());
340: } else if ("skipDays".equals(childNodesOfChannel[i]
341: .getLocalName())) {
342: assertFalse("skipDays is not hollow",
343: childNodesOfChannel[i].isHollow());
344: assertFalse("day is not hollow", childNodesOfChannel[i]
345: .getElementDescriptors()[0].isHollow());
346: } else if ("skipHours".equals(childNodesOfChannel[i]
347: .getLocalName())) {
348: assertFalse("skipHours is not hollow",
349: childNodesOfChannel[i].isHollow());
350: assertFalse(
351: "hour is not hollow",
352: childNodesOfChannel[i].getElementDescriptors()[0]
353: .isHollow());
354: }
355: }
356: }
357:
358: /** Tests for setting for map with a simple key */
359: public void testMapWithSimpleKey() throws Exception {
360: XMLIntrospector introspector = new XMLIntrospector();
361: introspector.getConfiguration().setWrapCollectionsInElement(
362: false);
363: introspector.getConfiguration()
364: .setAttributesForPrimitives(true);
365: XMLBeanInfo out = introspector.introspect(AddressBook.class);
366:
367: ElementDescriptor formatterDescriptor = out
368: .getElementDescriptor();
369: ElementDescriptor[] formatterChildDescriptors = formatterDescriptor
370: .getElementDescriptors();
371:
372: assertEquals("Two top level children", 2,
373: formatterChildDescriptors.length);
374:
375: ElementDescriptor entryDescriptor = formatterChildDescriptors[0];
376: assertEquals("Must be called entry", "entry", entryDescriptor
377: .getLocalName());
378: assertFalse("Is not hollow", entryDescriptor.isHollow());
379: assertNull("No updater for entry spacer", entryDescriptor
380: .getUpdater());
381:
382: ElementDescriptor[] entryChildDesciptors = entryDescriptor
383: .getElementDescriptors();
384: assertEquals("Entry has two children", 2,
385: entryChildDesciptors.length);
386:
387: ElementDescriptor keyDescriptor = entryChildDesciptors[0];
388: assertEquals("Must be called key", "key", keyDescriptor
389: .getLocalName());
390: assertFalse("Is simple therefore not hollow", keyDescriptor
391: .isHollow());
392: assertNotNull("Key should have an updater", keyDescriptor
393: .getUpdater());
394:
395: ElementDescriptor valueDescriptor = entryChildDesciptors[1];
396: assertEquals("Must be called key", "value", valueDescriptor
397: .getLocalName());
398: assertTrue("Is not simple therefore hollow", valueDescriptor
399: .isHollow());
400: assertNotNull("Value should have an updater", valueDescriptor
401: .getUpdater());
402: }
403:
404: /** Tests introspector of map with simple entries */
405: public void testMapWithSimpleEntry() throws Exception {
406: XMLIntrospector introspector = new XMLIntrospector();
407: introspector.getConfiguration().setWrapCollectionsInElement(
408: false);
409: introspector.getConfiguration()
410: .setAttributesForPrimitives(true);
411: XMLBeanInfo out = introspector.introspect(AddressBook.class);
412:
413: ElementDescriptor formatterDescriptor = out
414: .getElementDescriptor();
415: ElementDescriptor[] formatterChildDescriptors = formatterDescriptor
416: .getElementDescriptors();
417:
418: assertEquals("Two top level children", 2,
419: formatterChildDescriptors.length);
420:
421: ElementDescriptor entryDescriptor = formatterChildDescriptors[1];
422: assertEquals("Must be called entry", "entry", entryDescriptor
423: .getLocalName());
424: assertFalse("Is not hollow", entryDescriptor.isHollow());
425: assertNull("No updater for entry spacer", entryDescriptor
426: .getUpdater());
427:
428: ElementDescriptor[] entryChildDesciptors = entryDescriptor
429: .getElementDescriptors();
430: assertEquals("Entry has two children", 2,
431: entryChildDesciptors.length);
432:
433: ElementDescriptor keyDescriptor = entryChildDesciptors[0];
434: assertEquals("Must be called key", "key", keyDescriptor
435: .getLocalName());
436: assertTrue("Is not simple therefore hollow", keyDescriptor
437: .isHollow());
438: assertNotNull("Key should have an updater", keyDescriptor
439: .getUpdater());
440:
441: ElementDescriptor valueDescriptor = entryChildDesciptors[1];
442: assertEquals("Must be called key", "value", valueDescriptor
443: .getLocalName());
444: assertFalse("Is simple therefore not hollow", valueDescriptor
445: .isHollow());
446: assertNotNull("Value should have an updater", valueDescriptor
447: .getUpdater());
448: }
449:
450: public void testConcreteMapNoWrap() throws Exception {
451: XMLIntrospector introspector = new XMLIntrospector();
452: introspector.getConfiguration().setWrapCollectionsInElement(
453: false);
454: XMLBeanInfo beanInfo = introspector
455: .introspect(BeanWithConcreteMap.class);
456: ElementDescriptor beanDescriptor = beanInfo
457: .getElementDescriptor();
458:
459: ElementDescriptor[] beanChildDescriptors = beanDescriptor
460: .getElementDescriptors();
461: assertEquals("One Entry element", 1,
462: beanChildDescriptors.length);
463:
464: ElementDescriptor entry = beanChildDescriptors[0];
465: ElementDescriptor[] entryChildren = entry
466: .getElementDescriptors();
467: assertEquals("Expected key and entry elements", 2,
468: entryChildren.length);
469: }
470:
471: public void testConcreteMapWithWrap() throws Exception {
472: XMLIntrospector introspector = new XMLIntrospector();
473: introspector.getConfiguration().setWrapCollectionsInElement(
474: true);
475: XMLBeanInfo beanInfo = introspector
476: .introspect(BeanWithConcreteMap.class);
477:
478: ElementDescriptor beanDescriptor = beanInfo
479: .getElementDescriptor();
480:
481: ElementDescriptor[] beanChildDescriptors = beanDescriptor
482: .getElementDescriptors();
483: assertEquals("One wrapper element", 1,
484: beanChildDescriptors.length);
485:
486: ElementDescriptor wrapper = beanChildDescriptors[0];
487: ElementDescriptor[] wrapperChildren = wrapper
488: .getElementDescriptors();
489: assertEquals("One Entry element", 1, wrapperChildren.length);
490:
491: ElementDescriptor entry = wrapperChildren[0];
492: ElementDescriptor[] entryChildren = entry
493: .getElementDescriptors();
494: assertEquals("Expected key and entry elements", 2,
495: entryChildren.length);
496:
497: }
498: }
|