JaxbPlaylist.java
/*
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License
* at:
*
* http://opensource.org/licenses/ecl2.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
*/
package org.opencastproject.playlists.serialization;
import org.opencastproject.playlists.Playlist;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
/** 1:1 serialization of a {@link Playlist}. Intended for endpoints. */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "playlist", namespace = "http://playlist.opencastproject.org")
@XmlRootElement(name = "playlist", namespace = "http://playlist.opencastproject.org")
public class JaxbPlaylist {
static class DateAdapter extends XmlAdapter<Long, Date> {
/**
* {@inheritDoc}
*
* @see javax.xml.bind.annotation.adapters.XmlAdapter#marshal(java.lang.Object)
*/
@Override
public Long marshal(Date v) throws Exception {
return v == null ? null : v.getTime();
}
/**
* {@inheritDoc}
*
* @see javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal(java.lang.Object)
*/
@Override
public Date unmarshal(Long v) throws Exception {
return v == null ? null : new Date(v);
}
}
@XmlAttribute()
private String id;
@XmlElement(name = "organization")
private String organization;
private List<JaxbPlaylistEntry> entries;
@XmlElement(name = "title")
private String title;
@XmlElement(name = "description")
private String description;
@XmlElement(name = "creator")
private String creator;
@XmlJavaTypeAdapter(JaxbPlaylist.DateAdapter.class)
@XmlElement
private Date updated;
private List<JaxbPlaylistAccessControlEntry> accessControlEntries;
void beforeMarshal(Marshaller u) {
// Explicitly set empty lists to `null`. This is to avoid having an empty list wrongly show up in a JSON
// serialization with the value of an empty string
if (entries != null && entries.isEmpty()) {
entries = null;
}
if (accessControlEntries != null && accessControlEntries.isEmpty()) {
accessControlEntries = null;
}
}
/**
* Default no-arg constructor needed by JAXB
*/
public JaxbPlaylist() {
}
public JaxbPlaylist(Playlist playlist) {
this();
this.id = playlist.getId();
this.organization = playlist.getOrganization();
this.entries = playlist.getEntries()
.stream()
.map(JaxbPlaylistEntry::new)
.collect(Collectors.toList());
this.title = playlist.getTitle();
this.description = playlist.getDescription();
this.creator = playlist.getCreator();
this.updated = playlist.getUpdated();
this.accessControlEntries = playlist.getAccessControlEntries()
.stream()
.map(JaxbPlaylistAccessControlEntry::new)
.collect(Collectors.toList());
}
public Playlist toPlaylist() {
return new Playlist(
id,
organization,
Optional.ofNullable(entries)
.orElseGet(Collections::emptyList)
.stream()
.map(JaxbPlaylistEntry::toPlaylistEntry)
.collect(Collectors.toList()),
title,
description,
creator,
updated,
Optional.ofNullable(accessControlEntries)
.orElseGet(Collections::emptyList)
.stream()
.map(JaxbPlaylistAccessControlEntry::toPlaylistAccessControlEntry)
.collect(Collectors.toList())
);
}
public List<JaxbPlaylistEntry> getEntries() {
return entries;
}
public void setEntries(List<JaxbPlaylistEntry> entries) {
for (var entry : entries) {
if (!this.entries.contains(entry)) {
entry.setId(0L);
}
}
this.entries = entries;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
JaxbPlaylist jaxbPlaylist = (JaxbPlaylist) o;
return new EqualsBuilder()
.append(id, jaxbPlaylist.id)
.append(organization, jaxbPlaylist.organization)
.append(entries, jaxbPlaylist.entries)
.append(title, jaxbPlaylist.title)
.append(description, jaxbPlaylist.description)
.append(creator, jaxbPlaylist.creator)
.append(updated, jaxbPlaylist.updated)
.append(accessControlEntries, jaxbPlaylist.accessControlEntries)
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(id)
.append(organization)
.append(entries)
.append(title)
.append(description)
.append(creator)
.append(updated)
.append(accessControlEntries)
.toHashCode();
}
}