long firstResult, long maxResults,
SortCriterion[] orderby) throws Exception {
DIDLContent didl = new DIDLContent();
LibraryBrowseService browseService = new LibraryBrowseService();
String smdObjectID = null;
Integer smdMaxItems;
List<String> filters = this.filterStringToList(filter);
// if objectID is 0, the client asks for root menu (null value for SMD)
if(objectID.equals("0")) {
smdObjectID = null;
}else {
smdObjectID = objectID;
}
// if upnp maxResults is 0, there's no limit
if(maxResults==0) {
smdMaxItems = null;
} else { // items to return is limited
smdMaxItems = new Integer((int)maxResults);
}
Result<Object> browsedContent = browseService.findChildren("upnp", smdObjectID, (int)firstResult, smdMaxItems, false);
// Memo: DIDL object mandatory elements:
// id, parentID, title, class, restricted (for 'object' base class)
Container upnpContainer = null;
Item upnpItem = null;
for(ResultItem<?> browsedItem: browsedContent.getItems()) {
// nullify container to prevent a bug if browsedItem type is unknown
// unless nullified, the same object will be added twice in didl document
upnpContainer = null;
if(browsedItem.getType().equals("Folder") || browsedItem.getType().equals("ImageFolder") ) {
// found item is a Folder (could be root elements, LastFM Image, etc.
upnpContainer = new SmdFolder( (ResultItem<String>)browsedItem);
// create object ID (parentId/itemID)
if(smdObjectID != null) {
upnpContainer.setId(smdObjectID+"/"+browsedItem.getId());
}
// before r839: upnpContainer.setChildCount(browseService.findChildren(browsedItem.getId(), null, null, false).getCount().intValue());
// after r839: upnpContainer.setChildCount(browseService.findChildren("upnp", browsedItem.getId(), null, null, false).getCount().intValue());
} else if (browsedItem.getType().equals("Artist") ) {
// SMD Item is considered as an artist, create corresponding UPnP container
ResultItem<ArtistEntity> artistItem = (ResultItem<ArtistEntity>) browsedItem;
org.teleal.cling.support.model.container.MusicArtist upnpMusicArtist = new org.teleal.cling.support.model.container.MusicArtist();
upnpContainer = upnpMusicArtist;
upnpMusicArtist.setId(objectID+"/"+artistItem.getId())
.setClazz(new org.teleal.cling.support.model.DIDLObject.Class("object.container.person.musicArtist"))
.setTitle(artistItem.getItem().getName());
System.err.println("CurrentArtist: "+upnpMusicArtist.getTitle());
// TODO: Artist can have "artistDiscographyURI"
// upnpMusicArtist.setGenres( new String[] {"Unknown"} );
// findChildren seems to require parent path concatenation now
//upnpContainer.setChildCount(browseService.findChildren(artistItem.getId(), null, null, false).getCount().intValue());
// upnpContainer.setChildCount(browseService.findChildren(objectID+"/"+artistItem.getId(), null, null, false).getCount().intValue());
// search for artist genre
// TODO: activate again when performance problem is gone
// List<String> artistGenres = new ArrayList<String>();
// for(ResultItem<ClassificationEntity> classificationResult: classificationBrowseService.findChildren(Arrays.asList(artistItem.getId()), null, 0, null, false).getItems() ) {
// ClassificationEntity classification = classificationResult.getItem();
// if(classification.getType().equals("genre")) {
// artistGenres.add(classification.getName());
// }
// }
// if(artistGenres.size()>0) {
// upnpMusicArtist.setGenres(artistGenres.toArray(new String[0]));
// }
} else if (browsedItem.getType().equals("Release") ) {
ResultItem<ReleaseEntity> releaseItem = (ResultItem<ReleaseEntity>) browsedItem;
MusicAlbum upnpAlbum = new MusicAlbum();
upnpContainer = upnpAlbum;
List<PersonWithRole> contributors = new ArrayList<PersonWithRole>();
// try {
Collection<ResultItem<ArtistEntity>> artists =
artistBrowseService.findChildren(Arrays.asList(releaseItem.getId()), null, 0, null, false).getItems();
for(ResultItem<ArtistEntity> artist : artists) {
// TODO: replace hard coded "performer" by SMD role
contributors.add(new PersonWithRole(artist.getItem().getName(), "Performer"));
}
upnpAlbum.setArtists(contributors.toArray(new PersonWithRole[0] ));
// TODO: check what happens if there's no artist (should be handled below by contributors.size test)
// } catch(java.util.NoSuchElementException Ex) {
// // ignore this exception, it means there's no artist for that album
// }
upnpAlbum.setId(objectID+"/"+releaseItem.getId());
upnpAlbum.setClazz(new org.teleal.cling.support.model.DIDLObject.Class("object.container.album.musicAlbum"));
if(contributors.size()>0) {
upnpAlbum.setCreator(contributors.get(0).getName());
} else {
upnpAlbum.setCreator("unknown");
}
upnpAlbum.setTitle(releaseItem.getItem().getName());
upnpAlbum.addProperty(new DIDLObject.Property.UPNP.ALBUM(upnpAlbum.getTitle()) );
upnpAlbum.setDescription("aze");
// <albumArtUri dlna:profileID="PNG_TN">
// <albumArtUri dlna:profileID="JPEG_TN">
upnpAlbum.setAlbumArtURIs(new URI[] { new URI(releaseItem.getImage().getUrl())} );
Property<URI>[] albumArtUriProperties = upnpAlbum.getProperties(UPNP.ALBUM_ART_URI.class);
for(Property<URI> uriProperty : albumArtUriProperties) {
//DIDLObject.Property.DLNA.PROFILE_ID toto = new DIDLObject.Property.DLNA.PROFILE_ID();
//toto.getValue().
//DIDLAttribute tutu = new DIDLAttribute(DIDLObject.Property.DLNA, "dlna", "zeazé")
// value for dlna:profileID attribute of upnp:albumArtURI element
String upnpProfileID;
if(uriProperty.getValue().toString().endsWith(".png")) {
upnpProfileID = "PNG_TN";
} else {
// if extension isn't png, suppose it's JPEG (may be a bad guess)
upnpProfileID = "JPEG_TN";
// TODO: improve image entity to contain image type or enhance this code
// to detect image format
}
uriProperty.addAttribute(
new DIDLObject.Property.DLNA.PROFILE_ID(
new DIDLAttribute(
DIDLObject.Property.DLNA.NAMESPACE.URI,
"dlna",
upnpProfileID)
)
);
}
// search for album genre
// commented for performance reason, should be uncommented or changed
// when performance problem is solved
// List<String> albumGenres = new ArrayList<String>();
// for(ResultItem<ClassificationEntity> classificationResult: classificationBrowseService.findChildren(Arrays.asList(releaseItem.getId()), null, 0, null, false).getItems() ) {
// ClassificationEntity classification = classificationResult.getItem();
// if(classification.getType().equals("genre")) {
// albumGenres.add(classification.getName());
// }
// }
// construct album genres from genre, style and moods classifications
List<String> albumGenres = new ArrayList<String>();
for(ResultItem<ClassificationEntity> classificationResult:
classificationBrowseService.findChildren(
Arrays.asList(releaseItem.getId(),"Classification.genre"),
null, 0, null, false).getItems()
) {
StringTokenizer sk = new StringTokenizer(classificationResult.getItem().getName(), ",");
while(sk.hasMoreTokens() ) {
String genre = sk.nextToken().trim();
if(!albumGenres.contains(genre))
albumGenres.add(genre);
}
}
for(ResultItem<ClassificationEntity> classificationResult:
classificationBrowseService.findChildren(
Arrays.asList(releaseItem.getId(),"Classification.style"),
null, 0, null, false).getItems()
) {
// albumGenres.addAll( Arrays.asList(classificationResult.getItem().getName().split(" ")) );
StringTokenizer sk = new StringTokenizer(classificationResult.getItem().getName(), ",");
while(sk.hasMoreTokens() ) {
String genre = sk.nextToken().trim();
if(!albumGenres.contains(genre))
albumGenres.add(genre);
}
}
for(ResultItem<ClassificationEntity> classificationResult:
classificationBrowseService.findChildren(
Arrays.asList(releaseItem.getId(),"Classification.mood"),
null, 0, null, false).getItems()
) {
// albumGenres.add(classificationResult.getItem().getName());
StringTokenizer sk = new StringTokenizer(classificationResult.getItem().getName(), ",");
while(sk.hasMoreTokens() ) {
String genre = sk.nextToken().trim();
if(!albumGenres.contains(genre))
albumGenres.add(genre);
}
}
if(albumGenres.size()>0) {
upnpAlbum.setGenres(albumGenres.toArray(new String[0]));
}
// TODO: add childcount is asked for by the client parameters
// before r839: upnpContainer.setChildCount(browseService.findChildren(objectID+"/"+releaseItem.getId(), null, null, false).getCount().intValue());
// after r839: upnpContainer.setChildCount(browseService.findChildren("upnp", artistItem.getId(), null, null, false).getCount().intValue());
} else if (browsedItem.getType().equals("Classification") ) {
ResultItem<ClassificationEntity> classificationItem = (ResultItem<ClassificationEntity>) browsedItem;
upnpContainer = new org.teleal.cling.support.model.container.MusicArtist();
upnpContainer.setId(objectID+"/"+classificationItem.getId())
.setClazz(new org.teleal.cling.support.model.DIDLObject.Class("object.container.genre.musicGenre"))
.setTitle(classificationItem.getItem().getName());
upnpContainer.setChildCount(browseService.findChildren("upnp", classificationItem.getId(), null, null, false).getCount().intValue());
} else if (browsedItem.getType().equals("Track") ) {
upnpItem = getUpnpMusicTrackFromSmdTrackEntity((ResultItem<TrackEntity>)browsedItem, objectID, filters);