/*
************************************************************************
******************* CANADIAN ASTRONOMY DATA CENTRE *******************
************** CENTRE CANADIEN DE DONNÉES ASTRONOMIQUES **************
*
* (c) 2011. (c) 2011.
* Government of Canada Gouvernement du Canada
* National Research Council Conseil national de recherches
* Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6
* All rights reserved Tous droits réservés
*
* NRC disclaims any warranties, Le CNRC dénie toute garantie
* expressed, implied, or énoncée, implicite ou légale,
* statutory, of any kind with de quelque nature que ce
* respect to the software, soit, concernant le logiciel,
* including without limitation y compris sans restriction
* any warranty of merchantability toute garantie de valeur
* or fitness for a particular marchande ou de pertinence
* purpose. NRC shall not be pour un usage particulier.
* liable in any event for any Le CNRC ne pourra en aucun cas
* damages, whether direct or être tenu responsable de tout
* indirect, special or general, dommage, direct ou indirect,
* consequential or incidental, particulier ou général,
* arising from the use of the accessoire ou fortuit, résultant
* software. Neither the name de l'utilisation du logiciel. Ni
* of the National Research le nom du Conseil National de
* Council of Canada nor the Recherches du Canada ni les noms
* names of its contributors may de ses participants ne peuvent
* be used to endorse or promote être utilisés pour approuver ou
* products derived from this promouvoir les produits dérivés
* software without specific prior de ce logiciel sans autorisation
* written permission. préalable et particulière
* par écrit.
*
* This file is part of the Ce fichier fait partie du projet
* OpenCADC project. OpenCADC.
*
* OpenCADC is free software: OpenCADC est un logiciel libre ;
* you can redistribute it and/or vous pouvez le redistribuer ou le
* modify it under the terms of modifier suivant les termes de
* the GNU Affero General Public la “GNU Affero General Public
* License as published by the License” telle que publiée
* Free Software Foundation, par la Free Software Foundation
* either version 3 of the : soit la version 3 de cette
* License, or (at your option) licence, soit (à votre gré)
* any later version. toute version ultérieure.
*
* OpenCADC is distributed in the OpenCADC est distribué
* hope that it will be useful, dans l’espoir qu’il vous
* but WITHOUT ANY WARRANTY; sera utile, mais SANS AUCUNE
* without even the implied GARANTIE : sans même la garantie
* warranty of MERCHANTABILITY implicite de COMMERCIALISABILITÉ
* or FITNESS FOR A PARTICULAR ni d’ADÉQUATION À UN OBJECTIF
* PURPOSE. See the GNU Affero PARTICULIER. Consultez la Licence
* General Public License for Générale Publique GNU Affero
* more details. pour plus de détails.
*
* You should have received Vous devriez avoir reçu une
* a copy of the GNU Affero copie de la Licence Générale
* General Public License along Publique GNU Affero avec
* with OpenCADC. If not, see OpenCADC ; si ce n’est
* . pas le cas, consultez :
* .
*
* $Revision: 5 $
*
************************************************************************
*/
package ca.nrc.cadc.ac.xml;
import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.Field;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.Principal;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import javax.security.auth.x500.X500Principal;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import ca.nrc.cadc.ac.Group;
import ca.nrc.cadc.ac.GroupProperty;
import ca.nrc.cadc.ac.InternalID;
import ca.nrc.cadc.ac.PersonalDetails;
import ca.nrc.cadc.ac.PosixDetails;
import ca.nrc.cadc.ac.ReaderException;
import ca.nrc.cadc.ac.User;
import ca.nrc.cadc.ac.UserRequest;
import ca.nrc.cadc.ac.WriterException;
import ca.nrc.cadc.auth.DNPrincipal;
import ca.nrc.cadc.auth.HttpPrincipal;
import ca.nrc.cadc.auth.IdentityType;
import ca.nrc.cadc.auth.NumericPrincipal;
import ca.nrc.cadc.auth.OpenIdPrincipal;
import ca.nrc.cadc.date.DateUtil;
import ca.nrc.cadc.reg.Standards;
import ca.nrc.cadc.reg.client.LocalAuthority;
/**
* AbstractReaderWriter TODO describe class
*/
public abstract class AbstractReaderWriter
{
public static final String ADDRESS = "address";
public static final String AUTHORITY = "authority";
public static final String CITY = "city";
public static final String COUNTRY = "country";
public static final String EMAIL = "email";
public static final String DESCRIPTION = "description";
public static final String FIRST_NAME = "firstName";
public static final String GID = "gid";
public static final String GROUP = "group";
public static final String GROUPS = "groups";
public static final String GROUP_ADMINS = "groupAdmins";
public static final String GROUP_MEMBERS = "groupMembers";
public static final String HOME_DIRECTORY = "homeDirectory";
public static final String ID = "id";
public static final String IDENTITY = "identity";
public static final String IDENTITIES = "identities";
public static final String INSTITUTE = "institute";
public static final String INTEGER = "Integer";
public static final String INTERNAL_ID = "internalID";
public static final String KEY = "key";
public static final String LAST_MODIFIED = "lastModified";
public static final String LAST_NAME = "lastName";
public static final String OWNER = "owner";
public static final String PASSWORD = "password";
public static final String PERSONAL_DETAILS = "personalDetails";
public static final String POSIX_DETAILS = "posixDetails";
public static final String PROPERTIES = "properties";
public static final String PROPERTY = "property";
public static final String READ_ONLY = "readOnly";
public static final String STRING = "String";
public static final String TYPE = "type";
public static final String UID = "uid";
public static final String URI = "uri";
public static final String USER = "user";
public static final String USERNAME = "username";
public static final String USERS = "users";
public static final String USER_ADMINS = "userAdmins";
public static final String USER_MEMBERS = "userMembers";
public static final String USER_REQUEST = "userRequest";
private String gmsServiceURI;
public AbstractReaderWriter()
{
LocalAuthority localAuthority = new LocalAuthority();
URI serviceURI = localAuthority.getServiceURI(Standards.GMS_GROUPS_01.toString());
gmsServiceURI = serviceURI.toString();
}
/**
* Write to root Element to a writer.
*
* @param root Root Element to write.
* @param writer Writer to write to.
* @throws IOException if the writer fails to write.
*/
protected void write(Element root, Writer writer)
throws IOException
{
XMLOutputter outputter = new XMLOutputter();
outputter.setFormat(Format.getPrettyFormat());
outputter.output(new Document(root), writer);
}
/**
* Get a User object from a JDOM element.
*
* @param element The User JDOM element.
* @return A User object.
* @throws ReaderException
*/
protected final User getUser(Element element)
throws ReaderException
{
User user = new User();
// id
Element internalIDElement = element.getChild(INTERNAL_ID);
if (internalIDElement != null)
{
setInternalID(user, internalIDElement);
}
// identities
Element identitiesElement = element.getChild(IDENTITIES);
if (identitiesElement != null)
{
List identityElements = identitiesElement.getChildren(IDENTITY);
for (Element identityElement : identityElements)
{
user.getIdentities().add(getPrincipal(identityElement));
}
}
// personalDetails
Element personalDetailsElement = element.getChild(PERSONAL_DETAILS);
if (personalDetailsElement != null)
{
user.personalDetails = getPersonalDetails(personalDetailsElement);
}
// posixDetails
Element posixDetailsElement = element.getChild(POSIX_DETAILS);
if (posixDetailsElement != null)
{
user.posixDetails = getPosixDetails(posixDetailsElement);
}
return user;
}
/**
* Get a UserRequest object from a JDOM element.
*
* @param element The UserRequest JDOM element.
* @return A UserRequest object.
* @throws ReaderException
*/
protected final UserRequest getUserRequest(Element element)
throws ReaderException
{
// user element of the UserRequest element
Element userElement = element.getChild(USER);
if (userElement == null)
{
String error = "user element not found in userRequest element";
throw new ReaderException(error);
}
User user = getUser(userElement);
// password element of the userRequest element
Element passwordElement = element.getChild(PASSWORD);
if (passwordElement == null)
{
String error = "password element not found in userRequest element";
throw new ReaderException(error);
}
String password = passwordElement.getText();
return new UserRequest(user, password.toCharArray());
}
/**
* Get a Principal object from a JDOM element.
*
* @param element The Principal JDOM element.
* @return A Principal object.
* @throws ReaderException
*/
protected final Principal getPrincipal(Element element)
throws ReaderException
{
if (element == null)
{
String error = "null identity element";
throw new ReaderException(error);
}
if (!element.getName().equals(IDENTITY))
{
String error = "expected identity element name, found " +
element.getName();
throw new ReaderException(error);
}
String type = element.getAttributeValue(TYPE);
if (type == null)
{
String error = "type attribute not found in identity element" +
element.getName();
throw new ReaderException(error);
}
String identity = element.getText();
Principal principal;
if (type.equals(IdentityType.OPENID.getValue()))
{
principal = new OpenIdPrincipal(identity);
}
else if (type.equals(IdentityType.CADC.getValue()))
{
principal = new NumericPrincipal(UUID.fromString(identity));
}
else if (type.equals(IdentityType.USERNAME.getValue()))
{
principal = new HttpPrincipal(identity);
}
else if (type.equals(IdentityType.X500.getValue()))
{
principal = new X500Principal(identity);
}
else if (type.equals(IdentityType.ENTRY_DN.getValue()))
{
principal = new DNPrincipal(identity);
}
else
{
String error = "Unknown type attribute: " + type;
throw new ReaderException(error);
}
return principal;
}
/**
* Get a PosixDetails object from a JDOM element.
*
* @param element The PosixDetails JDOM element.
* @return A PosixDetails object.
* @throws ReaderException
*/
protected final PosixDetails getPosixDetails(Element element)
throws ReaderException
{
if (element == null)
{
String error = "null posixDetails element";
throw new ReaderException(error);
}
// userName
Element userNameElement = element.getChild(USERNAME);
if (userNameElement == null)
{
String error = "posixDetails missing required element username";
throw new ReaderException(error);
}
String username = userNameElement.getText();
// uid
Element uidElement = element.getChild(UID);
if (uidElement == null)
{
String error = "posixDetails missing required element uid";
throw new ReaderException(error);
}
long uid;
try
{
uid = Long.valueOf(uidElement.getText());
}
catch (NumberFormatException e)
{
String error = "Cannot parse posixDetails uid to a long";
throw new ReaderException(error);
}
// gid
Element gidElement = element.getChild(GID);
if (gidElement == null)
{
String error = "posixDetails missing required element gid";
throw new ReaderException(error);
}
long gid;
try
{
gid = Long.valueOf(gidElement.getText());
}
catch (NumberFormatException e)
{
String error = "Cannot parse posixDetails gid to a long";
throw new ReaderException(error);
}
// homeDirectory
Element homeDirElement = element.getChild(HOME_DIRECTORY);
if (homeDirElement == null)
{
String error = "posixDetails missing required element homeDirectory";
throw new ReaderException(error);
}
String homeDirectory = homeDirElement.getText();
return new PosixDetails(username, uid, gid, homeDirectory);
}
/**
* Get a PersonalDetails object from a JDOM element.
*
* @param element The PersonalDetails JDOM element.
* @return A PersonalDetails object.
* @throws ReaderException
*/
protected final PersonalDetails getPersonalDetails(Element element)
throws ReaderException
{
if (element == null)
{
String error = "null personalDetails element";
throw new ReaderException(error);
}
// firstName
Element firstNameElement = element.getChild(FIRST_NAME);
if (firstNameElement == null)
{
String error = "personalDetails missing required element firstName";
throw new ReaderException(error);
}
String firstName = firstNameElement.getText();
// lastName
Element lastNameElement = element.getChild(LAST_NAME);
if (lastNameElement == null)
{
String error = "personalDetails missing required element lastName";
throw new ReaderException(error);
}
String lastName = lastNameElement.getText();
PersonalDetails details = new PersonalDetails(firstName, lastName);
// email
Element emailElement = element.getChild(EMAIL);
if (emailElement != null)
{
details.email = emailElement.getText();
}
// address
Element addressElement = element.getChild(ADDRESS);
if (addressElement != null)
{
details.address = addressElement.getText();
}
// institute
Element instituteElement = element.getChild(INSTITUTE);
if (instituteElement != null)
{
details.institute = instituteElement.getText();
}
// city
Element cityElement = element.getChild(CITY);
if (cityElement != null)
{
details.city = cityElement.getText();
}
// country
Element countryElement = element.getChild(COUNTRY);
if (countryElement != null)
{
details.country = countryElement.getText();
}
return details;
}
/**
* Get a UserRequest object from a JDOM element.
*
* @param element The UserRequest JDOM element.
* @return A UserRequest object.
* @throws ReaderException
*/
protected final Group getGroup(Element element)
throws ReaderException
{
String uri = element.getAttributeValue(URI);
if (uri == null)
{
String error = "group missing required uri attribute";
throw new ReaderException(error);
}
// Group groupID
int index = uri.indexOf(gmsServiceURI);
if (index == -1)
{
String error = "group uri attribute malformed: " + uri;
throw new ReaderException(error);
}
String groupID = uri.substring(gmsServiceURI.length() + 1);
// Group owner
User user = null;
Element ownerElement = element.getChild(OWNER);
if (ownerElement != null)
{
// Owner user
Element userElement = ownerElement.getChild(USER);
if (userElement == null)
{
String error = "owner missing required user element";
throw new ReaderException(error);
}
user = getUser(userElement);
}
Group group = new Group(groupID);
// set owner field
setField(group, user, OWNER);
// description
Element descriptionElement = element.getChild(DESCRIPTION);
if (descriptionElement != null)
{
group.description = descriptionElement.getText();
}
// lastModified
Element lastModifiedElement = element.getChild(LAST_MODIFIED);
if (lastModifiedElement != null)
{
try
{
DateFormat df = DateUtil.getDateFormat(DateUtil.IVOA_DATE_FORMAT, DateUtil.UTC);
group.lastModified = df.parse(lastModifiedElement.getText());
}
catch (ParseException e)
{
String error = "Unable to parse group lastModified because " + e.getMessage();
throw new ReaderException(error);
}
}
// properties
Element propertiesElement = element.getChild(PROPERTIES);
if (propertiesElement != null)
{
List propertyElements = propertiesElement.getChildren(PROPERTY);
for (Element propertyElement : propertyElements)
{
group.getProperties().add(getGroupProperty(propertyElement));
}
}
// groupMembers
Element groupMembersElement = element.getChild(GROUP_MEMBERS);
if (groupMembersElement != null)
{
List groupElements = groupMembersElement.getChildren(GROUP);
for (Element groupMember : groupElements)
{
group.getGroupMembers().add(getGroup(groupMember));
}
}
// userMembers
Element userMembersElement = element.getChild(USER_MEMBERS);
if (userMembersElement != null)
{
List userElements = userMembersElement.getChildren(USER);
for (Element userMember : userElements)
{
group.getUserMembers().add(getUser(userMember));
}
}
// groupAdmins
Element groupAdminsElement = element.getChild(GROUP_ADMINS);
if (groupAdminsElement != null)
{
List groupElements = groupAdminsElement.getChildren(GROUP);
for (Element groupMember : groupElements)
{
group.getGroupAdmins().add(getGroup(groupMember));
}
}
// userAdmins
Element userAdminsElement = element.getChild(USER_ADMINS);
if (userAdminsElement != null)
{
List userElements = userAdminsElement.getChildren(USER);
for (Element userMember : userElements)
{
group.getUserAdmins().add(getUser(userMember));
}
}
return group;
}
/**
* Get a GroupProperty object from a JDOM element.
*
* @param element The GroupProperty JDOM element.
* @return A GroupProperty object.
* @throws ReaderException
*/
protected final GroupProperty getGroupProperty(Element element)
throws ReaderException
{
if (element == null)
{
String error = "null property element";
throw new ReaderException(error);
}
if (!element.getName().equals(PROPERTY))
{
String error = "expected property element name, found " +
element.getName();
throw new ReaderException(error);
}
String key = element.getAttributeValue(KEY);
if (key == null)
{
String error = "required key attribute not found";
throw new ReaderException(error);
}
String type = element.getAttributeValue(TYPE);
if (type == null)
{
String error = "required type attribute not found";
throw new ReaderException(error);
}
Object value;
if (type.equals(STRING))
{
value = String.valueOf(element.getText());
}
else
{
if (type.equals(INTEGER))
{
value = Integer.valueOf(element.getText());
}
else
{
String error = "Unsupported GroupProperty type: " + type;
throw new ReaderException(error);
}
}
Boolean readOnly = Boolean.valueOf(element.getAttributeValue(READ_ONLY));
return new GroupProperty(key, value, readOnly);
}
/**
* Get a JDOM element from a User object.
*
* @param user The User.
* @return A JDOM User representation.
* @throws WriterException
*/
protected final Element getElement(User user)
throws WriterException
{
if (user == null)
{
throw new WriterException("null User");
}
// Create the user Element.
Element userElement = new Element(USER);
// internalID element
if (user.getID() != null)
{
userElement.addContent(getElement(user.getID()));
}
// identities
Set identities = user.getIdentities();
if (!identities.isEmpty()) // includes alternate identities
{
Element identitiesElement = new Element(IDENTITIES);
for (Principal identity : identities)
{
identitiesElement.addContent(getElement(identity));
}
userElement.addContent(identitiesElement);
}
// personalDetails
if (user.personalDetails != null)
{
userElement.addContent(getElement(user.personalDetails));
}
// posixDetails
if (user.posixDetails != null)
{
userElement.addContent(getElement(user.posixDetails));
}
return userElement;
}
/**
* Get a JDOM element from a UserRequest object.
*
* @param userRequest The UserRequest.
* @return A JDOM UserRequest representation.
* @throws WriterException
*/
protected final Element getElement(UserRequest userRequest)
throws WriterException
{
if (userRequest == null)
{
throw new WriterException("null UserRequest");
}
// Create the userRequest Element.
Element userRequestElement = new Element(USER_REQUEST);
// user element
Element userElement = getElement(userRequest.getUser());
userRequestElement.addContent(userElement);
// password element
Element passwordElement = new Element(PASSWORD);
passwordElement.setText(String.valueOf(userRequest.getPassword()));
userRequestElement.addContent(passwordElement);
return userRequestElement;
}
/**
* Get a JDOM element from a InternalID object.
*
* @param internalID The InternalID.
* @return A JDOM InternalID representation.
* @throws WriterException
*/
protected final Element getElement(InternalID internalID)
throws WriterException
{
if (internalID == null)
{
throw new WriterException("null InternalID");
}
// Create the internalID Element.
Element internalIDElement = new Element(INTERNAL_ID);
// uri element
Element uriElement = new Element(URI);
uriElement.addContent(internalID.getURI().toString());
internalIDElement.addContent(uriElement);
return internalIDElement;
}
/**
* Get a JDOM element from a Principal object.
*
* @param identity The Principal.
* @return A JDOM UserDetails representation.
* @throws WriterException
*/
protected final Element getElement(Principal identity)
throws WriterException
{
if (identity == null)
{
String error = "null Principal";
throw new WriterException(error);
}
Element identityElement = new Element(IDENTITY);
if ((identity instanceof HttpPrincipal))
{
identityElement.setAttribute(TYPE, IdentityType.USERNAME.getValue());
}
else if ((identity instanceof NumericPrincipal))
{
identityElement.setAttribute(TYPE, IdentityType.CADC.getValue());
}
else if ((identity instanceof OpenIdPrincipal))
{
identityElement.setAttribute(TYPE, IdentityType.OPENID.getValue());
}
else if ((identity instanceof X500Principal))
{
identityElement.setAttribute(TYPE, IdentityType.X500.getValue());
}
else if ((identity instanceof DNPrincipal))
{
identityElement.setAttribute(TYPE, IdentityType.ENTRY_DN.getValue());
}
else
{
String error = "Unsupported Principal type " +
identity.getClass().getSimpleName();
throw new IllegalArgumentException(error);
}
identityElement.setText(identity.getName());
return identityElement;
}
/**
* Get a JDOM element from a PosixDetails object.
*
* @param details The PosixDetails.
* @return A JDOM PosixDetails representation.
*/
protected final Element getElement(PosixDetails details)
throws WriterException
{
if (details == null)
{
String error = "null PosixDetails";
throw new WriterException(error);
}
Element detailsElement = new Element(POSIX_DETAILS);
Element usernameElement = new Element(USERNAME);
usernameElement.setText(details.getUsername());
detailsElement.addContent(usernameElement);
Element uidElement = new Element(UID);
uidElement.setText(String.valueOf(details.getUid()));
detailsElement.addContent(uidElement);
Element gidElement = new Element(GID);
gidElement.setText(String.valueOf(details.getGid()));
detailsElement.addContent(gidElement);
Element homeDirElement = new Element(HOME_DIRECTORY);
homeDirElement.setText(details.getHomeDirectory());
detailsElement.addContent(homeDirElement);
return detailsElement;
}
/**
* Get a JDOM element from a PersonalDetails object.
*
* @param details The PersonalDetails.
* @return JDOM PersonalDetails representation.
*/
protected final Element getElement(PersonalDetails details)
throws WriterException
{
if (details == null)
{
String error = "null PersonalDetails";
throw new WriterException(error);
}
Element detailsElement = new Element(PERSONAL_DETAILS);
Element firstNameElement = new Element(FIRST_NAME);
firstNameElement.setText(details.getFirstName());
detailsElement.addContent(firstNameElement);
Element lastNameElement = new Element(LAST_NAME);
lastNameElement.setText(details.getLastName());
detailsElement.addContent(lastNameElement);
if (details.email != null)
{
Element emailElement = new Element(EMAIL);
emailElement.setText(details.email);
detailsElement.addContent(emailElement);
}
if (details.address != null)
{
Element addressElement = new Element(ADDRESS);
addressElement.setText(details.address);
detailsElement.addContent(addressElement);
}
if (details.institute != null)
{
Element instituteElement = new Element(INSTITUTE);
instituteElement.setText(details.institute);
detailsElement.addContent(instituteElement);
}
if (details.city != null)
{
Element cityElement = new Element(CITY);
cityElement.setText(details.city);
detailsElement.addContent(cityElement);
}
if (details.country != null)
{
Element countryElement = new Element(COUNTRY);
countryElement.setText(details.country);
detailsElement.addContent(countryElement);
}
return detailsElement;
}
/**
* Get a JDOM element from a Group object.
*
* @param group The UserRequest.
* @return A JDOM Group representation.
* @throws WriterException
*/
protected final Element getElement(Group group)
throws WriterException
{
return getElement(group, true);
}
/**
* Get a JDOM element from a Group object.
*
* @param group The UserRequest.
* @param deepCopy Return all Group elements.
* @return A JDOM Group representation.
* @throws WriterException
*/
protected final Element getElement(Group group, boolean deepCopy)
throws WriterException
{
if (group == null)
{
throw new WriterException("null Group");
}
// Create the root group element.
Element groupElement = new Element(GROUP);
String groupURI = gmsServiceURI + "#" + group.getID();
groupElement.setAttribute(new Attribute(URI, groupURI));
// Group owner
if (group.getOwner() != null)
{
Element ownerElement = new Element(OWNER);
Element userElement = getElement(group.getOwner());
ownerElement.addContent(userElement);
groupElement.addContent(ownerElement);
}
if (deepCopy)
{
// Group description
if (group.description != null)
{
Element descriptionElement = new Element(DESCRIPTION);
descriptionElement.setText(group.description);
groupElement.addContent(descriptionElement);
}
// lastModified
if (group.lastModified != null)
{
Element lastModifiedElement = new Element(LAST_MODIFIED);
DateFormat df = DateUtil.getDateFormat(DateUtil.IVOA_DATE_FORMAT, DateUtil.UTC);
lastModifiedElement.setText(df.format(group.lastModified));
groupElement.addContent(lastModifiedElement);
}
// Group properties
if (!group.getProperties().isEmpty())
{
Element propertiesElement = new Element(PROPERTIES);
for (GroupProperty property : group.getProperties())
{
propertiesElement.addContent(getElement(property));
}
groupElement.addContent(propertiesElement);
}
// Group groupMembers.
if ((group.getGroupMembers() != null) && (!group.getGroupMembers().isEmpty()))
{
Element groupMembersElement = new Element(GROUP_MEMBERS);
for (Group groupMember : group.getGroupMembers())
{
groupMembersElement.addContent(getElement(groupMember, false));
}
groupElement.addContent(groupMembersElement);
}
// Group userMembers
if ((group.getUserMembers() != null) && (!group.getUserMembers().isEmpty()))
{
Element userMembersElement = new Element(USER_MEMBERS);
for (User userMember : group.getUserMembers())
{
userMembersElement.addContent(getElement(userMember));
}
groupElement.addContent(userMembersElement);
}
// Group groupAdmins.
if ((group.getGroupAdmins() != null) && (!group.getGroupAdmins().isEmpty()))
{
Element groupAdminsElement = new Element(GROUP_ADMINS);
for (Group groupMember : group.getGroupAdmins())
{
groupAdminsElement.addContent(getElement(groupMember, false));
}
groupElement.addContent(groupAdminsElement);
}
// Group userAdmins
if ((group.getUserAdmins() != null) && (!group.getUserAdmins().isEmpty()))
{
Element userAdminsElement = new Element(USER_ADMINS);
for (User userMember : group.getUserAdmins())
{
userAdminsElement.addContent(getElement(userMember));
}
groupElement.addContent(userAdminsElement);
}
}
return groupElement;
}
/**
* Get a JDOM element from a GroupProperty object.
*
* @param property The GroupProperty.
* @return A JDOM GroupProperty representation.
* @throws WriterException
*/
protected final Element getElement(GroupProperty property)
throws WriterException
{
if (property == null)
{
throw new WriterException("null GroupProperty");
}
Element propertyElement = new Element(PROPERTY);
propertyElement.setAttribute(KEY, property.getKey());
if (property.isReadOnly())
{
propertyElement.setAttribute(READ_ONLY, Boolean.TRUE.toString());
}
Object value = property.getValue();
if ((value instanceof String))
{
propertyElement.setAttribute(TYPE, STRING);
}
else if ((value instanceof Integer))
{
propertyElement.setAttribute(TYPE, INTEGER);
}
else
{
String error = "Unsupported value type: " +
value.getClass().getSimpleName();
throw new IllegalArgumentException(error);
}
propertyElement.setText(String.valueOf(property.getValue()));
return propertyElement;
}
private void setInternalID(User user, Element element)
throws ReaderException
{
Element uriElement = element.getChild(URI);
if (uriElement == null)
{
String error = "expected uri element not found in internalID element";
throw new ReaderException(error);
}
String text = uriElement.getText();
URI uri;
try
{
uri = new URI(text);
}
catch (URISyntaxException e)
{
throw new ReaderException("Invalid InternalID URI " + text, e);
}
InternalID internalID = new InternalID(uri);
setField(user, internalID, ID);
}
// set private field using reflection
private void setField(Object object, Object value, String name)
{
try
{
Field field = object.getClass().getDeclaredField(name);
field.setAccessible(true);
field.set(object, value);
}
catch (NoSuchFieldException e)
{
final String error = object.getClass().getSimpleName() +
" field " + name + "not found";
throw new RuntimeException(error, e);
}
catch (IllegalAccessException e)
{
final String error = "unable to update " + name + " in " +
object.getClass().getSimpleName();
throw new RuntimeException(error, e);
}
}
}