View Javadoc
1   /*
2    * Copyright (C) 2013 4th Line GmbH, Switzerland
3    *
4    * The contents of this file are subject to the terms of either the GNU
5    * Lesser General Public License Version 2 or later ("LGPL") or the
6    * Common Development and Distribution License Version 1 or later
7    * ("CDDL") (collectively, the "License"). You may not use this file
8    * except in compliance with the License. See LICENSE.txt for more
9    * information.
10   *
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14   */
15  package example.mediaserver;
16  
17  import org.fourthline.cling.support.contentdirectory.DIDLParser;
18  import org.fourthline.cling.support.model.DIDLContent;
19  import org.fourthline.cling.support.model.DIDLObject;
20  import org.fourthline.cling.support.model.DIDLObject.Property;
21  import org.fourthline.cling.support.model.DescMeta;
22  import org.fourthline.cling.support.model.Res;
23  import org.fourthline.cling.support.model.StorageMedium;
24  import org.fourthline.cling.support.model.WriteStatus;
25  import org.fourthline.cling.support.model.container.Album;
26  import org.fourthline.cling.support.model.container.Container;
27  import org.fourthline.cling.support.model.container.MusicAlbum;
28  import org.fourthline.cling.support.model.container.PhotoAlbum;
29  import org.fourthline.cling.support.model.item.AudioBook;
30  import org.fourthline.cling.support.model.item.AudioBroadcast;
31  import org.fourthline.cling.support.model.item.Item;
32  import org.fourthline.cling.support.model.item.Movie;
33  import org.fourthline.cling.support.model.item.MusicTrack;
34  import org.fourthline.cling.support.model.item.MusicVideoClip;
35  import org.fourthline.cling.support.model.item.Photo;
36  import org.fourthline.cling.support.model.item.PlaylistItem;
37  import org.fourthline.cling.support.model.item.TextItem;
38  import org.fourthline.cling.support.model.item.VideoBroadcast;
39  import org.testng.annotations.Test;
40  import org.w3c.dom.Document;
41  import org.xml.sax.Attributes;
42  import org.xml.sax.SAXException;
43  
44  import javax.xml.transform.OutputKeys;
45  import javax.xml.transform.Transformer;
46  import javax.xml.transform.TransformerFactory;
47  import javax.xml.transform.dom.DOMSource;
48  import javax.xml.transform.stream.StreamResult;
49  import java.io.StringWriter;
50  import java.net.URI;
51  import java.util.List;
52  
53  import static org.testng.Assert.*;
54  import static org.testng.Assert.assertEquals;
55  
56  public class DIDLParserTest {
57  
58      protected DIDLParser parser = new DIDLParser();
59  
60      @Test
61      public void readWriteEmpty() throws Exception {
62  
63          DIDLContent didl = parser.parseResource("org/fourthline/cling/test/support/contentdirectory/samples/browseEmpty.xml");
64          assertSampleEmpty(didl);
65          String xml = parser.generate(didl);
66          didl = parser.parse(xml);
67          assertSampleEmpty(didl);
68  
69          // Again with an empty DIDLContent instance
70          didl = new DIDLContent();
71          assertSampleEmpty(didl);
72          xml = parser.generate(didl);
73          //parser.debugXML(xml);
74          didl = parser.parse(xml);
75          assertSampleEmpty(didl);
76      }
77  
78      @Test
79      public void readWriteRoot() throws Exception {
80  
81          DIDLContent didl = parser.parseResource("org/fourthline/cling/test/support/contentdirectory/samples/browseRoot.xml");
82          assertSampleRoot(didl);
83  
84          String xml = parser.generate(didl);
85  
86          //parser.debugXML(xml);
87  
88          didl = parser.parse(xml);
89          assertSampleRoot(didl);
90      }
91  
92      @Test
93      public void readWriteRootChildren() throws Exception {
94  
95          DIDLContent didl = parser.parseResource("org/fourthline/cling/test/support/contentdirectory/samples/browseRootChildren.xml");
96          assertSampleRootChildren(didl);
97  
98          String xml = parser.generate(didl);
99  
100         //parser.debugXML(xml);
101 
102         didl = parser.parse(xml);
103         assertSampleRootChildren(didl);
104     }
105 
106     @Test
107     public void readWriteFolder() throws Exception {
108 
109         DIDLContent didl = parser.parseResource("org/fourthline/cling/test/support/contentdirectory/samples/browseFolder.xml");
110         assertSampleFolder(didl);
111 
112         String xml = parser.generate(didl);
113 
114         //parser.debugXML(xml);
115 
116         didl = parser.parse(xml);
117         assertSampleFolder(didl);
118     }
119 
120     @Test
121     public void readWriteItems() throws Exception {
122 
123         DIDLContent didl = parser.parseResource("org/fourthline/cling/test/support/contentdirectory/samples/browseItems.xml");
124         assertSampleItems(didl);
125 
126         String xml = parser.generate(didl);
127 
128         parser.debugXML(xml);
129 
130         didl = parser.parse(xml);
131         assertSampleItems(didl);
132     }
133 
134     @Test
135     public void readWriteItemsMinimal() throws Exception {
136 
137         DIDLContent didl = parser.parseResource("org/fourthline/cling/test/support/contentdirectory/samples/browseItemsMinimal.xml");
138         assertEquals(didl.getContainers().size(), 0);
139 
140         List<Item> items = didl.getItems();
141         assertEquals(items.size(), 1);
142         Item itemOne = items.get(0);
143         assertEquals(itemOne.getId(), "1");
144         assertEquals(itemOne.getParentID(), "0");
145         assertFalse(!itemOne.isRestricted());
146         assertEquals(itemOne.getTitle(), "Chloe Dancer");
147         assertNull(itemOne.getCreator());
148         assertEquals(itemOne.getClazz().getValue(), "object.item.audioItem.musicTrack");
149         Res resource = itemOne.getResources().get(0);
150         assertEquals(resource.getProtocolInfo().toString(), "http-get:*:audio/x-ms-wma:*");
151         assertNull(resource.getSize());
152         assertEquals(resource.getValue(), "http://10.0.0.1/somecontent.wma");
153         assertNull(resource.getDuration());
154         assertNull(resource.getBitrate());
155         assertNull(resource.getSampleFrequency());
156         assertNull(resource.getBitsPerSample());
157         assertNull(resource.getNrAudioChannels());
158         assertEquals(resource.getResolutionX(), 0);
159         assertEquals(resource.getResolutionY(), 0);
160         assertNull(resource.getColorDepth());
161         assertNull(resource.getProtection());
162         assertNull(resource.getImportUri());
163 
164         String xml = parser.generate(didl);
165 
166         parser.debugXML(xml);
167 
168         didl = parser.parse(xml);
169 
170         items = didl.getItems();
171         assertEquals(items.size(), 1);
172         itemOne = items.get(0);
173         assertEquals(itemOne.getId(), "1");
174         assertEquals(itemOne.getParentID(), "0");
175         assertFalse(!itemOne.isRestricted());
176         assertEquals(itemOne.getTitle(), "Chloe Dancer");
177         assertNull(itemOne.getCreator());
178         assertEquals(itemOne.getClazz().getValue(), "object.item.audioItem.musicTrack");
179         resource = itemOne.getResources().get(0);
180         assertEquals(resource.getProtocolInfo().toString(), "http-get:*:audio/x-ms-wma:*");
181         assertNull(resource.getSize());
182         assertEquals(resource.getValue(), "http://10.0.0.1/somecontent.wma");
183         assertNull(resource.getDuration());
184         assertNull(resource.getBitrate());
185         assertNull(resource.getSampleFrequency());
186         assertNull(resource.getBitsPerSample());
187         assertNull(resource.getNrAudioChannels());
188         assertEquals(resource.getResolutionX(), 0);
189         assertEquals(resource.getResolutionY(), 0);
190         assertNull(resource.getColorDepth());
191         assertNull(resource.getProtection());
192         assertNull(resource.getImportUri());
193     }
194 
195     @Test
196     public void readWriteMixed() throws Exception {
197 
198         final boolean[] tests = new boolean[1];
199 
200         // This is how you extend the parser for reading vendor-specific elements within root, container, or item scope
201         DIDLParser parser = new DIDLParser() {
202             @Override
203             protected DIDLParser.ItemHandler createItemHandler(Item instance, Handler parent) {
204                 return new ItemHandler(instance, parent) {
205                     @Override
206                     public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
207                         super.startElement(uri, localName, qName, attributes);
208                         if ("urn:my-vendor-extension".equals(uri) && localName.equals("foo")) {
209                             tests[0] = true;
210                         }
211                     }
212                 };
213             }
214         };
215 
216         DIDLContent didl = parser.parseResource("org/fourthline/cling/test/support/contentdirectory/samples/browseMixed.xml");
217         assertSampleMixed(didl);
218         assert tests[0];
219 
220         String xml = parser.generate(didl);
221 
222         //parser.debugXML(xml);
223 
224         didl = parser.parse(xml);
225         assertSampleMixed(didl);
226     }
227 
228     @Test
229     public void readWriteNested() throws Exception {
230 
231         DIDLContent didl = parser.parseResource("org/fourthline/cling/test/support/contentdirectory/samples/browseNested.xml");
232         assertSampleNested(didl);
233 
234         String xml = parser.generate(didl, true); // Special switch for nesting of items inside containers
235 
236         //parser.debugXML(xml);
237 
238         didl = parser.parse(xml);
239         assertSampleNested(didl);
240     }
241 
242     @Test
243     public void readWriteItemsMixed() throws Exception {
244 
245         DIDLContent didl = parser.parseResource("org/fourthline/cling/test/support/contentdirectory/samples/browseItemsMixed.xml");
246         assertSampleItemsMixed(didl);
247 
248         String xml = parser.generate(didl);
249 
250         //parser.debugXML(xml);
251 
252         didl = parser.parse(xml);
253         assertSampleItemsMixed(didl);
254     }
255 
256     @Test
257     public void readWriteFoldersMixed() throws Exception {
258 
259         DIDLContent didl = parser.parseResource("org/fourthline/cling/test/support/contentdirectory/samples/browseFoldersMixed.xml");
260         assertSampleFoldersMixed(didl);
261 
262         String xml = parser.generate(didl, true);
263 
264         // parser.debugXML(xml);
265 
266         didl = parser.parse(xml);
267         assertSampleFoldersMixed(didl);
268     }
269 
270     protected void assertSampleEmpty(DIDLContent didl) {
271         assertEquals(didl.getContainers().size(), 0);
272         assertEquals(didl.getDescMetadata().size(), 0);
273         assertEquals(didl.getItems().size(), 0);
274     }
275 
276     protected void assertSampleRoot(DIDLContent didl) {
277 
278         List<Container> containers = didl.getContainers();
279         assertEquals(containers.size(), 1);
280 
281         Container rootContainer = didl.getFirstContainer();
282 
283         assertEquals(rootContainer.getId(), "0");
284         assertEquals(rootContainer.getParentID(), "-1");
285         assertEquals(rootContainer.isRestricted(), true);
286         assertEquals(rootContainer.isSearchable(), true);
287         assertEquals(rootContainer.getTitle(), "My multimedia stuff");
288 
289         assertEquals(rootContainer.getCreator(), "John Doe");
290 
291         String longDescription = rootContainer.getFirstPropertyValue(DIDLObject.Property.UPNP.LONG_DESCRIPTION.class);
292         assertEquals(longDescription, "This is a long description!");
293 
294         assertEquals(rootContainer.getClazz().getFriendlyName(), "Folder");
295         assertEquals(rootContainer.getClazz().getValue(), "object.container.storageFolder");
296 
297         assertEquals(rootContainer.getSearchClasses().size(), 5);
298         assertEquals(rootContainer.getSearchClasses().get(0).isIncludeDerived(), false);
299         assertEquals(rootContainer.getSearchClasses().get(0).getValue(), "object.container.album.musicAlbum");
300         assertEquals(rootContainer.getSearchClasses().get(4).getValue(), "object.item.imageItem.photo.vendorAlbumArt");
301         assertEquals(rootContainer.getSearchClasses().get(4).getFriendlyName(), "Vendor Album Art");
302 
303         assertEquals(rootContainer.getFirstPropertyValue(DIDLObject.Property.UPNP.STORAGE_USED.class), new Long(907000));
304 
305         assertEquals(rootContainer.getWriteStatus(), WriteStatus.WRITABLE);
306     }
307 
308     protected void assertSampleRootChildren(DIDLContent didl) {
309 
310         List<Container> containers = didl.getContainers();
311         assertEquals(containers.size(), 3);
312 
313         Container myMusicContainer = didl.getContainers().get(0);
314         assertEquals(myMusicContainer.getId(), "1");
315         assertEquals(myMusicContainer.getParentID(), "0");
316         assertEquals(myMusicContainer.getChildCount(), new Integer(2));
317         assertEquals(myMusicContainer.isRestricted(), false);
318         assertEquals(myMusicContainer.isSearchable(), false);
319         assertEquals(myMusicContainer.getTitle(), "My Music");
320         assertEquals(myMusicContainer.getClazz().getValue(), "object.container.storageFolder");
321 
322         assertEquals(myMusicContainer.getFirstPropertyValue(DIDLObject.Property.UPNP.STORAGE_USED.class), new Long(730000));
323         assertEquals(myMusicContainer.getWriteStatus(), WriteStatus.WRITABLE);
324 
325         assertEquals(myMusicContainer.getSearchClasses().size(), 2);
326         assertEquals(myMusicContainer.getSearchClasses().get(0).isIncludeDerived(), false);
327         assertEquals(myMusicContainer.getSearchClasses().get(0).getValue(), "object.container.album.musicAlbum");
328         assertEquals(myMusicContainer.getSearchClasses().get(1).isIncludeDerived(), false);
329         assertEquals(myMusicContainer.getSearchClasses().get(1).getValue(), "object.item.audioItem.musicTrack");
330 
331         assertEquals(myMusicContainer.getCreateClasses().size(), 1);
332         assertEquals(myMusicContainer.getCreateClasses().get(0).isIncludeDerived(), false);
333         assertEquals(myMusicContainer.getCreateClasses().get(0).getValue(), "object.container.album.musicAlbum");
334 
335         Container myPhotosContainer = didl.getContainers().get(1);
336         assertEquals(myPhotosContainer.getId(), "2");
337         assertEquals(myPhotosContainer.getParentID(), "0");
338         assertEquals(myPhotosContainer.getChildCount(), new Integer(2));
339         assertEquals(myPhotosContainer.isRestricted(), false);
340         assertEquals(myPhotosContainer.isSearchable(), false);
341         assertEquals(myPhotosContainer.getTitle(), "My Photos");
342         assertEquals(myPhotosContainer.getClazz().getValue(), "object.container.storageFolder");
343 
344         assertEquals(myPhotosContainer.getFirstPropertyValue(DIDLObject.Property.UPNP.STORAGE_USED.class), new Long(177000));
345         assertEquals(myPhotosContainer.getWriteStatus(), WriteStatus.WRITABLE);
346 
347         assertEquals(myPhotosContainer.getSearchClasses().size(), 2);
348         assertEquals(myPhotosContainer.getSearchClasses().get(0).isIncludeDerived(), false);
349         assertEquals(myPhotosContainer.getSearchClasses().get(0).getValue(), "object.container.album.photoAlbum");
350         assertEquals(myPhotosContainer.getSearchClasses().get(1).isIncludeDerived(), false);
351         assertEquals(myPhotosContainer.getSearchClasses().get(1).getValue(), "object.item.imageItem.photo");
352 
353         assertEquals(myPhotosContainer.getCreateClasses().size(), 1);
354         assertEquals(myPhotosContainer.getCreateClasses().get(0).isIncludeDerived(), false);
355         assertEquals(myPhotosContainer.getCreateClasses().get(0).getValue(), "object.container.album.photoAlbum");
356 
357         Container albumArtContainer = didl.getContainers().get(2);
358         assertEquals(albumArtContainer.getId(), "3");
359         assertEquals(albumArtContainer.getParentID(), "0");
360         assertEquals(albumArtContainer.getChildCount(), new Integer(2));
361         assertEquals(albumArtContainer.isRestricted(), false);
362         assertEquals(albumArtContainer.isSearchable(), false);
363         assertEquals(albumArtContainer.getTitle(), "Album Art");
364         assertEquals(albumArtContainer.getClazz().getValue(), "object.container.storageFolder");
365 
366         assertEquals(albumArtContainer.getFirstPropertyValue(DIDLObject.Property.UPNP.STORAGE_USED.class), new Long(40000));
367         assertEquals(albumArtContainer.getWriteStatus(), WriteStatus.WRITABLE);
368 
369         assertEquals(albumArtContainer.getSearchClasses().size(), 1);
370         assertEquals(albumArtContainer.getSearchClasses().get(0).isIncludeDerived(), true);
371         assertEquals(albumArtContainer.getSearchClasses().get(0).getValue(), "object.item.imageItem.photo.vendorAlbumArt");
372 
373         assertEquals(albumArtContainer.getCreateClasses().size(), 1);
374         assertEquals(albumArtContainer.getCreateClasses().get(0).isIncludeDerived(), true);
375         assertEquals(albumArtContainer.getCreateClasses().get(0).getValue(), "object.item.imageItem.photo.vendorAlbumArt");
376     }
377 
378     protected void assertSampleFolder(DIDLContent didl) {
379 
380         List<Container> containers = didl.getContainers();
381         assertEquals(containers.size(), 2);
382 
383         Container brandNewDayContainer = didl.getContainers().get(0);
384 
385         assertEquals(brandNewDayContainer.getId(), "4");
386         assertEquals(brandNewDayContainer.getParentID(), "1");
387         assertEquals(brandNewDayContainer.getChildCount(), new Integer(3));
388         assertEquals(brandNewDayContainer.isRestricted(), false);
389         assertEquals(brandNewDayContainer.isSearchable(), false);
390         assertEquals(brandNewDayContainer.getTitle(), "Brand New Day");
391         assertEquals(brandNewDayContainer.getClazz().getValue(), "object.container.album.musicAlbum");
392 
393         assertEquals(brandNewDayContainer.getSearchClasses().size(), 1);
394         assertEquals(brandNewDayContainer.getSearchClasses().get(0).isIncludeDerived(), false);
395         assertEquals(brandNewDayContainer.getSearchClasses().get(0).getValue(), "object.item.audioItem.musicTrack");
396 
397         Container singlesSoundtrackContainer = didl.getContainers().get(1);
398         assertEquals(singlesSoundtrackContainer.getId(), "5");
399         assertEquals(singlesSoundtrackContainer.getParentID(), "1");
400         assertEquals(singlesSoundtrackContainer.getChildCount(), new Integer(4));
401         assertEquals(singlesSoundtrackContainer.isRestricted(), false);
402         assertEquals(singlesSoundtrackContainer.isSearchable(), false);
403         assertEquals(singlesSoundtrackContainer.getTitle(), "Singles Soundtrack");
404         assertEquals(singlesSoundtrackContainer.getClazz().getValue(), "object.container.album.musicAlbum");
405 
406         assertEquals(singlesSoundtrackContainer.getSearchClasses().size(), 1);
407         assertEquals(singlesSoundtrackContainer.getSearchClasses().get(0).isIncludeDerived(), false);
408         assertEquals(singlesSoundtrackContainer.getSearchClasses().get(0).getValue(), "object.item.audioItem.musicTrack");
409 
410         assertEquals(singlesSoundtrackContainer.getFirstPropertyValue(DIDLObject.Property.UPNP.STORAGE_USED.class), new Long(1234));
411         assertEquals(singlesSoundtrackContainer.getFirstPropertyValue(DIDLObject.Property.UPNP.STORAGE_FREE.class), new Long(12345));
412         assertEquals(singlesSoundtrackContainer.getFirstPropertyValue(DIDLObject.Property.UPNP.STORAGE_TOTAL.class), new Long(123456));
413         assertEquals(singlesSoundtrackContainer.getFirstPropertyValue(DIDLObject.Property.UPNP.STORAGE_MAX_PARTITION.class), new Long(1234567));
414         assertEquals(singlesSoundtrackContainer.getFirstPropertyValue(DIDLObject.Property.UPNP.STORAGE_MEDIUM.class), StorageMedium.UNKNOWN);
415 
416         assertEquals(singlesSoundtrackContainer.getFirstPropertyValue(DIDLObject.Property.UPNP.ALBUM_ART_URI.class).toString(), "http://some/album/art");
417         assertEquals(singlesSoundtrackContainer.getFirstPropertyValue(DIDLObject.Property.UPNP.ARTIST_DISCO_URI.class).toString(), "http://some/disco");
418         assertEquals(singlesSoundtrackContainer.getFirstPropertyValue(DIDLObject.Property.UPNP.LYRICS_URI.class).toString(), "http://some/lyrics");
419         
420         Property<URI> albumArtURI = singlesSoundtrackContainer.getFirstProperty(DIDLObject.Property.UPNP.ALBUM_ART_URI.class);
421         assertEquals(albumArtURI.getAttribute("profileID").getValue().getValue(), "JPEG_TN");
422     }
423 
424     protected void assertSampleItems(DIDLContent didl) {
425 
426         assertEquals(didl.getContainers().size(), 0);
427 
428         List<Item> items = didl.getItems();
429         assertEquals(items.size(), 4);
430 
431         Item itemOne = items.get(0);
432         assertEquals(itemOne.getId(), "6");
433         assertEquals(itemOne.getParentID(), "5");
434         assert !itemOne.isRestricted();
435         assertEquals(itemOne.getTitle(), "Chloe Dancer");
436         assertEquals(itemOne.getCreator(), "Mother Love Bone");
437         assertEquals(itemOne.getClazz().getValue(), "object.item.audioItem.musicTrack");
438         Res resource = itemOne.getResources().get(0);
439         assertEquals(resource.getProtocolInfo().toString(), "http-get:*:audio/x-ms-wma:*");
440         assertEquals(resource.getSize(), new Long(200000));
441         assertEquals(resource.getValue(), "http://10.0.0.1/getcontent.asp?id=6&foo=bar");
442         assertEquals(resource.getDuration(), "00:03:25");
443         assertEquals(resource.getBitrate(), new Long(8192));
444         assertEquals(resource.getSampleFrequency(), new Long(44100));
445         assertEquals(resource.getBitsPerSample(), new Long(16));
446         assertEquals(resource.getNrAudioChannels(), new Long(2));
447         assertEquals(resource.getResolutionX(), 120);
448         assertEquals(resource.getResolutionY(), 130);
449         assertEquals(resource.getColorDepth(), new Long(8));
450         assertEquals(resource.getProtection(), "None");
451         assertEquals(resource.getImportUri(), URI.create("http://10.0.0.1/import"));
452 
453         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.DC.DESCRIPTION.class), "Some Description");
454         assertEquals(itemOne.getPropertyValues(DIDLObject.Property.DC.PUBLISHER.class).size(), 2);
455         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.DC.CONTRIBUTOR.class).getName(), "Some Contributor");
456         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.DC.DATE.class), "2010-12-24");
457         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.DC.LANGUAGE.class), "en-US");
458         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.DC.RELATION.class).toString(), "http://some/related/resource");
459         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.DC.RIGHTS.class), "CC SA-BY");
460 
461         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.GENRE.class), "Pop");
462         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.ALBUM.class), "Singles Soundtrack");
463         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.ARTIST.class).getName(), "Mother Love Bone");
464         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.ARTIST.class).getRole(), "performer");
465         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.ACTOR.class).getName(), "Some Actor");
466         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.ACTOR.class).getRole(), "myrole");
467         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.AUTHOR.class).getName(), "Some Author");
468         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.AUTHOR.class).getRole(), "anotherrole");
469         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.PRODUCER.class).getName(), "Some Producer");
470         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.DIRECTOR.class).getName(), "Some Director");
471         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.PLAYLIST.class), "Some Playlist");
472         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.LONG_DESCRIPTION.class), "Some Long Description");
473         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.ICON.class).toString(), "http://some/icon");
474         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.REGION.class), "US");
475         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.RATING.class), "R");
476 
477         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.RADIO_CALL_SIGN.class), "KSJO");
478         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.RADIO_STATION_ID.class), "107.7");
479         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.RADIO_BAND.class), "FM");
480 
481         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.CHANNEL_NR.class), new Integer(123));
482         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.CHANNEL_NAME.class), "Some Channel");
483         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.SCHEDULED_START_TIME.class), "2010-12-24T14:33:55");
484         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.SCHEDULED_END_TIME.class), "2010-12-24T14:43:55");
485 
486         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.DVD_REGION_CODE.class), new Integer(2));
487         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.ORIGINAL_TRACK_NUMBER.class), new Integer(11));
488         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.TOC.class), "123abc");
489         assertEquals(itemOne.getFirstPropertyValue(DIDLObject.Property.UPNP.USER_ANNOTATION.class), "Some User Annotation");
490 
491         Item itemTwo = items.get(1);
492         assertEquals(itemTwo.getId(), "7");
493         assertEquals(itemTwo.getParentID(), "5");
494         assert !itemTwo.isRestricted();
495         assertEquals(itemTwo.getTitle(), "Drown");
496         assertEquals(itemTwo.getCreator(), "Smashing Pumpkins");
497         assertEquals(itemTwo.getClazz().getValue(), "object.item.audioItem.musicTrack");
498         resource = itemTwo.getResources().get(0);
499         assertEquals(resource.getProtocolInfo().toString(), "http-get:*:audio/mpeg:*");
500         assertEquals(resource.getSize(), new Long(140000));
501         assertEquals(resource.getValue(), "http://10.0.0.1/getcontent.asp?id=7");
502 
503         Item itemThree = items.get(2);
504         assertEquals(itemThree.getId(), "8");
505         assertEquals(itemThree.getParentID(), "5");
506         assert !itemThree.isRestricted();
507         assertEquals(itemThree.getTitle(), "State Of Love And Trust");
508         assertEquals(itemThree.getCreator(), null);
509         assertEquals(itemThree.getClazz().getValue(), "object.item.audioItem.musicTrack");
510         resource = itemThree.getResources().get(0);
511         assertEquals(resource.getProtocolInfo().toString(), "http-get:*:audio/x-ms-wma:*");
512         assertEquals(resource.getSize(), new Long(70000));
513         assertEquals(resource.getValue(), "http://10.0.0.1/getcontent.asp?id=8");
514 
515         Item itemFour = items.get(3);
516         assertEquals(itemFour.getId(), "9");
517         assertEquals(itemFour.getParentID(), "5");
518         assertEquals(itemFour.getRefID(), "8");
519         assert !itemFour.isRestricted();
520         assertEquals(itemFour.getTitle(), "State Of Love And Trust");
521         assertEquals(itemFour.getCreator(), "Pearl Jam");
522 
523     }
524 
525     protected void assertSampleMixed(DIDLContent didl) throws Exception {
526 
527         DescMeta meta0 = didl.getDescMetadata().get(0);
528         assertEquals(meta0.getId(), "a1");
529         assertEquals(meta0.getType(), "Some Text");
530         assertEquals(meta0.getNameSpace().toString(), "urn:my-vendor-extension");
531         Document meta0Doc = (Document) meta0.getMetadata();
532         assertEquals(documentToString(meta0Doc), "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>" +
533                 "<desc-wrapper xmlns=\"urn:fourthline-org:cling:support:content-directory-desc-1-0\">" +
534                 "<vendor:foo xmlns:vendor=\"urn:my-vendor-extension\">" +
535                 "<vendor:bar vendor:abc=\"123\">aaa</vendor:bar>" +
536                 "<vendor:baz>bbb</vendor:baz>" +
537                 "</vendor:foo>" +
538                 "</desc-wrapper>");
539 
540         List<Container> containers = didl.getContainers();
541         assertEquals(containers.size(), 1);
542 
543         Container slideShowContainer = didl.getContainers().get(0);
544 
545         assertEquals(slideShowContainer.getId(), "10");
546         assertEquals(slideShowContainer.getParentID(), "5");
547         assertEquals(slideShowContainer.getChildCount(), new Integer(3));
548         assertEquals(slideShowContainer.isRestricted(), true);
549         assertEquals(slideShowContainer.isSearchable(), false);
550         assertEquals(slideShowContainer.getTitle(), "Slideshow");
551         assertEquals(slideShowContainer.getClazz().getValue(), "object.container.album.photoAlbum");
552 
553         DescMeta meta1 = slideShowContainer.getDescMetadata().get(0);
554         assertEquals(meta1.getId(), "b1");
555         assertEquals(meta1.getType(), "Some Text");
556         assertEquals(meta1.getNameSpace().toString(), "urn:my-vendor-extension");
557         Document meta1Doc = (Document) meta1.getMetadata();
558         assertEquals(documentToString(meta1Doc), "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>" +
559                 "<desc-wrapper xmlns=\"urn:fourthline-org:cling:support:content-directory-desc-1-0\">" +
560                 "<vendor:foo xmlns:vendor=\"urn:my-vendor-extension\">bar</vendor:foo>" +
561                 "</desc-wrapper>");
562 
563         List<Item> items = didl.getItems();
564         assertEquals(items.size(), 3);
565 
566         Item itemOne = items.get(0);
567         assertEquals(itemOne.getId(), "6");
568         assertEquals(itemOne.getParentID(), "5");
569         assert itemOne.isRestricted();
570         assertEquals(itemOne.getTitle(), "Chloe Dancer");
571         assertEquals(itemOne.getCreator(), "Mother Love Bone");
572         assertEquals(itemOne.getClazz().getValue(), "object.item.audioItem.musicTrack");
573         Res resource = itemOne.getResources().get(0);
574         assertEquals(resource.getProtocolInfo().toString(), "http-get:*:audio/x-ms-wma:*");
575         assertEquals(resource.getSize(), new Long(200000));
576         assertEquals(resource.getValue(), "http://10.0.0.1/getcontent.asp?id=6");
577 
578         DescMeta meta2 = itemOne.getDescMetadata().get(0);
579         assertEquals(meta2.getId(), "c1");
580         assertEquals(meta2.getType(), "Some Text");
581         assertEquals(meta2.getNameSpace().toString(), "urn:my-vendor-extension");
582         Document meta2Doc = (Document) meta2.getMetadata();
583         assertEquals(documentToString(meta2Doc), "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>" +
584                 "<desc-wrapper xmlns=\"urn:fourthline-org:cling:support:content-directory-desc-1-0\">" +
585                 "<vendor:foo xmlns:vendor=\"urn:my-vendor-extension\">bar</vendor:foo>" +
586                 "</desc-wrapper>");
587 
588         DescMeta meta3 = itemOne.getDescMetadata().get(1);
589         assertEquals(meta3.getId(), "c2");
590         assertEquals(meta3.getType(), "More Text");
591         assertEquals(meta3.getNameSpace().toString(), "urn:my-vendor-extension");
592         Document meta3Doc = (Document) meta3.getMetadata();
593         assertEquals(documentToString(meta3Doc), "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>" +
594                 "<desc-wrapper xmlns=\"urn:fourthline-org:cling:support:content-directory-desc-1-0\">" +
595                 "<vendor:foo xmlns:vendor=\"urn:my-vendor-extension\">baz</vendor:foo>" +
596                 "</desc-wrapper>");
597 
598         Item itemTwo = items.get(1);
599         assertEquals(itemTwo.getId(), "7");
600         assertEquals(itemTwo.getParentID(), "5");
601         assert itemTwo.isRestricted();
602         assertEquals(itemTwo.getTitle(), "Drown");
603         assertEquals(itemTwo.getCreator(), "Smashing Pumpkins");
604         assertEquals(itemTwo.getClazz().getValue(), "object.item.audioItem.musicTrack");
605         resource = itemTwo.getResources().get(0);
606         assertEquals(resource.getProtocolInfo().toString(), "http-get:*:audio/mpeg:*");
607         assertEquals(resource.getSize(), new Long(140000));
608         assertEquals(resource.getValue(), "http://10.0.0.1/getcontent.asp?id=7");
609 
610         Item itemThree = items.get(2);
611         assertEquals(itemThree.getId(), "8");
612         assertEquals(itemThree.getParentID(), "5");
613         assert itemThree.isRestricted();
614         assertEquals(itemThree.getTitle(), "State Of Love And Trust");
615         assertEquals(itemThree.getCreator(), "Pearl Jam");
616         assertEquals(itemThree.getClazz().getValue(), "object.item.audioItem.musicTrack");
617         resource = itemThree.getResources().get(0);
618         assertEquals(resource.getProtocolInfo().toString(), "http-get:*:audio/x-ms-wma:*");
619         assertEquals(resource.getSize(), new Long(70000));
620         assertEquals(resource.getValue(), "http://10.0.0.1/getcontent.asp?id=8");
621 
622     }
623 
624     protected void assertSampleNested(DIDLContent didl) {
625 
626         List<Container> containers = didl.getContainers();
627         assertEquals(containers.size(), 1);
628 
629         Container container = didl.getContainers().get(0);
630 
631         assertEquals(container.getId(), "5");
632         assertEquals(container.getParentID(), "1");
633         assertEquals(container.getChildCount(), new Integer(4));
634         assertEquals(container.isRestricted(), false);
635         assertEquals(container.isSearchable(), false);
636         assertEquals(container.getTitle(), "Singles Soundtrack");
637         assertEquals(container.getClazz().getValue(), "object.container.album.musicAlbum");
638         assertEquals(container.getSearchClasses().size(), 1);
639         assertEquals(container.getSearchClasses().get(0).isIncludeDerived(), false);
640         assertEquals(container.getSearchClasses().get(0).getValue(), "object.item.audioItem.musicTrack");
641 
642         List<Item> items = container.getItems();
643         assertEquals(items.size(), 3);
644 
645         Item itemOne = items.get(0);
646         assertEquals(itemOne.getId(), "6");
647         assertEquals(itemOne.getParentID(), "5");
648         assert itemOne.isRestricted();
649         assertEquals(itemOne.getTitle(), "Chloe Dancer");
650         assertEquals(itemOne.getCreator(), "Mother Love Bone");
651         assertEquals(itemOne.getClazz().getValue(), "object.item.audioItem.musicTrack");
652         Res resource = itemOne.getResources().get(0);
653         assertEquals(resource.getProtocolInfo().toString(), "http-get:*:audio/x-ms-wma:*");
654         assertEquals(resource.getSize(), new Long(200000));
655         assertEquals(resource.getValue(), "http://10.0.0.1/getcontent.asp?id=6");
656 
657         Item itemTwo = items.get(1);
658         assertEquals(itemTwo.getId(), "7");
659         assertEquals(itemTwo.getParentID(), "5");
660         assert itemTwo.isRestricted();
661         assertEquals(itemTwo.getTitle(), "Drown");
662         assertEquals(itemTwo.getCreator(), "Smashing Pumpkins");
663         assertEquals(itemTwo.getClazz().getValue(), "object.item.audioItem.musicTrack");
664         resource = itemTwo.getResources().get(0);
665         assertEquals(resource.getProtocolInfo().toString(), "http-get:*:audio/mpeg:*");
666         assertEquals(resource.getSize(), new Long(140000));
667         assertEquals(resource.getValue(), "http://10.0.0.1/getcontent.asp?id=7");
668 
669         Item itemThree = items.get(2);
670         assertEquals(itemThree.getId(), "8");
671         assertEquals(itemThree.getParentID(), "5");
672         assert itemThree.isRestricted();
673         assertEquals(itemThree.getTitle(), "State Of Love And Trust");
674         assertEquals(itemThree.getCreator(), "Pearl Jam");
675         assertEquals(itemThree.getClazz().getValue(), "object.item.audioItem.musicTrack");
676         resource = itemThree.getResources().get(0);
677         assertEquals(resource.getProtocolInfo().toString(), "http-get:*:audio/x-ms-wma:*");
678         assertEquals(resource.getSize(), new Long(70000));
679         assertEquals(resource.getValue(), "http://10.0.0.1/getcontent.asp?id=8");
680 
681         // More specific types
682 
683         MusicAlbum album = (MusicAlbum)container;
684         assertEquals(album.getMusicTracks()[0].getTitle(), "Chloe Dancer");
685         assertEquals(album.getMusicTracks()[1].getTitle(), "Drown");
686         assertEquals(album.getMusicTracks()[2].getTitle(), "State Of Love And Trust");
687 
688     }
689 
690     protected void assertSampleItemsMixed(DIDLContent didl) {
691 
692         assertEquals(didl.getContainers().size(), 0);
693 
694         List<Item> items = didl.getItems();
695 
696         MusicTrack item0 = (MusicTrack) items.get(0);
697         assertEquals(item0.getFirstGenre(), "Pop");
698         assertEquals(item0.getDescription(), "Some Description");
699         assertEquals(item0.getLongDescription(), "Some Long Description");
700         assertEquals(item0.getPublishers()[0].getName(), "Some Publisher");
701         assertEquals(item0.getPublishers()[1].getName(), "Another Publisher");
702         assertEquals(item0.getLanguage(), "en-US");
703         assertEquals(item0.getFirstRelation().toString(), "http://some/related/resource");
704         assertEquals(item0.getFirstRights(), "CC SA-BY");
705         assertEquals(item0.getFirstArtist().getName(), "Some Artist");
706         assertEquals(item0.getFirstArtist().getRole(), "Performer");
707         assertEquals(item0.getAlbum(), "Some Album");
708         assertEquals(item0.getOriginalTrackNumber(), new Integer(11));
709         assertEquals(item0.getFirstPlaylist(), "Some Playlist");
710         assertEquals(item0.getStorageMedium(), StorageMedium.NETWORK);
711         assertEquals(item0.getFirstContributor().getName(), "Some Contributor");
712         assertEquals(item0.getDate(), "2010-12-24");
713 
714         AudioBook item1 = (AudioBook) items.get(1);
715         assertEquals(item1.getFirstGenre(), "Pop");
716         assertEquals(item1.getDescription(), "Some Description");
717         assertEquals(item1.getLongDescription(), "Some Long Description");
718         assertEquals(item1.getPublishers()[0].getName(), "Some Publisher");
719         assertEquals(item1.getPublishers()[1].getName(), "Another Publisher");
720         assertEquals(item1.getLanguage(), "en-US");
721         assertEquals(item1.getFirstRelation().toString(), "http://some/related/resource");
722         assertEquals(item1.getFirstRights(), "CC SA-BY");
723         assertEquals(item1.getFirstProducer().getName(), "Some Producer");
724         assertEquals(item1.getFirstContributor().getName(), "Some Contributor");
725         assertEquals(item1.getDate(), "2010-12-24");
726         assertEquals(item1.getStorageMedium(), StorageMedium.NETWORK);
727 
728         AudioBroadcast item2 = (AudioBroadcast) items.get(2);
729         assertEquals(item2.getFirstGenre(), "Pop");
730         assertEquals(item2.getDescription(), "Some Description");
731         assertEquals(item2.getLongDescription(), "Some Long Description");
732         assertEquals(item2.getPublishers()[0].getName(), "Some Publisher");
733         assertEquals(item2.getPublishers()[1].getName(), "Another Publisher");
734         assertEquals(item2.getLanguage(), "en-US");
735         assertEquals(item2.getFirstRelation().toString(), "http://some/related/resource");
736         assertEquals(item2.getFirstRights(), "CC SA-BY");
737         assertEquals(item2.getRegion(), "US");
738         assertEquals(item2.getRadioCallSign(), "KSJO");
739         assertEquals(item2.getRadioStationID(), "107.7");
740         assertEquals(item2.getRadioBand(), "FM");
741         assertEquals(item2.getChannelNr(), new Integer(123));
742 
743         Movie item3 = (Movie) items.get(3);
744         assertEquals(item3.getFirstGenre(), "Pop");
745         assertEquals(item3.getDescription(), "Some Description");
746         assertEquals(item3.getLongDescription(), "Some Long Description");
747         assertEquals(item3.getFirstDirector().getName(), "Some Director");
748         assertEquals(item3.getFirstProducer().getName(), "Some Producer");
749         assertEquals(item3.getPublishers()[0].getName(), "Some Publisher");
750         assertEquals(item3.getPublishers()[1].getName(), "Another Publisher");
751         assertEquals(item3.getLanguage(), "en-US");
752         assertEquals(item3.getFirstRelation().toString(), "http://some/related/resource");
753         assertEquals(item3.getRating(), "R");
754         assertEquals(item3.getStorageMedium(), StorageMedium.NETWORK);
755         assertEquals(item3.getDVDRegionCode(), new Integer(2));
756         assertEquals(item3.getChannelName(), "Some Channel");
757         assertEquals(item3.getFirstScheduledStartTime(), "2010-12-24T14:33:55");
758         assertEquals(item3.getFirstScheduledEndTime(), "2010-12-24T14:43:55");
759 
760         VideoBroadcast item4 = (VideoBroadcast) items.get(4);
761         assertEquals(item4.getFirstGenre(), "Pop");
762         assertEquals(item4.getDescription(), "Some Description");
763         assertEquals(item4.getLongDescription(), "Some Long Description");
764         assertEquals(item4.getFirstDirector().getName(), "Some Director");
765         assertEquals(item4.getFirstProducer().getName(), "Some Producer");
766         assertEquals(item4.getPublishers()[0].getName(), "Some Publisher");
767         assertEquals(item4.getPublishers()[1].getName(), "Another Publisher");
768         assertEquals(item4.getLanguage(), "en-US");
769         assertEquals(item4.getFirstRelation().toString(), "http://some/related/resource");
770         assertEquals(item4.getRating(), "R");
771         assertEquals(item4.getIcon().toString(), "http://some/icon");
772         assertEquals(item4.getRegion(), "US");
773         assertEquals(item4.getChannelNr(), new Integer(123));
774 
775         MusicVideoClip item5 = (MusicVideoClip) items.get(5);
776         assertEquals(item5.getFirstGenre(), "Pop");
777         assertEquals(item5.getDescription(), "Some Description");
778         assertEquals(item5.getLongDescription(), "Some Long Description");
779         assertEquals(item5.getFirstDirector().getName(), "Some Director");
780         assertEquals(item5.getFirstProducer().getName(), "Some Producer");
781         assertEquals(item5.getPublishers()[0].getName(), "Some Publisher");
782         assertEquals(item5.getPublishers()[1].getName(), "Another Publisher");
783         assertEquals(item5.getLanguage(), "en-US");
784         assertEquals(item5.getFirstRelation().toString(), "http://some/related/resource");
785         assertEquals(item5.getRating(), "R");
786         assertEquals(item5.getFirstArtist().getName(), "Some Artist");
787         assertEquals(item5.getFirstArtist().getRole(), "Performer");
788         assertEquals(item5.getAlbum(), "Some Album");
789         assertEquals(item5.getStorageMedium(), StorageMedium.NETWORK);
790         assertEquals(item5.getFirstContributor().getName(), "Some Contributor");
791         assertEquals(item5.getDate(), "2010-12-24");
792         assertEquals(item5.getFirstScheduledStartTime(), "2010-12-24T14:33:55");
793         assertEquals(item5.getFirstScheduledEndTime(), "2010-12-24T14:43:55");
794 
795         Photo item6 = (Photo) items.get(6);
796         assertEquals(item6.getDescription(), "Some Description");
797         assertEquals(item6.getLongDescription(), "Some Long Description");
798         assertEquals(item6.getPublishers()[0].getName(), "Some Publisher");
799         assertEquals(item6.getPublishers()[1].getName(), "Another Publisher");
800         assertEquals(item6.getRating(), "R");
801         assertEquals(item6.getDate(), "2010-12-24");
802         assertEquals(item6.getStorageMedium(), StorageMedium.NETWORK);
803         assertEquals(item6.getFirstRights(), "CC SA-BY");
804         assertEquals(item6.getAlbum(), "Some Album");
805 
806         PlaylistItem item7 = (PlaylistItem) items.get(7);
807         assertEquals(item7.getFirstGenre(), "Pop");
808         assertEquals(item7.getDescription(), "Some Description");
809         assertEquals(item7.getLongDescription(), "Some Long Description");
810         assertEquals(item7.getLanguage(), "en-US");
811         assertEquals(item7.getFirstArtist().getName(), "Some Artist");
812         assertEquals(item7.getFirstArtist().getRole(), "Performer");
813         assertEquals(item7.getStorageMedium(), StorageMedium.NETWORK);
814         assertEquals(item7.getDate(), "2010-12-24");
815 
816         TextItem item8 = (TextItem) items.get(8);
817         assertEquals(item8.getDescription(), "Some Description");
818         assertEquals(item8.getLongDescription(), "Some Long Description");
819         assertEquals(item8.getFirstAuthor().getName(), "Some Author");
820         assertEquals(item8.getFirstAuthor().getRole(), "anotherrole");
821         assertEquals(item8.getStorageMedium(), StorageMedium.NETWORK);
822         assertEquals(item8.getRating(), "R");
823         assertEquals(item8.getPublishers()[0].getName(), "Some Publisher");
824         assertEquals(item8.getPublishers()[1].getName(), "Another Publisher");
825         assertEquals(item5.getFirstContributor().getName(), "Some Contributor");
826         assertEquals(item8.getLanguage(), "en-US");
827         assertEquals(item8.getFirstRelation().toString(), "http://some/related/resource");
828         assertEquals(item8.getDate(), "2010-12-24");
829         assertEquals(item6.getFirstRights(), "CC SA-BY");
830     }
831 
832     protected void assertSampleFoldersMixed(DIDLContent didl) {
833 
834         assertEquals(didl.getItems().size(), 0);
835 
836         List<Container> containers = didl.getContainers();
837 
838         Album c0 = (Album) containers.get(0);
839         assertEquals(c0.getChildCount(), new Integer(3));
840         assertEquals(c0.isRestricted(), true);
841         assertEquals(c0.getDescription(), "Some Description");
842         assertEquals(c0.getLongDescription(), "Some Long Description");
843         assertEquals(c0.getPublishers()[0].getName(), "Some Publisher");
844         assertEquals(c0.getPublishers()[1].getName(), "Another Publisher");
845         assertEquals(c0.getFirstRelation().toString(), "http://some/related/resource");
846         assertEquals(c0.getFirstRights(), "CC SA-BY");
847         assertEquals(c0.getStorageMedium(), StorageMedium.NETWORK);
848         assertEquals(c0.getFirstContributor().getName(), "Some Contributor");
849         assertEquals(c0.getDate(), "2010-12-24");
850 
851         PhotoAlbum c1 = (PhotoAlbum)containers.get(1);
852         assertEquals(c1.getChildCount(), new Integer(2));
853         assertEquals(c1.getTitle(), "Some Photos");
854         assertEquals(c1.getPhotos()[0].getTitle(), "Photo 2010");
855         assertEquals(c1.getPhotos()[0].getAlbum(), "Some Photos");
856         assertEquals(c1.getPhotos()[1].getTitle(), "Photo 2011");
857         assertEquals(c1.getPhotos()[1].getAlbum(), "Some Photos");
858     }
859 
860     public String documentToString(Document document) throws Exception {
861         TransformerFactory transFactory = TransformerFactory.newInstance();
862         Transformer transformer = transFactory.newTransformer();
863         transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
864         StringWriter out = new StringWriter();
865         transformer.transform(new DOMSource(document), new StreamResult(out));
866         return out.toString();
867     }
868 }
869