/**
* 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.index.service.impl.index.group;
import org.opencastproject.index.service.impl.index.IndexObject;
import org.opencastproject.security.api.JaxbGroup;
import org.opencastproject.util.IoSupport;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.codehaus.jettison.mapped.Configuration;
import org.codehaus.jettison.mapped.MappedNamespaceConvention;
import org.codehaus.jettison.mapped.MappedXMLStreamReader;
import org.codehaus.jettison.mapped.MappedXMLStreamWriter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.stream.StreamSource;
/**
* Object wrapper for a group.
*/
@XmlType(name = "group", namespace = IndexObject.INDEX_XML_NAMESPACE, propOrder = { "identifier", "name",
"description", "organization", "role", "roles", "members" })
@XmlRootElement(name = "group", namespace = IndexObject.INDEX_XML_NAMESPACE)
@XmlAccessorType(XmlAccessType.NONE)
public class Group implements IndexObject {
/** The name of the surrounding XML tag to wrap a result of multiple groups */
public static final String XML_SURROUNDING_TAG = "groups";
/** The document type */
public static final String DOCUMENT_TYPE = "group";
/** The identifier */
@XmlElement(name = "identifier")
private String identifier = null;
/** The name for the group */
@XmlElement(name = "name")
private String name = null;
/** The name of the group role */
@XmlElement(name = "role")
private String role = null;
/** The description */
@XmlElement(name = "description")
private String description = null;
/** The organization for the group */
@XmlElement(name = "organization")
private String organization = null;
@XmlElementWrapper(name = "roles")
@XmlElement(name = "role")
private Set<String> roles = null;
@XmlElementWrapper(name = "members")
@XmlElement(name = "member")
private Set<String> members = null;
/** Context for serializing and deserializing */
private static JAXBContext context = null;
/**
* Required default no arg constructor for JAXB.
*/
public Group() {
}
public Group(String identifier, String organization) {
this.identifier = identifier;
this.organization = organization;
this.role = JaxbGroup.ROLE_PREFIX + identifier.toUpperCase();
}
/**
* Create a new group with all of the properties populated.
*
* @param identifier
* The identifier for this group
* @param name
* The easy to read name of this group
* @param description
* The description of the group
* @param organization
* The organization applying to this group
* @param roles
* The roles that are given with being in this group
* @param members
* The user names of the current members of the group.
*/
public Group(String identifier, String name, String description, String organization, Set<String> roles,
Set<String> members) {
this.identifier = identifier;
this.name = name;
this.description = description;
this.organization = organization;
this.role = JaxbGroup.ROLE_PREFIX + identifier.toUpperCase();
this.roles = roles;
this.members = members;
}
public String getIdentifier() {
return identifier;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRole() {
return role;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getOrganization() {
return organization;
}
/**
* Add role to this group
*
* @param role
* The role.
*/
public void addRole(String role) {
if (roles == null) {
roles = new HashSet<String>();
}
roles.add(role);
}
/**
* Sets the list of roles.
*
* @param roles
* the roles for this group
*/
public void setRoles(Set<String> roles) {
this.roles = roles;
}
/**
* Returns the group's roles.
*
* @return the roles
*/
public Set<String> getRoles() {
return roles;
}
/**
* Add a member
*
* @param member
* The member's name.
*/
public void addMember(String member) {
if (members == null) {
members = new HashSet<String>();
}
members.add(member);
}
/**
* Sets the list of members.
*
* @param members
* the members for this group
*/
public void setMembers(Set<String> members) {
this.members = members;
}
/**
* Returns the group members.
*
* @return the members
*/
public Set<String> getMembers() {
return members;
}
/**
* Reads the group from the input stream.
*
* @param xml
* the input stream
* @return the deserialized group
* @throws IOException
*/
public static Group valueOf(InputStream xml) throws IOException {
try {
if (context == null) {
createJAXBContext();
}
Unmarshaller unmarshaller = context.createUnmarshaller();
return unmarshaller.unmarshal(new StreamSource(xml), Group.class).getValue();
} catch (JAXBException e) {
throw new IOException(e.getLinkedException() != null ? e.getLinkedException() : e);
} finally {
IoSupport.closeQuietly(xml);
}
}
/**
* Reads the group from the input stream.
*
* @param json
* the input stream
* @return the deserialized group
* @throws JSONException
* @throws XMLStreamException
* @throws JAXBException
*/
public static Group valueOfJson(InputStream json) throws IOException, JSONException, XMLStreamException,
JAXBException {
// TODO Get this to work, it is currently returning null properties for all properties.
if (context == null) {
createJAXBContext();
}
BufferedReader streamReader = new BufferedReader(new InputStreamReader(json, "UTF-8"));
StringBuilder jsonStringBuilder = new StringBuilder();
String inputStr;
while ((inputStr = streamReader.readLine()) != null)
jsonStringBuilder.append(inputStr);
JSONObject obj = new JSONObject(jsonStringBuilder.toString());
Configuration config = new Configuration();
config.setSupressAtAttributes(true);
Map<String, String> xmlToJsonNamespaces = new HashMap<String, String>(1);
xmlToJsonNamespaces.put(INDEX_XML_NAMESPACE, "");
config.setXmlToJsonNamespaces(xmlToJsonNamespaces);
MappedNamespaceConvention con = new MappedNamespaceConvention(config);
XMLStreamReader xmlStreamReader = new MappedXMLStreamReader(obj, con);
Unmarshaller unmarshaller = context.createUnmarshaller();
Group event = (Group) unmarshaller.unmarshal(xmlStreamReader);
return event;
}
/**
* Initialize the JAXBContext.
*/
private static void createJAXBContext() throws JAXBException {
context = JAXBContext.newInstance(Group.class);
}
@Override
public String toJSON() {
try {
if (context == null) {
createJAXBContext();
}
Marshaller marshaller = Group.context.createMarshaller();
Configuration config = new Configuration();
config.setSupressAtAttributes(true);
MappedNamespaceConvention con = new MappedNamespaceConvention(config);
StringWriter writer = new StringWriter();
XMLStreamWriter xmlStreamWriter = new MappedXMLStreamWriter(con, writer) {
@Override
public void writeStartElement(String prefix, String local, String uri) throws XMLStreamException {
super.writeStartElement("", local, "");
}
@Override
public void writeStartElement(String uri, String local) throws XMLStreamException {
super.writeStartElement("", local, "");
}
@Override
public void setPrefix(String pfx, String uri) throws XMLStreamException {
}
@Override
public void setDefaultNamespace(String uri) throws XMLStreamException {
}
};
marshaller.marshal(this, xmlStreamWriter);
return writer.toString();
} catch (JAXBException e) {
throw new IllegalStateException(e.getLinkedException() != null ? e.getLinkedException() : e);
}
}
/**
* Serializes the group to an XML format.
*
* @return A String with this group' content as XML.
*/
public String toXML() {
try {
if (context == null) {
createJAXBContext();
}
StringWriter writer = new StringWriter();
Marshaller marshaller = Group.context.createMarshaller();
marshaller.marshal(this, writer);
return writer.toString();
} catch (JAXBException e) {
throw new IllegalStateException(e.getLinkedException() != null ? e.getLinkedException() : e);
}
}
}