/*
* Copyright (C) 2011 Teleal GmbH, Switzerland
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.teleal.cling.support.model;
import org.w3c.dom.Element;
import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @author Christian Bauer
* @author Mario Franco
*/
public abstract class DIDLObject {
static public abstract class Property<V> {
public interface NAMESPACE {
}
private V value;
final private String descriptorName;
final private List<Property<DIDLAttribute>> attributes = new ArrayList<Property<DIDLAttribute>>();
protected Property() {
this(null, null);
}
protected Property(String descriptorName) {
this(null, descriptorName);
}
protected Property(V value, String descriptorName) {
this.value = value;
this.descriptorName = descriptorName == null ? getClass().getSimpleName().toLowerCase() : descriptorName;
}
protected Property(V value, String descriptorName, List<Property<DIDLAttribute>> attributes) {
this.value = value;
this.descriptorName = descriptorName == null ? getClass().getSimpleName().toLowerCase() : descriptorName;
this.attributes.addAll(attributes);
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
public String getDescriptorName() {
return descriptorName;
}
public void setOnElement(Element element) {
element.setTextContent(toString());
for (Property<DIDLAttribute> attr : attributes) {
element.setAttributeNS(
attr.getValue().getNamespaceURI(),
attr.getValue().getPrefix() + ':' + attr.getDescriptorName(),
attr.getValue().getValue());
}
}
public void addAttribute(Property<DIDLAttribute> attr) {
this.attributes.add(attr);
}
public void removeAttribute(Property<DIDLAttribute> attr) {
this.attributes.remove(attr);
}
public void removeAttribute(String descriptorName) {
for (Property<DIDLAttribute> attr : attributes) {
if (attr.getDescriptorName().equals(descriptorName)) {
this.removeAttribute(attr);
break;
}
}
}
public Property<DIDLAttribute> getAttribute(String descriptorName) {
for (Property<DIDLAttribute> attr : attributes) {
if (attr.getDescriptorName().equals(descriptorName)) {
return attr;
}
}
return null;
}
@Override
public String toString() {
return getValue() != null ? getValue().toString() : "";
}
static public class PropertyPersonWithRole extends Property<PersonWithRole> {
public PropertyPersonWithRole() {
}
public PropertyPersonWithRole(String descriptorName) {
super(descriptorName);
}
public PropertyPersonWithRole(PersonWithRole value, String descriptorName) {
super(value, descriptorName);
}
@Override
public void setOnElement(Element element) {
if (getValue() != null)
getValue().setOnElement(element);
}
}
static public class DC {
public interface NAMESPACE extends Property.NAMESPACE {
public static final String URI = "http://purl.org/dc/elements/1.1/";
}
static public class DESCRIPTION extends Property<String> implements NAMESPACE {
public DESCRIPTION() {
}
public DESCRIPTION(String value) {
super(value, null);
}
}
static public class PUBLISHER extends Property<Person> implements NAMESPACE {
public PUBLISHER() {
}
public PUBLISHER(Person value) {
super(value, null);
}
}
static public class CONTRIBUTOR extends Property<Person> implements NAMESPACE {
public CONTRIBUTOR() {
}
public CONTRIBUTOR(Person value) {
super(value, null);
}
}
static public class DATE extends Property<String> implements NAMESPACE {
public DATE() {
}
public DATE(String value) {
super(value, null);
}
}
static public class LANGUAGE extends Property<String> implements NAMESPACE {
public LANGUAGE() {
}
public LANGUAGE(String value) {
super(value, null);
}
}
static public class RELATION extends Property<URI> implements NAMESPACE {
public RELATION() {
}
public RELATION(URI value) {
super(value, null);
}
}
static public class RIGHTS extends Property<String> implements NAMESPACE {
public RIGHTS() {
}
public RIGHTS(String value) {
super(value, null);
}
}
}
static public abstract class UPNP {
public interface NAMESPACE extends Property.NAMESPACE {
public static final String URI = "urn:schemas-upnp-org:metadata-1-0/upnp/";
}
static public class ARTIST extends PropertyPersonWithRole implements NAMESPACE {
public ARTIST() {
}
public ARTIST(PersonWithRole value) {
super(value, null);
}
}
static public class ACTOR extends PropertyPersonWithRole implements NAMESPACE {
public ACTOR() {
}
public ACTOR(PersonWithRole value) {
super(value, null);
}
}
static public class AUTHOR extends PropertyPersonWithRole implements NAMESPACE {
public AUTHOR() {
}
public AUTHOR(PersonWithRole value) {
super(value, null);
}
}
static public class PRODUCER extends Property<Person> implements NAMESPACE {
public PRODUCER() {
}
public PRODUCER(Person value) {
super(value, null);
}
}
static public class DIRECTOR extends Property<Person> implements NAMESPACE {
public DIRECTOR() {
}
public DIRECTOR(Person value) {
super(value, null);
}
}
static public class GENRE extends Property<String> implements NAMESPACE {
public GENRE() {
}
public GENRE(String value) {
super(value, null);
}
}
static public class ALBUM extends Property<String> implements NAMESPACE {
public ALBUM() {
}
public ALBUM(String value) {
super(value, null);
}
}
static public class PLAYLIST extends Property<String> implements NAMESPACE {
public PLAYLIST() {
}
public PLAYLIST(String value) {
super(value, null);
}
}
static public class REGION extends Property<String> implements NAMESPACE {
public REGION() {
}
public REGION(String value) {
super(value, null);
}
}
static public class RATING extends Property<String> implements NAMESPACE {
public RATING() {
}
public RATING(String value) {
super(value, null);
}
}
static public class TOC extends Property<String> implements NAMESPACE {
public TOC() {
}
public TOC(String value) {
super(value, null);
}
}
static public class ALBUM_ART_URI extends Property<URI> implements NAMESPACE {
public ALBUM_ART_URI() {
this(null);
}
public ALBUM_ART_URI(URI value) {
super(value, "albumArtURI");
}
public ALBUM_ART_URI(URI value, List<Property<DIDLAttribute>> attributes) {
super(value, "albumArtURI", attributes);
}
}
static public class ARTIST_DISCO_URI extends Property<URI> implements NAMESPACE {
public ARTIST_DISCO_URI() {
this(null);
}
public ARTIST_DISCO_URI(URI value) {
super(value, "artistDiscographyURI");
}
}
static public class LYRICS_URI extends Property<URI> implements NAMESPACE {
public LYRICS_URI() {
this(null);
}
public LYRICS_URI(URI value) {
super(value, "lyricsURI");
}
}
static public class STORAGE_TOTAL extends Property<Long> implements NAMESPACE {
public STORAGE_TOTAL() {
this(null);
}
public STORAGE_TOTAL(Long value) {
super(value, "storageTotal");
}
}
static public class STORAGE_USED extends Property<Long> implements NAMESPACE {
public STORAGE_USED() {
this(null);
}
public STORAGE_USED(Long value) {
super(value, "storageUsed");
}
}
static public class STORAGE_FREE extends Property<Long> implements NAMESPACE {
public STORAGE_FREE() {
this(null);
}
public STORAGE_FREE(Long value) {
super(value, "storageFree");
}
}
static public class STORAGE_MAX_PARTITION extends Property<Long> implements NAMESPACE {
public STORAGE_MAX_PARTITION() {
this(null);
}
public STORAGE_MAX_PARTITION(Long value) {
super(value, "storageMaxPartition");
}
}
static public class STORAGE_MEDIUM extends Property<StorageMedium> implements NAMESPACE {
public STORAGE_MEDIUM() {
this(null);
}
public STORAGE_MEDIUM(StorageMedium value) {
super(value, "storageMedium");
}
}
static public class LONG_DESCRIPTION extends Property<String> implements NAMESPACE {
public LONG_DESCRIPTION() {
this(null);
}
public LONG_DESCRIPTION(String value) {
super(value, "longDescription");
}
}
static public class ICON extends Property<URI> implements NAMESPACE {
public ICON() {
}
public ICON(URI value) {
super(value, null);
}
}
static public class RADIO_CALL_SIGN extends Property<String> implements NAMESPACE {
public RADIO_CALL_SIGN() {
this(null);
}
public RADIO_CALL_SIGN(String value) {
super(value, "radioCallSign");
}
}
static public class RADIO_STATION_ID extends Property<String> implements NAMESPACE {
public RADIO_STATION_ID() {
this(null);
}
public RADIO_STATION_ID(String value) {
super(value, "radioStationID");
}
}
static public class RADIO_BAND extends Property<String> implements NAMESPACE {
public RADIO_BAND() {
this(null);
}
public RADIO_BAND(String value) {
super(value, "radioBand");
}
}
static public class CHANNEL_NR extends Property<Integer> implements NAMESPACE {
public CHANNEL_NR() {
this(null);
}
public CHANNEL_NR(Integer value) {
super(value, "channelNr");
}
}
static public class CHANNEL_NAME extends Property<String> implements NAMESPACE {
public CHANNEL_NAME() {
this(null);
}
public CHANNEL_NAME(String value) {
super(value, "channelName");
}
}
static public class SCHEDULED_START_TIME extends Property<String> implements NAMESPACE {
public SCHEDULED_START_TIME() {
this(null);
}
public SCHEDULED_START_TIME(String value) {
super(value, "scheduledStartTime");
}
}
static public class SCHEDULED_END_TIME extends Property<String> implements NAMESPACE {
public SCHEDULED_END_TIME() {
this(null);
}
public SCHEDULED_END_TIME(String value) {
super(value, "scheduledEndTime");
}
}
static public class DVD_REGION_CODE extends Property<Integer> implements NAMESPACE {
public DVD_REGION_CODE() {
this(null);
}
public DVD_REGION_CODE(Integer value) {
super(value, "DVDRegionCode");
}
}
static public class ORIGINAL_TRACK_NUMBER extends Property<Integer> implements NAMESPACE {
public ORIGINAL_TRACK_NUMBER() {
this(null);
}
public ORIGINAL_TRACK_NUMBER(Integer value) {
super(value, "originalTrackNumber");
}
}
static public class USER_ANNOTATION extends Property<String> implements NAMESPACE {
public USER_ANNOTATION() {
this(null);
}
public USER_ANNOTATION(String value) {
super(value, "userAnnotation");
}
}
}
static public abstract class DLNA {
public interface NAMESPACE extends Property.NAMESPACE {
public static final String URI = "urn:schemas-dlna-org:metadata-1-0/";
}
static public class PROFILE_ID extends Property<DIDLAttribute> implements NAMESPACE {
public PROFILE_ID() {
this(null);
}
public PROFILE_ID(DIDLAttribute value) {
super(value, "profileID");
}
}
}
}
public static class Class {
protected String value;
protected String friendlyName;
protected boolean includeDerived;
public Class() {
}
public Class(String value) {
this.value = value;
}
public Class(String value, String friendlyName) {
this.value = value;
this.friendlyName = friendlyName;
}
public Class(String value, String friendlyName, boolean includeDerived) {
this.value = value;
this.friendlyName = friendlyName;
this.includeDerived = includeDerived;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getFriendlyName() {
return friendlyName;
}
public void setFriendlyName(String friendlyName) {
this.friendlyName = friendlyName;
}
public boolean isIncludeDerived() {
return includeDerived;
}
public void setIncludeDerived(boolean includeDerived) {
this.includeDerived = includeDerived;
}
public boolean equals(DIDLObject instance) {
return getValue().equals(instance.getClazz().getValue());
}
}
protected String id;
protected String parentID;
protected String title; // DC
protected String creator; // DC
protected boolean restricted = true; // Let's just assume read-only is default
protected WriteStatus writeStatus; // UPNP
protected Class clazz; // UPNP
protected List<Res> resources = new ArrayList();
protected List<Property> properties = new ArrayList();
protected List<DescMeta> descMetadata = new ArrayList();
protected DIDLObject() {
}
protected DIDLObject(DIDLObject other) {
this(other.getId(),
other.getParentID(),
other.getTitle(),
other.getCreator(),
other.isRestricted(),
other.getWriteStatus(),
other.getClazz(),
other.getResources(),
other.getProperties(),
other.getDescMetadata()
);
}
protected DIDLObject(String id, String parentID, String title, String creator, boolean restricted, WriteStatus writeStatus, Class clazz, List<Res> resources, List<Property> properties, List<DescMeta> descMetadata) {
this.id = id;
this.parentID = parentID;
this.title = title;
this.creator = creator;
this.restricted = restricted;
this.writeStatus = writeStatus;
this.clazz = clazz;
this.resources = resources;
this.properties = properties;
this.descMetadata = descMetadata;
}
public String getId() {
return id;
}
public DIDLObject setId(String id) {
this.id = id;
return this;
}
public String getParentID() {
return parentID;
}
public DIDLObject setParentID(String parentID) {
this.parentID = parentID;
return this;
}
public String getTitle() {
return title;
}
public DIDLObject setTitle(String title) {
this.title = title;
return this;
}
public String getCreator() {
return creator;
}
public DIDLObject setCreator(String creator) {
this.creator = creator;
return this;
}
public boolean isRestricted() {
return restricted;
}
public DIDLObject setRestricted(boolean restricted) {
this.restricted = restricted;
return this;
}
public WriteStatus getWriteStatus() {
return writeStatus;
}
public DIDLObject setWriteStatus(WriteStatus writeStatus) {
this.writeStatus = writeStatus;
return this;
}
public Res getFirstResource() {
return getResources().size() > 0 ? getResources().get(0) : null;
}
public List<Res> getResources() {
return resources;
}
public DIDLObject setResources(List<Res> resources) {
this.resources = resources;
return this;
}
public DIDLObject addResource(Res resource) {
getResources().add(resource);
return this;
}
public Class getClazz() {
return clazz;
}
public DIDLObject setClazz(Class clazz) {
this.clazz = clazz;
return this;
}
public List<Property> getProperties() {
return properties;
}
public DIDLObject setProperties(List<Property> properties) {
this.properties = properties;
return this;
}
public DIDLObject addProperty(Property property) {
if (property == null) return this;
getProperties().add(property);
return this;
}
public DIDLObject replaceFirstProperty(Property property) {
if (property == null) return this;
Iterator<Property> it = getProperties().iterator();
while (it.hasNext()) {
Property p = it.next();
if (p.getClass().isAssignableFrom(property.getClass()))
it.remove();
}
addProperty(property);
return this;
}
public DIDLObject replaceProperties(java.lang.Class<? extends Property> propertyClass, Property[] properties) {
if (properties.length == 0) return this;
removeProperties(propertyClass);
return addProperties(properties);
}
public DIDLObject addProperties(Property[] properties) {
if (properties == null) return this;
for (Property property : properties) {
addProperty(property);
}
return this;
}
public DIDLObject removeProperties(java.lang.Class<? extends Property> propertyClass) {
Iterator<Property> it = getProperties().iterator();
while (it.hasNext()) {
Property p = it.next();
if (p.getClass().isAssignableFrom(propertyClass))
it.remove();
}
return this;
}
public boolean hasProperty(java.lang.Class<? extends Property> propertyClass) {
for (Property property : getProperties()) {
if (property.getClass().isAssignableFrom(propertyClass)) return true;
}
return false;
}
public <V> Property<V> getFirstProperty(java.lang.Class<? extends Property<V>> propertyClass) {
for (Property property : getProperties()) {
if (property.getClass().isAssignableFrom(propertyClass)) return property;
}
return null;
}
public <V> Property<V> getLastProperty(java.lang.Class<? extends Property<V>> propertyClass) {
Property found = null;
for (Property property : getProperties()) {
if (property.getClass().isAssignableFrom(propertyClass)) found = property;
}
return found;
}
public <V> Property<V>[] getProperties(java.lang.Class<? extends Property<V>> propertyClass) {
List<Property<V>> list = new ArrayList();
for (Property property : getProperties()) {
if (property.getClass().isAssignableFrom(propertyClass))
list.add(property);
}
return list.toArray(new Property[list.size()]);
}
public <V> Property<V>[] getPropertiesByNamespace(java.lang.Class<? extends Property.NAMESPACE> namespace) {
List<Property<V>> list = new ArrayList();
for (Property property : getProperties()) {
if (namespace.isAssignableFrom(property.getClass()))
list.add(property);
}
return list.toArray(new Property[list.size()]);
}
public <V> V getFirstPropertyValue(java.lang.Class<? extends Property<V>> propertyClass) {
Property<V> prop = getFirstProperty(propertyClass);
return prop == null ? null : prop.getValue();
}
public <V> List<V> getPropertyValues(java.lang.Class<? extends Property<V>> propertyClass) {
List<V> list = new ArrayList();
for (Property property : getProperties(propertyClass)) {
list.add((V) property.getValue());
}
return list;
}
public List<DescMeta> getDescMetadata() {
return descMetadata;
}
public void setDescMetadata(List<DescMeta> descMetadata) {
this.descMetadata = descMetadata;
}
public DIDLObject addDescMetadata(DescMeta descMetadata) {
getDescMetadata().add(descMetadata);
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DIDLObject that = (DIDLObject) o;
if (!id.equals(that.id)) return false;
return true;
}
@Override
public int hashCode() {
return id.hashCode();
}
}