From 1ef4184dbeaa6197a8a5f4e943b9c34d315a13fe Mon Sep 17 00:00:00 2001 From: Jeff Burke <Jeff.Burke@nrc-cnrc.gc.ca> Date: Tue, 25 Aug 2015 09:52:27 -0700 Subject: [PATCH] ac2 rework to repackage the XML and JSON reader and writers --- projects/cadcAccessControl-Server/build.xml | 2 +- .../nrc/cadc/ac/server/UserPersistence.java | 14 +- .../nrc/cadc/ac/server/ldap/LdapUserDAO.java | 23 +- .../ac/server/ldap/LdapUserPersistence.java | 7 +- .../web/groups/AbstractGroupAction.java | 26 +- .../server/web/groups/CreateGroupAction.java | 3 +- .../server/web/users/AbstractUserAction.java | 4 +- .../web/users/GetUserListActionTest.java | 32 +- .../src/ca/nrc/cadc/ac/client/GMSClient.java | 1 + .../ca/nrc/cadc/ac/json/JsonGroupReader.java | 55 +- .../ca/nrc/cadc/ac/json/JsonGroupWriter.java | 47 +- .../nrc/cadc/ac/json/JsonUserListReader.java | 127 ++ .../nrc/cadc/ac/json/JsonUserListWriter.java | 76 +- .../ca/nrc/cadc/ac/json/JsonUserReader.java | 50 +- .../cadc/ac/json/JsonUserRequestReader.java | 70 +- .../cadc/ac/json/JsonUserRequestWriter.java | 89 +- .../ca/nrc/cadc/ac/json/JsonUserWriter.java | 57 +- .../src/ca/nrc/cadc/ac/xml/AbstractXML.java | 1018 +++++++++++++++++ .../ca/nrc/cadc/ac/xml/GroupListReader.java | 36 +- .../ca/nrc/cadc/ac/xml/GroupListWriter.java | 117 +- .../src/ca/nrc/cadc/ac/xml/GroupReader.java | 132 +-- .../src/ca/nrc/cadc/ac/xml/GroupWriter.java | 137 +-- .../ca/nrc/cadc/ac/xml/UserListReader.java | 204 ++++ .../ca/nrc/cadc/ac/xml/UserListWriter.java | 105 +- .../src/ca/nrc/cadc/ac/xml/UserReader.java | 62 +- .../ca/nrc/cadc/ac/xml/UserRequestReader.java | 37 +- .../ca/nrc/cadc/ac/xml/UserRequestWriter.java | 51 +- .../src/ca/nrc/cadc/ac/xml/UserWriter.java | 78 +- .../ac/json/JsonUserListReaderWriterTest.java | 95 ++ .../ac/json/JsonUserReaderWriterTest.java | 8 +- ...st.java => GroupListReaderWriterTest.java} | 4 +- .../ac/xml/GroupPropertyReaderWriterTest.java | 27 +- .../cadc/ac/xml/IdentityReaderWriterTest.java | 35 +- .../ac/xml/UserDetailsReaderWriterTest.java | 21 +- .../cadc/ac/xml/UserListReaderWriterTest.java | 92 ++ .../nrc/cadc/ac/xml/UserReaderWriterTest.java | 8 +- 36 files changed, 1995 insertions(+), 955 deletions(-) create mode 100644 projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserListReader.java create mode 100644 projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractXML.java create mode 100644 projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListReader.java create mode 100644 projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/JsonUserListReaderWriterTest.java rename projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/{GroupsReaderWriterTest.java => GroupListReaderWriterTest.java} (98%) create mode 100644 projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserListReaderWriterTest.java diff --git a/projects/cadcAccessControl-Server/build.xml b/projects/cadcAccessControl-Server/build.xml index 8a87c3bc..b5ad9f91 100644 --- a/projects/cadcAccessControl-Server/build.xml +++ b/projects/cadcAccessControl-Server/build.xml @@ -148,7 +148,7 @@ <pathelement path="${jars}:${testingJars}"/> </classpath> <sysproperty key="ca.nrc.cadc.util.PropertiesReader.dir" value="test"/> - <test name="ca.nrc.cadc.ac.server.web.users.GetUserActionTest" /> + <test name="ca.nrc.cadc.ac.server.web.users.UserActionFactoryTest" /> <formatter type="plain" usefile="false" /> </junit> </target> diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/UserPersistence.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/UserPersistence.java index f88faffe..07008080 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/UserPersistence.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/UserPersistence.java @@ -68,13 +68,15 @@ */ package ca.nrc.cadc.ac.server; -import java.security.AccessControlException; -import java.security.Principal; -import java.util.Map; - -import ca.nrc.cadc.ac.*; +import ca.nrc.cadc.ac.User; +import ca.nrc.cadc.ac.UserAlreadyExistsException; +import ca.nrc.cadc.ac.UserNotFoundException; +import ca.nrc.cadc.ac.UserRequest; import ca.nrc.cadc.net.TransientException; +import java.security.AccessControlException; +import java.security.Principal; +import java.util.Collection; public interface UserPersistence<T extends Principal> { @@ -85,7 +87,7 @@ public interface UserPersistence<T extends Principal> * @throws TransientException If an temporary, unexpected problem occurred. * @throws AccessControlException If the operation is not permitted. */ - Map<String, PersonalDetails> getUsers() + Collection<User<Principal>> getUsers() throws TransientException, AccessControlException; /** diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java index 219728d8..5c09a99f 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java @@ -150,8 +150,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO private String[] userAttribs = new String[] { LDAP_FIRST_NAME, LDAP_LAST_NAME, LDAP_ADDRESS, LDAP_CITY, - LDAP_COUNTRY, - LDAP_EMAIL, LDAP_INSTITUTE + LDAP_COUNTRY, LDAP_EMAIL, LDAP_INSTITUTE }; private String[] memberAttribs = new String[] { @@ -539,11 +538,10 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO * @return A map of string keys to string values. * @throws TransientException If an temporary, unexpected problem occurred. */ - public Map<String, PersonalDetails> getUsers() + public Collection<User<Principal>> getUsers() throws TransientException { - final Map<String, PersonalDetails> users = - new HashMap<String, PersonalDetails>(); + final Collection<User<Principal>> users = new ArrayList<User<Principal>>(); try { @@ -566,16 +564,15 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO { if (!next.hasAttribute(LDAP_NSACCOUNTLOCK)) { - final String trimmedFirstName = + final String firstName = next.getAttributeValue(LDAP_FIRST_NAME).trim(); - final String trimmedLastName = + final String lastName = next.getAttributeValue(LDAP_LAST_NAME).trim(); - final String trimmedUID = - next.getAttributeValue(LDAP_UID).trim(); - - users.put(trimmedUID, - new PersonalDetails(trimmedFirstName, - trimmedLastName)); + final String uid = next.getAttributeValue(LDAP_UID).trim(); + User<Principal> user = new User<Principal>(new HttpPrincipal(uid)); + PersonalDetails pd = new PersonalDetails(firstName, lastName); + user.details.add(pd); + users.add(user); } } } diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java index 6a042cc3..fd8b41ec 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java @@ -75,6 +75,7 @@ import com.unboundid.ldap.sdk.DN; import java.security.AccessControlException; import java.security.Principal; import java.util.Collection; +import java.util.List; import java.util.Map; import org.apache.log4j.Logger; @@ -96,8 +97,8 @@ public class LdapUserPersistence<T extends Principal> logger.error("test/config/LdapConfig.properties file required.", e); } } - - public Map<String, PersonalDetails> getUsers() + + public Collection<User<Principal>> getUsers() throws TransientException, AccessControlException { LdapUserDAO<T> userDAO = null; @@ -125,7 +126,6 @@ public class LdapUserPersistence<T extends Principal> * @throws TransientException If an temporary, unexpected problem occurred. * @throws AccessControlException If the operation is not permitted. */ - @Override public User<T> addUser(UserRequest<T> user) throws TransientException, AccessControlException, UserAlreadyExistsException @@ -183,7 +183,6 @@ public class LdapUserPersistence<T extends Principal> * @throws TransientException If an temporary, unexpected problem occurred. * @throws AccessControlException If the operation is not permitted. */ - @Override public User<T> getPendingUser(final T userID) throws UserNotFoundException, TransientException, AccessControlException diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupAction.java index 2805eda5..9a93cfec 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupAction.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupAction.java @@ -68,19 +68,6 @@ */ package ca.nrc.cadc.ac.server.web.groups; -import java.io.IOException; -import java.security.AccessControlException; -import java.security.Principal; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.List; - -import javax.security.auth.Subject; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.log4j.Logger; - import ca.nrc.cadc.ac.GroupAlreadyExistsException; import ca.nrc.cadc.ac.GroupNotFoundException; import ca.nrc.cadc.ac.MemberAlreadyExistsException; @@ -91,6 +78,15 @@ import ca.nrc.cadc.ac.server.PluginFactory; import ca.nrc.cadc.ac.server.UserPersistence; import ca.nrc.cadc.ac.server.web.SyncOutput; import ca.nrc.cadc.net.TransientException; +import org.apache.log4j.Logger; + +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.security.AccessControlException; +import java.security.Principal; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.List; public abstract class AbstractGroupAction implements PrivilegedExceptionAction<Object> { @@ -208,18 +204,18 @@ public abstract class AbstractGroupAction implements PrivilegedExceptionAction<O private void sendError(int responseCode, String message) { syncOut.setHeader("Content-Type", "text/plain"); + syncOut.setCode(responseCode); if (message != null) { try { - syncOut.getWriter() .write(message); + syncOut.getWriter().write(message); } catch (IOException e) { log.warn("Could not write error message to output stream"); } } - syncOut.setCode(responseCode); } <T extends Principal> GroupPersistence<T> getGroupPersistence() diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/CreateGroupAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/CreateGroupAction.java index a4341c40..5afabdb0 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/CreateGroupAction.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/CreateGroupAction.java @@ -99,7 +99,8 @@ public class CreateGroupAction extends AbstractGroupAction groupWriter.write(newGroup, syncOut.getWriter()); List<String> addedMembers = null; - if ((newGroup.getUserMembers().size() > 0) || (newGroup.getGroupMembers().size() > 0)) + if ((newGroup.getUserMembers().size() > 0) || + (newGroup.getGroupMembers().size() > 0)) { addedMembers = new ArrayList<String>(); for (Group gr : newGroup.getGroupMembers()) diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java index 07a83782..0a7266ca 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java @@ -94,7 +94,9 @@ import java.io.Writer; import java.security.AccessControlException; import java.security.Principal; import java.security.PrivilegedExceptionAction; +import java.util.Collection; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Set; @@ -324,7 +326,7 @@ public abstract class AbstractUserAction implements PrivilegedExceptionAction<Ob * * @param users The Map of user IDs to names. */ - protected final void writeUsers(final Map<String, PersonalDetails> users) + protected final <T extends Principal> void writeUsers(final Collection<User<T>> users) throws IOException { syncOut.setHeader("Content-Type", acceptedContentType); diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserListActionTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserListActionTest.java index 8e3a6db4..0624272f 100644 --- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserListActionTest.java +++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserListActionTest.java @@ -70,6 +70,7 @@ package ca.nrc.cadc.ac.server.web.users; import ca.nrc.cadc.ac.PersonalDetails; +import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.json.JsonUserListWriter; import ca.nrc.cadc.ac.server.UserPersistence; import ca.nrc.cadc.ac.server.web.SyncOutput; @@ -85,7 +86,10 @@ import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; +import java.security.Principal; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import static org.easymock.EasyMock.*; @@ -115,13 +119,14 @@ public class GetUserListActionTest createMock(SyncOutput.class); final UserPersistence<HttpPrincipal> mockUserPersistence = createMock(UserPersistence.class); - final Map<String, PersonalDetails> userEntries = - new HashMap<String, PersonalDetails>(); + List<User<Principal>> expectedUsers = new ArrayList<User<Principal>>(); for (int i = 1; i <= 5; i++) { - userEntries.put("USER_" + i, - new PersonalDetails("USER", Integer.toString(i))); + User<Principal> user = new User<Principal>(new HttpPrincipal("USER_" + i)); + PersonalDetails pd = new PersonalDetails("USER", Integer.toString(i)); + user.details.add(pd); + expectedUsers.add(user); } final GetUserListAction testSubject = new GetUserListAction() @@ -138,8 +143,7 @@ public class GetUserListActionTest final Writer actualWriter = new StringWriter(); final PrintWriter actualPrintWriter = new PrintWriter(actualWriter); - expect(mockUserPersistence.getUsers()).andReturn( - userEntries).once(); + expect(mockUserPersistence.getUsers()).andReturn(expectedUsers).once(); expect(mockSyncOut.getWriter()).andReturn(actualPrintWriter).once(); mockSyncOut.setHeader("Content-Type", "application/json"); expectLastCall().once(); @@ -153,7 +157,7 @@ public class GetUserListActionTest final Writer expectedWriter = new StringWriter(); final PrintWriter expectedPrintWriter = new PrintWriter(expectedWriter); JsonUserListWriter userListWriter = new JsonUserListWriter(); - userListWriter.write(userEntries, expectedPrintWriter); + userListWriter.write(expectedUsers, expectedPrintWriter); JSONAssert.assertEquals(expectedWriter.toString(), actualWriter.toString(), false); verify(mockSyncOut, mockUserPersistence); @@ -167,13 +171,14 @@ public class GetUserListActionTest createMock(SyncOutput.class); final UserPersistence<HttpPrincipal> mockUserPersistence = createMock(UserPersistence.class); - final Map<String, PersonalDetails> userEntries = - new HashMap<String, PersonalDetails>(); + List<User<Principal>> expectedUsers = new ArrayList<User<Principal>>(); for (int i = 1; i <= 5; i++) { - userEntries.put("USER_" + i, - new PersonalDetails("USER", Integer.toString(i))); + User<Principal> user = new User<Principal>(new HttpPrincipal("USER_" + i)); + PersonalDetails pd = new PersonalDetails("USER", Integer.toString(i)); + user.details.add(pd); + expectedUsers.add(user); } final GetUserListAction testSubject = new GetUserListAction() @@ -188,8 +193,7 @@ public class GetUserListActionTest final Writer actualWriter = new StringWriter(); final PrintWriter actualPrintWriter = new PrintWriter(actualWriter); - expect(mockUserPersistence.getUsers()).andReturn( - userEntries).once(); + expect(mockUserPersistence.getUsers()).andReturn(expectedUsers).once(); expect(mockSyncOut.getWriter()).andReturn(actualPrintWriter).once(); mockSyncOut.setHeader("Content-Type", "text/xml"); expectLastCall().once(); @@ -203,7 +207,7 @@ public class GetUserListActionTest final Writer expectedWriter = new StringWriter(); final PrintWriter expectedPrintWriter = new PrintWriter(expectedWriter); UserListWriter userListWriter = new UserListWriter(); - userListWriter.write(userEntries, expectedPrintWriter); + userListWriter.write(expectedUsers, expectedPrintWriter); assertEquals("Wrong XML", expectedWriter.toString(), actualWriter.toString()); verify(mockSyncOut, mockUserPersistence); diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java index bad17d1f..d2d2661a 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java @@ -105,6 +105,7 @@ import java.security.AccessControlException; import java.security.AccessController; import java.security.Principal; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonGroupReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonGroupReader.java index a240184b..e5997162 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonGroupReader.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonGroupReader.java @@ -76,37 +76,15 @@ import org.jdom2.Document; import org.json.JSONException; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.io.Reader; import java.util.Scanner; +/** + * Class to read an JSON representation of a list of Groups + * into a list of Group objects. + */ public class JsonGroupReader extends GroupReader { - /** - * Construct a Group from a InputStream. - * - * @param in InputStream. - * @return Group Group. - * @throws ReaderException - * @throws IOException - */ - @Override - public Group read(InputStream in) - throws ReaderException, IOException - { - if (in == null) - { - throw new IOException("stream closed"); - } - InputStreamReader reader; - - Scanner s = new Scanner(in).useDelimiter("\\A"); - String json = s.hasNext() ? s.next() : ""; - - return read(json); - } - /** * Construct a Group from a Reader. * @@ -127,27 +105,6 @@ public class JsonGroupReader extends GroupReader Scanner s = new Scanner(reader).useDelimiter("\\A"); String json = s.hasNext() ? s.next() : ""; - return read(json); - } - - /** - * Construct a Group from an JSON String source. - * - * @param json String of JSON. - * @return Group Group. - * @throws ReaderException - * @throws IOException - */ - @Override - public Group read(String json) - throws ReaderException, IOException - { - if (json == null) - { - throw new IllegalArgumentException("JSON must not be null"); - } - - // Create a JSONObject from the JSON try { JsonInputter jsonInputter = new JsonInputter(); @@ -160,12 +117,12 @@ public class JsonGroupReader extends GroupReader jsonInputter.getListElementMap().put("userAdmins", "user"); Document document = jsonInputter.input(json); - return GroupReader.parseGroup(document.getRootElement()); + return getGroup(document.getRootElement()); } catch (JSONException e) { String error = "Unable to parse JSON to Group because " + - e.getMessage(); + e.getMessage(); throw new ReaderException(error, e); } } diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonGroupWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonGroupWriter.java index 2db22932..864e14df 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonGroupWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonGroupWriter.java @@ -71,57 +71,18 @@ package ca.nrc.cadc.ac.json; import ca.nrc.cadc.ac.Group; import ca.nrc.cadc.ac.WriterException; import ca.nrc.cadc.ac.xml.GroupWriter; -import ca.nrc.cadc.util.StringBuilderWriter; import ca.nrc.cadc.xml.JsonOutputter; import org.jdom2.Document; import org.jdom2.Element; -import java.io.BufferedWriter; import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; import java.io.Writer; +/** + * Class to write a JSON representation of a Group object. + */ public class JsonGroupWriter extends GroupWriter { - /** - * Write a Group to a StringBuilder. - * @param group - * @param builder - * @throws IOException - * @throws WriterException - */ - public void write(Group group, StringBuilder builder) - throws IOException, WriterException - { - write(group, new StringBuilderWriter(builder)); - } - - /** - * Write a Group to an OutputStream. - * - * @param group Group to write. - * @param out OutputStream to write to. - * @throws IOException if the writer fails to write. - * @throws WriterException - */ - @Override - public void write(Group group, OutputStream out) - throws IOException, WriterException - { - OutputStreamWriter outWriter; - try - { - outWriter = new OutputStreamWriter(out, "UTF-8"); - } - catch (UnsupportedEncodingException e) - { - throw new RuntimeException("UTF-8 encoding not supported", e); - } - write(group, new BufferedWriter(outWriter)); - } - /** * Write a Group to a Writer. * @@ -139,7 +100,7 @@ public class JsonGroupWriter extends GroupWriter throw new WriterException("null group"); } - Element children = GroupWriter.getGroupElement(group); + Element children = getElement(group); Element groupElement = new Element("group"); groupElement.addContent(children); Document document = new Document(); diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserListReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserListReader.java new file mode 100644 index 00000000..1e63aded --- /dev/null +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserListReader.java @@ -0,0 +1,127 @@ +/* + ************************************************************************ + ******************* CANADIAN ASTRONOMY DATA CENTRE ******************* + ************** CENTRE CANADIEN DE DONNÉES ASTRONOMIQUES ************** + * + * (c) 2015. (c) 2015. + * 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 + * <http://www.gnu.org/licenses/>. pas le cas, consultez : + * <http://www.gnu.org/licenses/>. + * + * + ************************************************************************ + */ + +package ca.nrc.cadc.ac.json; + +import ca.nrc.cadc.ac.ReaderException; +import ca.nrc.cadc.ac.User; +import ca.nrc.cadc.ac.xml.UserListReader; +import ca.nrc.cadc.xml.JsonInputter; +import org.jdom2.Document; +import org.json.JSONException; + +import java.io.Reader; +import java.net.URISyntaxException; +import java.security.Principal; +import java.util.List; +import java.util.Scanner; + +/** + * Class to read an JSON representation of a Collection of Users + * into a list of User objects. + */ +public class JsonUserListReader extends UserListReader +{ + /** + * Construct a list of Users from a Reader. + * + * @param reader Reader. + * @return users List of Users. + * @throws ReaderException + * @throws URISyntaxException + */ + @Override + public List<User<Principal>> read(Reader reader) + throws URISyntaxException, ReaderException + { + if (reader == null) + { + throw new IllegalArgumentException("reader must not be null"); + } + + Scanner s = new Scanner(reader).useDelimiter("\\A"); + String json = s.hasNext() ? s.next() : ""; + + try + { + JsonInputter jsonInputter = new JsonInputter(); + jsonInputter.getListElementMap().put("identities", "identity"); + jsonInputter.getListElementMap().put("details", "userDetails"); + + Document document = jsonInputter.input(json); + return getUserList(document.getRootElement()); + } + catch (JSONException e) + { + String error = "Unable to parse JSON to list of Users because " + + e.getMessage(); + throw new ReaderException(error, e); + } + } + +} diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserListWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserListWriter.java index 5bf9317a..9a8acad6 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserListWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserListWriter.java @@ -68,58 +68,54 @@ package ca.nrc.cadc.ac.json; -import ca.nrc.cadc.ac.PersonalDetails; -import org.json.JSONException; -import org.json.JSONWriter; +import ca.nrc.cadc.ac.User; +import ca.nrc.cadc.ac.WriterException; +import ca.nrc.cadc.ac.xml.UserListWriter; +import ca.nrc.cadc.xml.JsonOutputter; +import org.jdom2.Document; +import org.jdom2.Element; import java.io.IOException; import java.io.Writer; -import java.util.Map; - +import java.security.Principal; +import java.util.Collection; /** * Class to write out, as JSON, a list of user entries. */ -public class JsonUserListWriter +public class JsonUserListWriter extends UserListWriter { - public static void write(final Map<String, PersonalDetails> users, - final Writer writer) throws IOException + /** + * Write a Collection of Users to a Writer. + * + * @param users Users to write. + * @param writer Writer to write to. + * @throws IOException if the writer fails to write. + * @throws WriterException + */ + @Override + public <T extends Principal> void write(Collection<User<T>> users, Writer writer) + throws IOException, WriterException { - final JSONWriter jsonWriter = new JSONWriter(writer); - - try + if (users == null) { - jsonWriter.array(); - - for (final Map.Entry<String, PersonalDetails> entry - : users.entrySet()) - { - jsonWriter.object(); - - jsonWriter.key("id").value(entry.getKey()); - jsonWriter.key("firstName").value(entry.getValue(). - getFirstName()); - jsonWriter.key("lastName").value(entry.getValue(). - getLastName()); - - jsonWriter.endObject(); - writer.write("\n"); - } + throw new WriterException("null users"); } - catch (JSONException e) - { - throw new IOException(e); - } - finally + + Element usersElement = new Element("users"); + for (User<? extends Principal> user : users) { - try - { - jsonWriter.endArray(); - } - catch (JSONException e) - { - // Do nothing. - } + Element userElement = new Element(("user")); + userElement.addContent(getElement(user)); } + Document document = new Document(); + document.setRootElement(usersElement); + + JsonOutputter jsonOutputter = new JsonOutputter(); + jsonOutputter.getListElementNames().add("identities"); + jsonOutputter.getListElementNames().add("details"); + + jsonOutputter.output(document, writer); } + } diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserReader.java index 2c4a8e37..4ef9ee9a 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserReader.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserReader.java @@ -76,36 +76,15 @@ import org.jdom2.Document; import org.json.JSONException; import java.io.IOException; -import java.io.InputStream; import java.io.Reader; import java.security.Principal; import java.util.Scanner; +/** + * Class to read a JSON representation of a User to a User object. + */ public class JsonUserReader extends UserReader { - /** - * Construct a User from a InputStream. - * - * @param in InputStream. - * @return User User. - * @throws ReaderException - * @throws IOException - */ - @Override - public User<Principal> read(InputStream in) - throws IOException - { - if (in == null) - { - throw new IOException("stream closed"); - } - - Scanner s = new Scanner(in).useDelimiter("\\A"); - String json = s.hasNext() ? s.next() : ""; - - return read(json); - } - /** * Construct a User from a Reader. * @@ -126,27 +105,6 @@ public class JsonUserReader extends UserReader Scanner s = new Scanner(reader).useDelimiter("\\A"); String json = s.hasNext() ? s.next() : ""; - return read(json); - } - - /** - * Construct a User from an JSON String source. - * - * @param json String of JSON. - * @return User User. - * @throws ReaderException - * @throws IOException - */ - @Override - public User<Principal> read(String json) - throws IOException - { - if (json == null || json.isEmpty()) - { - throw new IllegalArgumentException("JSON must not be null or empty"); - } - - // Create a JSONObject from the JSON try { JsonInputter jsonInputter = new JsonInputter(); @@ -154,7 +112,7 @@ public class JsonUserReader extends UserReader jsonInputter.getListElementMap().put("details", "userDetails"); Document document = jsonInputter.input(json); - return UserReader.parseUser(document.getRootElement()); + return getUser(document.getRootElement()); } catch (JSONException e) { diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserRequestReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserRequestReader.java index b8d61e8c..eb03dbb0 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserRequestReader.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserRequestReader.java @@ -76,36 +76,15 @@ import org.jdom2.Document; import org.json.JSONException; import java.io.IOException; -import java.io.InputStream; import java.io.Reader; import java.security.Principal; import java.util.Scanner; +/** + * Class to read a JSON representation of a UserRequest to a UserRequest object. + */ public class JsonUserRequestReader extends UserRequestReader { - /** - * Construct a User from a InputStream. - * - * @param in InputStream. - * @return User User. - * @throws ReaderException - * @throws IOException - */ - @Override - public UserRequest<Principal> read(InputStream in) - throws IOException - { - if (in == null) - { - throw new IOException("stream closed"); - } - - Scanner s = new Scanner(in).useDelimiter("\\A"); - String json = s.hasNext() ? s.next() : ""; - - return read(json); - } - /** * Construct a User from a Reader. * @@ -126,41 +105,20 @@ public class JsonUserRequestReader extends UserRequestReader Scanner s = new Scanner(reader).useDelimiter("\\A"); String json = s.hasNext() ? s.next() : ""; - return read(json); - } - - /** - * Construct a UserRequest from an JSON String source. - * - * @param json String of the JSON. - * @return UserRequest UserRequest. - * @throws IOException - */ - @Override - public UserRequest<Principal> read(String json) - throws IOException - { - if (json == null) + try { - throw new IllegalArgumentException("JSON must not be null"); + JsonInputter jsonInputter = new JsonInputter(); + jsonInputter.getListElementMap().put("identities", "identity"); + jsonInputter.getListElementMap().put("details", "userDetails"); + + Document document = jsonInputter.input(json); + return getUserRequest(document.getRootElement()); } - else + catch (JSONException e) { - try - { - JsonInputter jsonInputter = new JsonInputter(); - jsonInputter.getListElementMap().put("identities", "identity"); - jsonInputter.getListElementMap().put("details", "userDetails"); - - Document document = jsonInputter.input(json); - return UserRequestReader.parseUserRequest(document.getRootElement()); - } - catch (JSONException e) - { - String error = "Unable to parse JSON to User because " + - e.getMessage(); - throw new ReaderException(error, e); - } + String error = "Unable to parse JSON to User because " + + e.getMessage(); + throw new ReaderException(error, e); } } diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserRequestWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserRequestWriter.java index 7ebb07a6..6cf6e6f7 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserRequestWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserRequestWriter.java @@ -1,9 +1,77 @@ +/* +************************************************************************ +******************* 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 +* <http://www.gnu.org/licenses/>. pas le cas, consultez : +* <http://www.gnu.org/licenses/>. +* +* $Revision: 5 $ +* +************************************************************************ +*/ + package ca.nrc.cadc.ac.json; import ca.nrc.cadc.ac.UserRequest; import ca.nrc.cadc.ac.WriterException; import ca.nrc.cadc.ac.xml.UserRequestWriter; -import ca.nrc.cadc.util.StringBuilderWriter; import ca.nrc.cadc.xml.JsonOutputter; import org.jdom2.Document; import org.jdom2.Element; @@ -17,20 +85,6 @@ import java.security.Principal; */ public class JsonUserRequestWriter extends UserRequestWriter { - /** - * Write a UserRequest to a StringBuilder. - * - * @param userRequest UserRequest to write. - * @param builder StringBuilder to write to. - * @throws java.io.IOException if the writer fails to write. - * @throws WriterException - */ - public void write(UserRequest<? extends Principal> userRequest, StringBuilder builder) - throws IOException, WriterException - { - write(userRequest, new StringBuilderWriter(builder)); - } - /** * Write a UserRequest to a Writer. * @@ -39,7 +93,8 @@ public class JsonUserRequestWriter extends UserRequestWriter * @throws IOException if the writer fails to write. * @throws WriterException */ - public static void write(UserRequest<? extends Principal> userRequest, Writer writer) + @Override + public <T extends Principal> void write(UserRequest<T> userRequest, Writer writer) throws IOException, WriterException { if (userRequest == null) @@ -47,7 +102,7 @@ public class JsonUserRequestWriter extends UserRequestWriter throw new WriterException("null UserRequest"); } - Element children = UserRequestWriter.getUserRequestElement(userRequest); + Element children = getElement(userRequest); Element userRequestElement = new Element("userRequest"); userRequestElement.addContent(children); Document document = new Document(); diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserWriter.java index 444a670a..3b9004ff 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserWriter.java @@ -69,68 +69,21 @@ package ca.nrc.cadc.ac.json; import ca.nrc.cadc.ac.User; -import ca.nrc.cadc.ac.UserDetails; import ca.nrc.cadc.ac.WriterException; -import ca.nrc.cadc.ac.xml.GroupWriter; import ca.nrc.cadc.ac.xml.UserWriter; -import ca.nrc.cadc.util.StringBuilderWriter; import ca.nrc.cadc.xml.JsonOutputter; import org.jdom2.Document; import org.jdom2.Element; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import java.io.BufferedWriter; import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; import java.io.Writer; import java.security.Principal; -import java.util.Set; +/** + * Class to write a JSON representation of a User object. + */ public class JsonUserWriter extends UserWriter { - /** - * Write a User as a JSON string to a StringBuilder. - * - * @param user User to write. - * @param builder StringBuilder to write to. - * @throws IOException if the writer fails to write. - * @throws WriterException - */ - @Override - public void write(User<? extends Principal> user, StringBuilder builder) - throws IOException, WriterException - { - write(user, new StringBuilderWriter(builder)); - } - - /** - * Write a User as a JSON string to an OutputStream. - * - * @param user User to write. - * @param out OutputStream to write to. - * @throws IOException if the writer fails to write. - * @throws WriterException - */ - @Override - public void write(User<? extends Principal> user, OutputStream out) - throws IOException, WriterException - { - OutputStreamWriter outWriter; - try - { - outWriter = new OutputStreamWriter(out, "UTF-8"); - } - catch (UnsupportedEncodingException e) - { - throw new RuntimeException("UTF-8 encoding not supported", e); - } - write(user, new BufferedWriter(outWriter)); - } - /** * Write a User as a JSON string to a Writer. * @@ -140,7 +93,7 @@ public class JsonUserWriter extends UserWriter * @throws WriterException */ @Override - public void write(User<? extends Principal> user, Writer writer) + public<T extends Principal> void write(User<T> user, Writer writer) throws IOException, WriterException { if (user == null) @@ -148,7 +101,7 @@ public class JsonUserWriter extends UserWriter throw new WriterException("null User"); } - Element children = UserWriter.getUserElement(user); + Element children = getElement(user); Element userElement = new Element("user"); userElement.addContent(children); Document document = new Document(); diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractXML.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractXML.java new file mode 100644 index 00000000..db221a9d --- /dev/null +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractXML.java @@ -0,0 +1,1018 @@ +/* +************************************************************************ +******************* 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 +* <http://www.gnu.org/licenses/>. pas le cas, consultez : +* <http://www.gnu.org/licenses/>. +* +* $Revision: 5 $ +* +************************************************************************ +*/ + +package ca.nrc.cadc.ac.xml; + +import ca.nrc.cadc.ac.AC; +import ca.nrc.cadc.ac.Group; +import ca.nrc.cadc.ac.GroupProperty; +import ca.nrc.cadc.ac.IdentityType; +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.UserDetails; +import ca.nrc.cadc.ac.UserRequest; +import ca.nrc.cadc.ac.WriterException; +import ca.nrc.cadc.auth.HttpPrincipal; +import ca.nrc.cadc.auth.NumericPrincipal; +import ca.nrc.cadc.auth.OpenIdPrincipal; +import ca.nrc.cadc.date.DateUtil; +import org.jdom2.Attribute; +import org.jdom2.Document; +import org.jdom2.Element; +import org.jdom2.output.Format; +import org.jdom2.output.XMLOutputter; + +import javax.security.auth.x500.X500Principal; +import java.io.IOException; +import java.io.Writer; +import java.security.Principal; +import java.text.DateFormat; +import java.text.ParseException; +import java.util.List; +import java.util.Set; + +/** + * AbstractXML TODO describe class + */ +public abstract class AbstractXML +{ + /** + * 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 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(AC.GROUP_URI); + if (index == -1) + { + String error = "group uri attribute malformed: " + uri; + throw new ReaderException(error); + } + String groupID = uri.substring(AC.GROUP_URI.length()); + + // Group owner + User<? extends Principal> 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, user); + + // description + Element descriptionElement = element.getChild("description"); + if (descriptionElement != null) + { + group.description = descriptionElement.getText(); + } + + // lastModified + Element lastModifiedElement = element.getChild("lastModified"); + 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<Element> propertyElements = propertiesElement.getChildren("property"); + for (Element propertyElement : propertyElements) + { + group.getProperties().add(getGroupProperty(propertyElement)); + } + } + + // groupMembers + Element groupMembersElement = element.getChild("groupMembers"); + if (groupMembersElement != null) + { + List<Element> groupElements = groupMembersElement.getChildren("group"); + for (Element groupMember : groupElements) + { + group.getGroupMembers().add(getGroup(groupMember)); + } + } + + // userMembers + Element userMembersElement = element.getChild("userMembers"); + if (userMembersElement != null) + { + List<Element> userElements = userMembersElement.getChildren("user"); + for (Element userMember : userElements) + { + group.getUserMembers().add(getUser(userMember)); + } + } + + // groupAdmins + Element groupAdminsElement = element.getChild("groupAdmins"); + if (groupAdminsElement != null) + { + List<Element> groupElements = groupAdminsElement.getChildren("group"); + for (Element groupMember : groupElements) + { + group.getGroupAdmins().add(getGroup(groupMember)); + } + } + + // userAdmins + Element userAdminsElement = element.getChild("userAdmins"); + if (userAdminsElement != null) + { + List<Element> userElements = userAdminsElement.getChildren("user"); + for (Element userMember : userElements) + { + group.getUserAdmins().add(getUser(userMember)); + } + } + + return group; + } + + /** + * 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 + { + // Create the root group element. + Element groupElement = new Element("group"); + String groupURI = AC.GROUP_URI + 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("lastModified"); + 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("groupMembers"); + 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("userMembers"); + for (User<? extends Principal> userMember : group.getUserMembers()) + { + userMembersElement.addContent(getElement(userMember)); + } + groupElement.addContent(userMembersElement); + } + + // Group groupAdmins. + if ((group.getGroupAdmins() != null) && (!group.getGroupAdmins().isEmpty())) + { + Element groupAdminsElement = new Element("groupAdmins"); + 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("userAdmins"); + for (User<? extends Principal> userMember : group.getUserAdmins()) + { + userAdminsElement.addContent(getElement(userMember)); + } + groupElement.addContent(userAdminsElement); + } + } + + return groupElement; + } + + /** + * Get a UserRequest object from a JDOM element. + * + * @param element The UserRequest JDOM element. + * @return A UserRequest object. + * @throws ReaderException + */ + protected final UserRequest<Principal> 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<Principal> 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<Principal>(user, password.toCharArray()); + } + + /** + * Get a JDOM element from a UserRequest object. + * + * @param userRequest The UserRequest. + * @return A JDOM UserRequest representation. + * @throws WriterException + */ + protected final Element getElement(UserRequest<? extends Principal> userRequest) + throws WriterException + { + // Create the userRequest Element. + Element userRequestElement = new Element("userRequest"); + + // 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 User object from a JDOM element. + * + * @param element The User JDOM element. + * @return A User object. + * @throws ReaderException + */ + protected final User<Principal> getUser(Element element) + throws ReaderException + { + // userID element of the User element + Element userIDElement = element.getChild("userID"); + if (userIDElement == null) + { + String error = "userID element not found in user element"; + throw new ReaderException(error); + } + + // identity element of the userID element + Element userIDIdentityElement = userIDElement.getChild("identity"); + if (userIDIdentityElement == null) + { + String error = "identity element not found in userID element"; + throw new ReaderException(error); + } + + Principal userID = getPrincipal(userIDIdentityElement); + User<Principal> user = new User<Principal>(userID); + + // identities + Element identitiesElement = element.getChild("identities"); + if (identitiesElement != null) + { + List<Element> identityElements = identitiesElement.getChildren("identity"); + for (Element identityElement : identityElements) + { + user.getIdentities().add(getPrincipal(identityElement)); + } + + } + + // details + Element detailsElement = element.getChild("details"); + if (detailsElement != null) + { + List<Element> userDetailsElements = detailsElement.getChildren("userDetails"); + for (Element userDetailsElement : userDetailsElements) + { + user.details.add(getUserDetails(userDetailsElement)); + } + } + + return user; + } + + /** + * Get a JDOM element from a User object. + * + * @param user The User. + * @return A JDOM User representation. + * @throws WriterException + */ + protected final Element getElement(User<? extends Principal> user) + throws WriterException + { + // Create the user Element. + Element userElement = new Element("user"); + + // userID element + Element userIDElement = new Element("userID"); + userIDElement.addContent(getElement(user.getUserID())); + userElement.addContent(userIDElement); + + // identities + Set<Principal> identities = user.getIdentities(); + if (!identities.isEmpty()) + { + Element identitiesElement = new Element("identities"); + for (Principal identity : identities) + { + identitiesElement.addContent(getElement(identity)); + } + userElement.addContent(identitiesElement); + } + + // details + if (!user.details.isEmpty()) + { + Element detailsElement = new Element("details"); + Set<UserDetails> userDetails = user.details; + for (UserDetails userDetail : userDetails) + { + detailsElement.addContent(getElement(userDetail)); + } + userElement.addContent(detailsElement); + } + + return userElement; + } + + /** + * 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(GroupProperty.NAME)) + { + String error = "expected property element name, found " + + element.getName(); + throw new ReaderException(error); + } + + String key = element.getAttributeValue(GroupProperty.KEY_ATTRIBUTE); + if (key == null) + { + String error = "required key attribute not found"; + throw new ReaderException(error); + } + + String type = element.getAttributeValue(GroupProperty.TYPE_ATTRIBUTE); + if (type == null) + { + String error = "required type attribute not found"; + throw new ReaderException(error); + } + Object value; + if (type.equals(GroupProperty.STRING_TYPE)) + { + value = String.valueOf(element.getText()); + } + else + { + if (type.equals(GroupProperty.INTEGER_TYPE)) + { + value = Integer.valueOf(element.getText()); + } + else + { + String error = "Unsupported GroupProperty type: " + type; + throw new ReaderException(error); + } + } + Boolean readOnly = Boolean.valueOf(element.getAttributeValue(GroupProperty.READONLY_ATTRIBUTE)); + + return new GroupProperty(key, value, readOnly); + } + + /** + * 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(GroupProperty.NAME); + propertyElement.setAttribute(GroupProperty.KEY_ATTRIBUTE, + property.getKey()); + if (property.isReadOnly()) + { + propertyElement.setAttribute(GroupProperty.READONLY_ATTRIBUTE, + "true"); + } + + Object value = property.getValue(); + if ((value instanceof String)) + { + propertyElement.setAttribute(GroupProperty.TYPE_ATTRIBUTE, + GroupProperty.STRING_TYPE); + } + else if ((value instanceof Integer)) + { + propertyElement.setAttribute(GroupProperty.TYPE_ATTRIBUTE, + GroupProperty.INTEGER_TYPE); + } + else + { + String error = "Unsupported value type: " + + value.getClass().getSimpleName(); + throw new IllegalArgumentException(error); + } + propertyElement.setText(String.valueOf(property.getValue())); + + return propertyElement; + } + + /** + * 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.UID.getValue())) + { + Integer cadcID; + try + { + cadcID = Integer.valueOf(identity); + } + catch (NumberFormatException e) + { + String error = "Non-integer cadcID: " + identity; + throw new ReaderException(error); + } + principal = new NumericPrincipal(cadcID); + } + else if (type.equals(IdentityType.USERNAME.getValue())) + { + principal = new HttpPrincipal(identity); + } + else if (type.equals(IdentityType.X500.getValue())) + { + principal = new X500Principal(identity); + } + else + { + String error = "Unknown type attribute: " + type; + throw new ReaderException(error); + } + + return principal; + } + + /** + * 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 identity"; + 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.UID.getValue()); + } + else if ((identity instanceof OpenIdPrincipal)) + { + identityElement.setAttribute("type", IdentityType.OPENID.getValue()); + } + else if ((identity instanceof X500Principal)) + { + identityElement.setAttribute("type", IdentityType.X500.getValue()); + } + else + { + String error = "Unsupported Principal type " + + identity.getClass().getSimpleName(); + throw new IllegalArgumentException(error); + } + identityElement.setText(identity.getName()); + + return identityElement; + } + + /** + * Get a UserDetails object from a JDOM element. + * + * @param element The UserDetails JDOM element. + * @return A UserDetails object. + * @throws ReaderException + */ + protected final UserDetails getUserDetails(Element element) + throws ReaderException + { + if (element == null) + { + throw new ReaderException("null UserDetails"); + } + + if (!element.getName().equals(UserDetails.NAME)) + { + String error = "expected element name userDetails, found " + + element.getName(); + throw new ReaderException(error); + } + + String type = element.getAttributeValue(UserDetails.TYPE_ATTRIBUTE); + if (type == null) + { + String error = "userDetails missing required attribute type"; + throw new ReaderException(error); + } + + if (type.equals(PosixDetails.NAME)) + { + return getPosixDetails(element); + } + if (type.equals(PersonalDetails.NAME)) + { + return getPersonalDetails(element); + } + + String error = "Unknown UserDetails attribute type " + type; + throw new ReaderException(error); + } + + /** + * 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 + { + // uid + Element uidElement = element.getChild(PosixDetails.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(PosixDetails.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(PosixDetails.HOME_DIRECTORY); + if (homeDirElement == null) + { + String error = "posixDetails missing required element homeDirectory"; + throw new ReaderException(error); + } + String homeDirectory = homeDirElement.getText(); + + return new PosixDetails(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 + { + // firstName + Element firstNameElement = element.getChild(PersonalDetails.FIRSTNAME); + if (firstNameElement == null) + { + String error = "personalDetails missing required element firstName"; + throw new ReaderException(error); + } + String firstName = firstNameElement.getText(); + + // lastName + Element lastNameElement = element.getChild(PersonalDetails.LASTNAME); + 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(PersonalDetails.EMAIL); + if (emailElement != null) + { + details.email = emailElement.getText(); + } + + // address + Element addressElement = element.getChild(PersonalDetails.ADDRESS); + if (addressElement != null) + { + details.address = addressElement.getText(); + } + + // institute + Element instituteElement = element.getChild(PersonalDetails.INSTITUTE); + if (instituteElement != null) + { + details.institute = instituteElement.getText(); + } + + // city + Element cityElement = element.getChild(PersonalDetails.CITY); + if (cityElement != null) + { + details.city = cityElement.getText(); + } + + // country + Element countryElement = element.getChild(PersonalDetails.COUNTRY); + if (countryElement != null) + { + details.country = countryElement.getText(); + } + + return details; + } + + /** + * Get a JDOM element from a UserDetails object. + * + * @param details The UserDetails. + * @return A JDOM UserDetails representation. + * @throws WriterException + */ + protected final Element getElement(UserDetails details) + throws WriterException + { + if (details == null) + { + throw new WriterException("null UserDetails"); + } + + if ((details instanceof PosixDetails)) + { + return getElement((PosixDetails) details); + } + if ((details instanceof PersonalDetails)) + { + return getElement((PersonalDetails) details); + } + + String error = "Unknown UserDetails implementation: " + + details.getClass().getName(); + throw new WriterException(error); + } + + /** + * Get a JDOM element from a PosixDetails object. + * + * @param details The PosixDetails. + * @return A JDOM PosixDetails representation. + */ + protected final Element getElement(PosixDetails details) + { + Element detailsElement = new Element(UserDetails.NAME); + detailsElement.setAttribute(UserDetails.TYPE_ATTRIBUTE, + PosixDetails.NAME); + + Element uidElement = new Element(PosixDetails.UID); + uidElement.setText(String.valueOf(details.getUid())); + detailsElement.addContent(uidElement); + + Element gidElement = new Element(PosixDetails.GID); + gidElement.setText(String.valueOf(details.getGid())); + detailsElement.addContent(gidElement); + + Element homeDirElement = new Element(PosixDetails.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) + { + Element detailsElement = new Element(UserDetails.NAME); + detailsElement.setAttribute(UserDetails.TYPE_ATTRIBUTE, + PersonalDetails.NAME); + + Element firstNameElement = new Element(PersonalDetails.FIRSTNAME); + firstNameElement.setText(details.getFirstName()); + detailsElement.addContent(firstNameElement); + + Element lastNameElement = new Element(PersonalDetails.LASTNAME); + lastNameElement.setText(details.getLastName()); + detailsElement.addContent(lastNameElement); + + if (details.email != null) + { + Element emailElement = new Element(PersonalDetails.EMAIL); + emailElement.setText(details.email); + detailsElement.addContent(emailElement); + } + + if (details.address != null) + { + Element addressElement = new Element(PersonalDetails.ADDRESS); + addressElement.setText(details.address); + detailsElement.addContent(addressElement); + } + + if (details.institute != null) + { + Element instituteElement = new Element(PersonalDetails.INSTITUTE); + instituteElement.setText(details.institute); + detailsElement.addContent(instituteElement); + } + + if (details.city != null) + { + Element cityElement = new Element(PersonalDetails.CITY); + cityElement.setText(details.city); + detailsElement.addContent(cityElement); + } + + if (details.country != null) + { + Element countryElement = new Element(PersonalDetails.COUNTRY); + countryElement.setText(details.country); + detailsElement.addContent(countryElement); + } + + return detailsElement; + } + + +} diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListReader.java index cd962918..10d46bbe 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListReader.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListReader.java @@ -71,6 +71,10 @@ package ca.nrc.cadc.ac.xml; import ca.nrc.cadc.ac.Group; import ca.nrc.cadc.ac.ReaderException; import ca.nrc.cadc.xml.XmlUtil; +import org.jdom2.Document; +import org.jdom2.Element; +import org.jdom2.JDOMException; + import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -80,15 +84,12 @@ import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; -import org.jdom2.Document; -import org.jdom2.Element; -import org.jdom2.JDOMException; /** - * Class to read an XML representation of a list of Groups - * into a List of Group objects. + * Class to read an XML representation of a List of Groups + * into a Collection of Group objects. */ -public class GroupListReader +public class GroupListReader extends AbstractXML { /** * Construct a list of Group's from an XML String source. @@ -110,7 +111,7 @@ public class GroupListReader } /** - * Construct a list of Group's from a InputStream. + * Construct a List of Group's from a InputStream. * * @param in InputStream. * @return Groups List of Group. @@ -175,20 +176,29 @@ public class GroupListReader throw new ReaderException(error); } - return parseGroups(root); + return getGroupList(root); } - protected static List<Group> parseGroups(Element groupsElement) - throws URISyntaxException, ReaderException - { + /** + * Get a List of Groups from a JDOM element. + * + * @param element The Group's JDOM element. + * @return A List of Group objects. + * @throws URISyntaxException + * @throws ReaderException + */ + protected final List<Group> getGroupList(Element element) + throws URISyntaxException, ReaderException + {; List<Group> groups = new ArrayList<Group>(); - List<Element> groupElements = groupsElement.getChildren("group"); + List<Element> groupElements = element.getChildren("group"); for (Element groupElement : groupElements) { - groups.add(GroupReader.parseGroup(groupElement)); + groups.add(getGroup(groupElement)); } return groups; } + } diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListWriter.java index b3707fb3..e406a4cd 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListWriter.java @@ -1,8 +1,79 @@ +/* +************************************************************************ +******************* 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 +* <http://www.gnu.org/licenses/>. pas le cas, consultez : +* <http://www.gnu.org/licenses/>. +* +* $Revision: 5 $ +* +************************************************************************ +*/ + package ca.nrc.cadc.ac.xml; import ca.nrc.cadc.ac.Group; import ca.nrc.cadc.ac.WriterException; import ca.nrc.cadc.util.StringBuilderWriter; +import org.jdom2.Element; + import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStream; @@ -10,19 +81,15 @@ import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.util.Collection; -import org.jdom2.Document; -import org.jdom2.Element; -import org.jdom2.output.Format; -import org.jdom2.output.XMLOutputter; /** * Class to write a XML representation from a Collection of Groups objects. */ -public class GroupListWriter +public class GroupListWriter extends AbstractXML { /** - * Write a List of Group's to a StringBuilder. - * @param groups List of Group's to write. + * Write a Collection of Group's to a StringBuilder. + * @param groups Collection of Group's to write. * @param builder * @throws java.io.IOException * @throws WriterException @@ -34,9 +101,9 @@ public class GroupListWriter } /** - * Write a List of Group's to an OutputStream. + * Write a Collection of Group's to an OutputStream. * - * @param groups List of Group's to write. + * @param groups Collection of Group's to write. * @param out OutputStream to write to. * @throws IOException if the writer fails to write. * @throws WriterException @@ -57,9 +124,9 @@ public class GroupListWriter } /** - * Write a List of Group's to a Writer. + * Write a Collection of Group's to a Writer. * - * @param groups List of Group's to write. + * @param groups Collection of Group's to write. * @param writer Writer to write to. * @throws IOException if the writer fails to write. * @throws WriterException @@ -72,41 +139,27 @@ public class GroupListWriter throw new WriterException("null groups"); } - write(getGroupsElement(groups), writer); + write(getElement(groups), writer); } /** - * - * @param groups List of Group's to write. - * @return Element of list of Group's. + * Get a JDOM element from a Collection of Group objects. + * + * @param groups Collection of Group's to write. + * @return A JDOM Group list representation. * @throws WriterException */ - public static Element getGroupsElement(Collection<Group> groups) + protected final Element getElement(Collection<Group> groups) throws WriterException { Element groupsElement = new Element("groups"); for (Group group : groups) { - groupsElement.addContent(GroupWriter.getGroupElement(group)); + groupsElement.addContent(getElement(group)); } return groupsElement; } - /** - * 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. - */ - private static void write(Element root, Writer writer) - throws IOException - { - XMLOutputter outputter = new XMLOutputter(); - outputter.setFormat(Format.getPrettyFormat()); - outputter.output(new Document(root), writer); - } - } \ No newline at end of file diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupReader.java index 0f0d1dca..31de44fc 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupReader.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupReader.java @@ -68,11 +68,8 @@ */ package ca.nrc.cadc.ac.xml; -import ca.nrc.cadc.ac.AC; import ca.nrc.cadc.ac.Group; import ca.nrc.cadc.ac.ReaderException; -import ca.nrc.cadc.ac.User; -import ca.nrc.cadc.date.DateUtil; import ca.nrc.cadc.xml.XmlUtil; import org.jdom2.Document; import org.jdom2.Element; @@ -85,15 +82,11 @@ import java.io.Reader; import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; -import java.security.Principal; -import java.text.DateFormat; -import java.text.ParseException; -import java.util.List; /** * Class to read a XML representation of a Group to a Group object. */ -public class GroupReader +public class GroupReader extends AbstractXML { /** @@ -181,128 +174,7 @@ public class GroupReader throw new ReaderException(error); } - return parseGroup(root); + return getGroup(root); } - public static Group parseGroup(Element groupElement) - throws ReaderException - { - String uri = groupElement.getAttributeValue("uri"); - if (uri == null) - { - String error = "group missing required uri attribute"; - throw new ReaderException(error); - } - - // Group groupID - int index = uri.indexOf(AC.GROUP_URI); - if (index == -1) - { - String error = "group uri attribute malformed: " + uri; - throw new ReaderException(error); - } - String groupID = uri.substring(AC.GROUP_URI.length()); - - // Group owner - User<? extends Principal> user = null; - Element ownerElement = groupElement.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 = UserReader.parseUser(userElement); - } - - Group group = new Group(groupID, user); - - // description - Element descriptionElement = groupElement.getChild("description"); - if (descriptionElement != null) - { - group.description = descriptionElement.getText(); - } - - // lastModified - Element lastModifiedElement = groupElement.getChild("lastModified"); - 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 = groupElement.getChild("properties"); - if (propertiesElement != null) - { - List<Element> propertyElements = propertiesElement.getChildren("property"); - for (Element propertyElement : propertyElements) - { - group.getProperties().add(ca.nrc.cadc.ac.xml.GroupPropertyReader.read(propertyElement)); - } - - } - - // groupMembers - Element groupMembersElement = groupElement.getChild("groupMembers"); - if (groupMembersElement != null) - { - List<Element> groupElements = groupMembersElement.getChildren("group"); - for (Element groupMember : groupElements) - { - group.getGroupMembers().add(parseGroup(groupMember)); - } - - } - - // userMembers - Element userMembersElement = groupElement.getChild("userMembers"); - if (userMembersElement != null) - { - List<Element> userElements = userMembersElement.getChildren("user"); - for (Element userMember : userElements) - { - group.getUserMembers().add(UserReader.parseUser(userMember)); - } - } - - // groupAdmins - Element groupAdminsElement = groupElement.getChild("groupAdmins"); - if (groupAdminsElement != null) - { - List<Element> groupElements = groupAdminsElement.getChildren("group"); - for (Element groupMember : groupElements) - { - group.getGroupAdmins().add(parseGroup(groupMember)); - } - - } - - // userAdmins - Element userAdminsElement = groupElement.getChild("userAdmins"); - if (userAdminsElement != null) - { - List<Element> userElements = userAdminsElement.getChildren("user"); - for (Element userMember : userElements) - { - group.getUserAdmins().add(UserReader.parseUser(userMember)); - } - } - - return group; - } } diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupWriter.java index 380ba79a..54eba4f2 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupWriter.java @@ -68,18 +68,9 @@ */ package ca.nrc.cadc.ac.xml; -import ca.nrc.cadc.ac.AC; import ca.nrc.cadc.ac.Group; -import ca.nrc.cadc.ac.GroupProperty; -import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.WriterException; -import ca.nrc.cadc.date.DateUtil; import ca.nrc.cadc.util.StringBuilderWriter; -import org.jdom2.Attribute; -import org.jdom2.Document; -import org.jdom2.Element; -import org.jdom2.output.Format; -import org.jdom2.output.XMLOutputter; import java.io.BufferedWriter; import java.io.IOException; @@ -87,13 +78,11 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; -import java.security.Principal; -import java.text.DateFormat; /** * Class to write a XML representation of a Group object. */ -public class GroupWriter +public class GroupWriter extends AbstractXML { /** * Write a Group to a StringBuilder. @@ -147,129 +136,7 @@ public class GroupWriter throw new WriterException("null group"); } - write(getGroupElement(group), writer); + write(getElement(group), writer); } - /** - * - * @param group - * @return - * @throws WriterException - */ - public static Element getGroupElement(Group group) - throws WriterException - { - return getGroupElement(group, true); - } - - public static Element getGroupElement(Group group, boolean deepCopy) - throws WriterException - { - // Create the root group element. - Element groupElement = new Element("group"); - String groupURI = AC.GROUP_URI + group.getID(); - groupElement.setAttribute(new Attribute("uri", groupURI)); - - // Group owner - if (group.getOwner() != null) - { - Element ownerElement = new Element("owner"); - Element userElement = UserWriter.getUserElement(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("lastModified"); - 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(ca.nrc.cadc.ac.xml.GroupPropertyWriter.write(property)); - } - groupElement.addContent(propertiesElement); - } - - // Group groupMembers. - if ((group.getGroupMembers() != null) && (!group.getGroupMembers().isEmpty())) - { - Element groupMembersElement = new Element("groupMembers"); - for (Group groupMember : group.getGroupMembers()) - { - groupMembersElement.addContent(getGroupElement(groupMember, false)); - } - groupElement.addContent(groupMembersElement); - } - - // Group userMembers - if ((group.getUserMembers() != null) && (!group.getUserMembers().isEmpty())) - { - Element userMembersElement = new Element("userMembers"); - for (User<? extends Principal> userMember : group.getUserMembers()) - { - userMembersElement.addContent(UserWriter.getUserElement(userMember)); - } - groupElement.addContent(userMembersElement); - } - - // Group groupAdmins. - if ((group.getGroupAdmins() != null) && (!group.getGroupAdmins().isEmpty())) - { - Element groupAdminsElement = new Element("groupAdmins"); - for (Group groupMember : group.getGroupAdmins()) - { - groupAdminsElement.addContent(getGroupElement(groupMember, false)); - } - groupElement.addContent(groupAdminsElement); - } - - // Group userAdmins - if ((group.getUserAdmins() != null) && (!group.getUserAdmins().isEmpty())) - { - Element userAdminsElement = new Element("userAdmins"); - for (User<? extends Principal> userMember : group.getUserAdmins()) - { - userAdminsElement.addContent(UserWriter.getUserElement(userMember)); - } - groupElement.addContent(userAdminsElement); - } - } - - return groupElement; - } - - /** - * 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. - */ - private static void write(Element root, Writer writer) - throws IOException - { - XMLOutputter outputter = new XMLOutputter(); - outputter.setFormat(Format.getPrettyFormat()); - outputter.output(new Document(root), writer); - } - } diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListReader.java new file mode 100644 index 00000000..4877e7c2 --- /dev/null +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListReader.java @@ -0,0 +1,204 @@ +/* + ************************************************************************ + ******************* CANADIAN ASTRONOMY DATA CENTRE ******************* + ************** CENTRE CANADIEN DE DONNÉES ASTRONOMIQUES ************** + * + * (c) 2015. (c) 2015. + * 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 + * <http://www.gnu.org/licenses/>. pas le cas, consultez : + * <http://www.gnu.org/licenses/>. + * + * + ************************************************************************ + */ + +package ca.nrc.cadc.ac.xml; + +import ca.nrc.cadc.ac.ReaderException; +import ca.nrc.cadc.ac.User; +import ca.nrc.cadc.xml.XmlUtil; +import org.jdom2.Document; +import org.jdom2.Element; +import org.jdom2.JDOMException; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.io.UnsupportedEncodingException; +import java.net.URISyntaxException; +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; + +/** + * Class to read an XML representation of a List of Users + * into a List of User objects. + */ +public class UserListReader extends AbstractXML +{ + /** + * Construct a List of Users from an XML String source. + * + * @param xml String of the XML. + * @return List of users. + * @throws ReaderException + * @throws java.io.IOException + * @throws java.net.URISyntaxException + */ + public List<User<Principal>> read(String xml) + throws ReaderException, IOException, URISyntaxException + { + if (xml == null) + { + throw new IllegalArgumentException("XML must not be null"); + } + return read(new StringReader(xml)); + } + + /** + * Construct a List of Users from a InputStream. + * + * @param in InputStream. + * @return List of Users. + * @throws ReaderException + * @throws java.io.IOException + * @throws java.net.URISyntaxException + */ + public List<User<Principal>> read(InputStream in) + throws ReaderException, IOException, URISyntaxException + { + if (in == null) + { + throw new IOException("stream closed"); + } + InputStreamReader reader; + try + { + reader = new InputStreamReader(in, "UTF-8"); + } + catch (UnsupportedEncodingException e) + { + throw new RuntimeException("UTF-8 encoding not supported"); + } + return read(reader); + } + + /** + * Construct a List of Users from a Reader. + * + * @param reader Reader. + * @return List of Users. + * @throws ReaderException + * @throws java.io.IOException + * @throws java.net.URISyntaxException + */ + public List<User<Principal>> read(Reader reader) + throws ReaderException, IOException, URISyntaxException + { + if (reader == null) + { + throw new IllegalArgumentException("reader must not be null"); + } + + Document document; + try + { + document = XmlUtil.buildDocument(reader); + } + catch (JDOMException jde) + { + String error = "XML failed validation: " + jde.getMessage(); + throw new ReaderException(error, jde); + } + + Element root = document.getRootElement(); + + String userElemName = root.getName(); + + if (!userElemName.equalsIgnoreCase("users")) + { + String error = "Expected users element, found " + userElemName; + throw new ReaderException(error); + } + + return getUserList(root); + } + + /** + * Get a List of Users from a JDOM element. + * + * @param element The Users JDOM element. + * @return A List of User objects. + * @throws URISyntaxException + * @throws ReaderException + */ + protected final List<User<Principal>> getUserList(Element element) + throws URISyntaxException, ReaderException + { + List<User<Principal>> users = new ArrayList<User<Principal>>(); + + List<Element> userElements = element.getChildren("user"); + for (Element userElement : userElements) + { + users.add(getUser(userElement)); + } + + return users; + } +} diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListWriter.java index f08d4de4..92697e1f 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListWriter.java @@ -68,54 +68,101 @@ package ca.nrc.cadc.ac.xml; -import ca.nrc.cadc.ac.PersonalDetails; -import org.jdom2.Document; +import ca.nrc.cadc.ac.User; +import ca.nrc.cadc.ac.WriterException; +import ca.nrc.cadc.util.StringBuilderWriter; import org.jdom2.Element; -import org.jdom2.output.Format; -import org.jdom2.output.XMLOutputter; +import java.io.BufferedWriter; import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; import java.io.Writer; -import java.util.Map; +import java.security.Principal; +import java.util.Collection; +import java.util.List; /** - * Class to write a XML representation of a Collection of User's. + * Class to write a XML representation of a List of User's. */ -public class UserListWriter +public class UserListWriter extends AbstractXML { /** - * Write the Map of User entries as XML. + * Write a Collection of User's to a StringBuilder. * - * @param users The Map of User IDs to Names. - * @param writer The Writer to output to. - * @throws IOException Any writing errors. + * @param users Collection of User's to write. + * @param builder The StringBuilder. + * @throws java.io.IOException + * @throws WriterException */ - public void write(final Map<String, PersonalDetails> users, - final Writer writer) throws IOException + public <T extends Principal> void write(Collection<User<T>> users, StringBuilder builder) + throws IOException, WriterException { - // Create the root users Element. - final Element usersElement = new Element("users"); + write(users, new StringBuilderWriter(builder)); + } + + /** + * Write a Collection of User's to an OutputStream. + * + * @param users Collection of User's to write. + * @param out OutputStream to write to. + * @throws IOException if the writer fails to write. + * @throws WriterException + */ + public <T extends Principal> void write(Collection<User<T>> users, OutputStream out) + throws IOException, WriterException + { + OutputStreamWriter outWriter; + try + { + outWriter = new OutputStreamWriter(out, "UTF-8"); + } + catch (UnsupportedEncodingException e) + { + throw new RuntimeException("UTF-8 encoding not supported", e); + } + write(users, new BufferedWriter(outWriter)); + } - for (final Map.Entry<String, PersonalDetails> entry : users.entrySet()) + /** + * Write a Collection of Users to a Writer. + * + * @param users Users to write. + * @param writer Writer to write to. + * @throws IOException if the writer fails to write. + * @throws WriterException + */ + public <T extends Principal> void write(Collection<User<T>> users, Writer writer) + throws IOException, WriterException + { + if (users == null) { - final Element userEntryElement = new Element("user"); - final Element firstNameElement = new Element("firstName"); - final Element lastNameElement = new Element("lastName"); + throw new WriterException("null users"); + } - userEntryElement.setAttribute("id", entry.getKey()); + write(getElement(users), writer); + } - firstNameElement.setText(entry.getValue().getFirstName()); - userEntryElement.addContent(firstNameElement); - lastNameElement.setText(entry.getValue().getLastName()); - userEntryElement.addContent(lastNameElement); + /** + * Get a JDOM element from a Collection of User objects. + * + * @param users Collection of User's to write. + * @return A JDOM Group list representation. + * @throws WriterException + */ + protected final <T extends Principal> Element getElement(Collection<User<T>> users) + throws WriterException + { + Element usersElement = new Element("users"); - usersElement.addContent(userEntryElement); + for (User<T> user : users) + { + usersElement.addContent(getElement(user)); } - final XMLOutputter output = new XMLOutputter(); - - output.setFormat(Format.getPrettyFormat()); - output.output(new Document(usersElement), writer); + return usersElement; } + } diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserReader.java index 0accd9da..b4181956 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserReader.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserReader.java @@ -83,16 +83,15 @@ import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; import java.security.Principal; -import java.util.List; /** * Class to read a XML representation of a User to a User object. */ -public class UserReader +public class UserReader extends AbstractXML { /** * Construct a User from an XML String source. - * + * * @param xml String of the XML. * @return User User. * @throws ReaderException @@ -111,7 +110,7 @@ public class UserReader /** * Construct a User from a InputStream. - * + * * @param in InputStream. * @return User User. * @throws java.io.IOException @@ -137,7 +136,7 @@ public class UserReader /** * Construct a User from a Reader. - * + * * @param reader Reader. * @return User User. * @throws ReaderException @@ -166,58 +165,7 @@ public class UserReader // Root element and namespace of the Document Element root = document.getRootElement(); - return parseUser(root); - } - - public static User<Principal> parseUser(Element userElement) - throws ReaderException - { - // userID element of the User element - Element userIDElement = userElement.getChild("userID"); - if (userIDElement == null) - { - String error = "userID element not found in user element"; - throw new ReaderException(error); - } - - // identity element of the userID element - Element userIDIdentityElement = userIDElement.getChild("identity"); - if (userIDIdentityElement == null) - { - String error = "identity element not found in userID element"; - throw new ReaderException(error); - } - - IdentityReader identityReader = new IdentityReader(); - Principal userID = identityReader.read(userIDIdentityElement); - - User<Principal> user = new User<Principal>(userID); - - // identities - Element identitiesElement = userElement.getChild("identities"); - if (identitiesElement != null) - { - List<Element> identityElements = identitiesElement.getChildren("identity"); - for (Element identityElement : identityElements) - { - user.getIdentities().add(identityReader.read(identityElement)); - } - - } - - // details - Element detailsElement = userElement.getChild("details"); - if (detailsElement != null) - { - UserDetailsReader userDetailsReader = new UserDetailsReader(); - List<Element> userDetailsElements = detailsElement.getChildren("userDetails"); - for (Element userDetailsElement : userDetailsElements) - { - user.details.add(userDetailsReader.read(userDetailsElement)); - } - } - - return user; + return getUser(root); } } diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestReader.java index e44eba1e..317d753c 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestReader.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestReader.java @@ -69,9 +69,12 @@ package ca.nrc.cadc.ac.xml; import ca.nrc.cadc.ac.ReaderException; -import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.UserRequest; import ca.nrc.cadc.xml.XmlUtil; +import org.jdom2.Document; +import org.jdom2.Element; +import org.jdom2.JDOMException; + import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -80,14 +83,10 @@ import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.security.Principal; -import org.jdom2.Document; -import org.jdom2.Element; -import org.jdom2.JDOMException; - /** * Class to read a XML representation of a UserRequest to a UserRequest object. */ -public class UserRequestReader +public class UserRequestReader extends AbstractXML { /** * Construct a UserRequest from an XML String source. @@ -164,31 +163,7 @@ public class UserRequestReader // Root element and namespace of the Document Element root = document.getRootElement(); - return parseUserRequest(root); + return getUserRequest(root); } - protected static UserRequest<Principal> parseUserRequest( - Element userRequestElement) - throws ReaderException - { - // user element of the UserRequest element - Element userElement = userRequestElement.getChild("user"); - if (userElement == null) - { - String error = "user element not found in userRequest element"; - throw new ReaderException(error); - } - User<Principal> user = ca.nrc.cadc.ac.xml.UserReader.parseUser(userElement); - - // password element of the userRequest element - Element passwordElement = userRequestElement.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<Principal>(user, password.toCharArray()); - } } diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestWriter.java index fe0ffee9..ef100682 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestWriter.java @@ -72,10 +72,6 @@ package ca.nrc.cadc.ac.xml; import ca.nrc.cadc.ac.UserRequest; import ca.nrc.cadc.ac.WriterException; import ca.nrc.cadc.util.StringBuilderWriter; -import org.jdom2.Document; -import org.jdom2.Element; -import org.jdom2.output.Format; -import org.jdom2.output.XMLOutputter; import java.io.IOException; import java.io.Writer; @@ -84,7 +80,7 @@ import java.security.Principal; /** * Class to write a XML representation of a UserRequest object. */ -public class UserRequestWriter +public class UserRequestWriter extends AbstractXML { /** * Write a UserRequest to a StringBuilder. @@ -94,7 +90,7 @@ public class UserRequestWriter * @throws java.io.IOException if the writer fails to write. * @throws WriterException */ - public void write(UserRequest<? extends Principal> userRequest, StringBuilder builder) + public <T extends Principal> void write(UserRequest<T> userRequest, StringBuilder builder) throws IOException, WriterException { write(userRequest, new StringBuilderWriter(builder)); @@ -108,7 +104,7 @@ public class UserRequestWriter * @throws IOException if the writer fails to write. * @throws WriterException */ - public static void write(UserRequest<? extends Principal> userRequest, Writer writer) + public <T extends Principal> void write(UserRequest<T> userRequest, Writer writer) throws IOException, WriterException { if (userRequest == null) @@ -116,46 +112,7 @@ public class UserRequestWriter throw new WriterException("null UserRequest"); } - write(getUserRequestElement(userRequest), writer); + write(getElement(userRequest), writer); } - /** - * Build the UserRequest element. - * - * @param userRequest UserRequest. - * @return member Element. - * @throws WriterException - */ - public static Element getUserRequestElement(UserRequest<? extends Principal> userRequest) - throws WriterException - { - // Create the userRequest Element. - Element userRequestElement = new Element("userRequest"); - - // user element - Element userElement = UserWriter.getUserElement(userRequest.getUser()); - userRequestElement.addContent(userElement); - - // password element - Element passwordElement = new Element("password"); - passwordElement.setText(String.valueOf(userRequest.getPassword())); - userRequestElement.addContent(passwordElement); - - return userRequestElement; - } - - /** - * 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. - */ - private static void write(Element root, Writer writer) - throws IOException - { - XMLOutputter outputter = new XMLOutputter(); - outputter.setFormat(Format.getPrettyFormat()); - outputter.output(new Document(root), writer); - } } diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserWriter.java index 86327ad8..e2fe3bf8 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserWriter.java @@ -69,13 +69,8 @@ package ca.nrc.cadc.ac.xml; import ca.nrc.cadc.ac.User; -import ca.nrc.cadc.ac.UserDetails; import ca.nrc.cadc.ac.WriterException; import ca.nrc.cadc.util.StringBuilderWriter; -import org.jdom2.Document; -import org.jdom2.Element; -import org.jdom2.output.Format; -import org.jdom2.output.XMLOutputter; import java.io.BufferedWriter; import java.io.IOException; @@ -84,12 +79,11 @@ import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.security.Principal; -import java.util.Set; /** * Class to write a XML representation of a User object. */ -public class UserWriter +public class UserWriter extends AbstractXML { /** * Write a User to a StringBuilder. @@ -99,7 +93,7 @@ public class UserWriter * @throws java.io.IOException if the writer fails to write. * @throws WriterException */ - public void write(User<? extends Principal> user, StringBuilder builder) + public <T extends Principal> void write(User<T> user, StringBuilder builder) throws IOException, WriterException { write(user, new StringBuilderWriter(builder)); @@ -113,7 +107,7 @@ public class UserWriter * @throws IOException if the writer fails to write. * @throws WriterException */ - public void write(User<? extends Principal> user, OutputStream out) + public <T extends Principal> void write(User<T> user, OutputStream out) throws IOException, WriterException { OutputStreamWriter outWriter; @@ -136,7 +130,7 @@ public class UserWriter * @throws IOException if the writer fails to write. * @throws WriterException */ - public void write(User<? extends Principal> user, Writer writer) + public <T extends Principal> void write(User<T> user, Writer writer) throws IOException, WriterException { if (user == null) @@ -144,69 +138,7 @@ public class UserWriter throw new WriterException("null User"); } - write(getUserElement(user), writer); - } - - /** - * Build the member Element of a User. - * - * @param user User. - * @return member Element. - * @throws WriterException - */ - public static Element getUserElement(User<? extends Principal> user) - throws WriterException - { - // Create the user Element. - Element userElement = new Element("user"); - - // userID element - IdentityWriter identityWriter = new IdentityWriter(); - Element userIDElement = new Element("userID"); - userIDElement.addContent(identityWriter.write(user.getUserID())); - userElement.addContent(userIDElement); - - // identities - Set<Principal> identities = user.getIdentities(); - if (!identities.isEmpty()) - { - Element identitiesElement = new Element("identities"); - for (Principal identity : identities) - { - identitiesElement.addContent(identityWriter.write(identity)); - } - userElement.addContent(identitiesElement); - } - - // details - if (!user.details.isEmpty()) - { - UserDetailsWriter userDetailsWriter = new UserDetailsWriter(); - Element detailsElement = new Element("details"); - Set<UserDetails> userDetails = user.details; - for (UserDetails userDetail : userDetails) - { - detailsElement.addContent(userDetailsWriter.write(userDetail)); - } - userElement.addContent(detailsElement); - } - - return userElement; - } - - /** - * 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. - */ - private static void write(Element root, Writer writer) - throws IOException - { - XMLOutputter outputter = new XMLOutputter(); - outputter.setFormat(Format.getPrettyFormat()); - outputter.output(new Document(root), writer); + write(getElement(user), writer); } } diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/JsonUserListReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/JsonUserListReaderWriterTest.java new file mode 100644 index 00000000..44b3922a --- /dev/null +++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/JsonUserListReaderWriterTest.java @@ -0,0 +1,95 @@ +package ca.nrc.cadc.ac.json; + +import ca.nrc.cadc.ac.PersonalDetails; +import ca.nrc.cadc.ac.PosixDetails; +import ca.nrc.cadc.ac.User; +import ca.nrc.cadc.ac.WriterException; +import ca.nrc.cadc.auth.HttpPrincipal; +import ca.nrc.cadc.auth.NumericPrincipal; +import org.apache.log4j.Logger; +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.security.Principal; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +/** + * JsonUserListReaderWriterTest TODO describe class + */ +public class JsonUserListReaderWriterTest +{ + private static Logger log = Logger.getLogger(JsonUserListReaderWriterTest.class); + + @Test + public void testReaderExceptions() + throws Exception + { + try + { + String s = null; + JsonUserListReader reader = new JsonUserListReader(); + List<User<Principal>> u = reader.read(s); + fail("null String should throw IllegalArgumentException"); + } + catch (IllegalArgumentException e) {} + + try + { + InputStream in = null; + JsonUserListReader reader = new JsonUserListReader(); + List<User<Principal>> u = reader.read(in); + fail("null InputStream should throw IOException"); + } + catch (IOException e) {} + + try + { + Reader r = null; + JsonUserListReader reader = new JsonUserListReader(); + List<User<Principal>> u = reader.read(r); + fail("null Reader should throw IllegalArgumentException"); + } + catch (IllegalArgumentException e) {} + } + + @Test + public void testWriterExceptions() + throws Exception + { + try + { + JsonUserWriter writer = new JsonUserWriter(); + writer.write(null, new StringBuilder()); + fail("null User should throw WriterException"); + } + catch (WriterException e) {} + } + + @Test + public void testReadWrite() + throws Exception + { + User<Principal> expected = new User<Principal>(new HttpPrincipal("foo")); + expected.getIdentities().add(new NumericPrincipal(123l)); + expected.details.add(new PersonalDetails("firstname", "lastname")); + expected.details.add(new PosixDetails(123l, 456l, "foo")); + + StringBuilder json = new StringBuilder(); + JsonUserWriter writer = new JsonUserWriter(); + writer.write(expected, json); + assertFalse(json.toString().isEmpty()); + + JsonUserReader reader = new JsonUserReader(); + User<Principal> actual = reader.read(json.toString()); + assertNotNull(actual); + assertEquals(expected, actual); + } + +} diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/JsonUserReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/JsonUserReaderWriterTest.java index dccefe89..7de85967 100644 --- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/JsonUserReaderWriterTest.java +++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/JsonUserReaderWriterTest.java @@ -103,7 +103,7 @@ public class JsonUserReaderWriterTest { String s = null; JsonUserReader reader = new JsonUserReader(); - User<? extends Principal> u = reader.read(s); + User<Principal> u = reader.read(s); fail("null String should throw IllegalArgumentException"); } catch (IllegalArgumentException e) {} @@ -112,7 +112,7 @@ public class JsonUserReaderWriterTest { InputStream in = null; JsonUserReader reader = new JsonUserReader(); - User<? extends Principal> u = reader.read(in); + User<Principal> u = reader.read(in); fail("null InputStream should throw IOException"); } catch (IOException e) {} @@ -121,7 +121,7 @@ public class JsonUserReaderWriterTest { Reader r = null; JsonUserReader reader = new JsonUserReader(); - User<? extends Principal> u = reader.read(r); + User<Principal> u = reader.read(r); fail("null Reader should throw IllegalArgumentException"); } catch (IllegalArgumentException e) {} @@ -144,7 +144,7 @@ public class JsonUserReaderWriterTest public void testReadWrite() throws Exception { - User<Principal> expected = new User<Principal>(new HttpPrincipal("foo")); + User<? extends Principal> expected = new User<Principal>(new HttpPrincipal("foo")); expected.getIdentities().add(new NumericPrincipal(123l)); expected.details.add(new PersonalDetails("firstname", "lastname")); expected.details.add(new PosixDetails(123l, 456l, "foo")); diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupsReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupListReaderWriterTest.java similarity index 98% rename from projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupsReaderWriterTest.java rename to projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupListReaderWriterTest.java index 0281eaf8..a18c13b3 100644 --- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupsReaderWriterTest.java +++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupListReaderWriterTest.java @@ -88,9 +88,9 @@ import static org.junit.Assert.fail; * * @author jburke */ -public class GroupsReaderWriterTest +public class GroupListReaderWriterTest { - private static Logger log = Logger.getLogger(GroupsReaderWriterTest.class); + private static Logger log = Logger.getLogger(GroupListReaderWriterTest.class); @Test public void testReaderExceptions() diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupPropertyReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupPropertyReaderWriterTest.java index 7075c9e1..172d211e 100644 --- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupPropertyReaderWriterTest.java +++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupPropertyReaderWriterTest.java @@ -83,7 +83,7 @@ import static org.junit.Assert.*; * * @author jburke */ -public class GroupPropertyReaderWriterTest +public class GroupPropertyReaderWriterTest extends AbstractXML { private static Logger log = Logger.getLogger(GroupPropertyReaderWriterTest.class); @@ -100,7 +100,7 @@ public class GroupPropertyReaderWriterTest Element element = null; try { - GroupProperty gp = GroupPropertyReader.read(element); + GroupProperty gp = getGroupProperty(element); fail("null element should throw ReaderException"); } catch (ReaderException e) {} @@ -108,7 +108,7 @@ public class GroupPropertyReaderWriterTest element = new Element("foo"); try { - GroupProperty gp = GroupPropertyReader.read(element); + GroupProperty gp = getGroupProperty(element); fail("element not named 'property' should throw ReaderException"); } catch (ReaderException e) {} @@ -116,7 +116,7 @@ public class GroupPropertyReaderWriterTest element = new Element("property"); try { - GroupProperty gp = GroupPropertyReader.read(element); + GroupProperty gp = getGroupProperty(element); fail("element without 'key' attribute should throw ReaderException"); } catch (ReaderException e) {} @@ -124,7 +124,7 @@ public class GroupPropertyReaderWriterTest element.setAttribute("key", "foo"); try { - GroupProperty gp = GroupPropertyReader.read(element); + GroupProperty gp = getGroupProperty(element); fail("element without 'type' attribute should throw ReaderException"); } catch (ReaderException e) {} @@ -132,7 +132,7 @@ public class GroupPropertyReaderWriterTest element.setAttribute("type", "Double"); try { - GroupProperty gp = GroupPropertyReader.read(element); + GroupProperty gp = getGroupProperty(element); fail("Unsupported 'type' should throw ReaderException"); } catch (ReaderException e) {} @@ -144,15 +144,16 @@ public class GroupPropertyReaderWriterTest { try { - Element element = GroupPropertyWriter.write(null); + GroupProperty groupProperty = null; + Element element = getElement(groupProperty); fail("null GroupProperty should throw WriterException"); } catch (WriterException e) {} - GroupProperty gp = new GroupProperty("key", new Double(1.0), true); + GroupProperty groupProperty = new GroupProperty("key", new Double(1.0), true); try { - Element element = GroupPropertyWriter.write(gp); + Element element = getElement(groupProperty); fail("Unsupported GroupProperty type should throw IllegalArgumentException"); } catch (IllegalArgumentException e) {} @@ -164,20 +165,20 @@ public class GroupPropertyReaderWriterTest { // String type GroupProperty expected = new GroupProperty("key", "value", true); - Element element = GroupPropertyWriter.write(expected); + Element element = getElement(expected); assertNotNull(element); - GroupProperty actual = GroupPropertyReader.read(element); + GroupProperty actual = getGroupProperty(element); assertNotNull(actual); assertEquals(expected, actual); // Integer tuype expected = new GroupProperty("key", new Integer(1), false); - element = GroupPropertyWriter.write(expected); + element = getElement(expected); assertNotNull(element); - actual = GroupPropertyReader.read(element); + actual = getGroupProperty(element); assertNotNull(actual); assertEquals(expected, actual); diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/IdentityReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/IdentityReaderWriterTest.java index 58918c8d..7ff46919 100644 --- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/IdentityReaderWriterTest.java +++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/IdentityReaderWriterTest.java @@ -89,7 +89,7 @@ import static org.junit.Assert.fail; * * @author jburke */ -public class IdentityReaderWriterTest +public class IdentityReaderWriterTest extends AbstractXML { private static Logger log = Logger.getLogger(IdentityReaderWriterTest.class); @@ -100,7 +100,7 @@ public class IdentityReaderWriterTest Element element = null; try { - Principal p = IdentityReader.read(element); + Principal p = getPrincipal(element); fail("null element should throw ReaderException"); } catch (ReaderException e) {} @@ -108,7 +108,7 @@ public class IdentityReaderWriterTest element = new Element("foo"); try { - Principal p = IdentityReader.read(element); + Principal p = getPrincipal(element); fail("element not named 'identity' should throw ReaderException"); } catch (ReaderException e) {} @@ -116,7 +116,7 @@ public class IdentityReaderWriterTest element = new Element("identity"); try { - Principal p = IdentityReader.read(element); + Principal p = getPrincipal(element); fail("element without 'type' attribute should throw ReaderException"); } catch (ReaderException e) {} @@ -124,7 +124,7 @@ public class IdentityReaderWriterTest element.setAttribute("type", "foo"); try { - Principal p = IdentityReader.read(element); + Principal p = getPrincipal(element); fail("element with unknown 'type' attribute should throw ReaderException"); } catch (ReaderException e) {} @@ -134,17 +134,18 @@ public class IdentityReaderWriterTest public void testWriterExceptions() throws Exception { + Principal p = null; try { - Element element = IdentityWriter.write(null); + Element element = getElement(p); fail("null Identity should throw WriterException"); } catch (WriterException e) {} - Principal p = new JMXPrincipal("foo"); + p = new JMXPrincipal("foo"); try { - Element element = IdentityWriter.write(p); + Element element = getElement(p); fail("Unsupported Principal type should throw IllegalArgumentException"); } catch (IllegalArgumentException e) {} @@ -156,40 +157,40 @@ public class IdentityReaderWriterTest { // X500 Principal expected = new X500Principal("cn=foo,o=bar"); - Element element = IdentityWriter.write(expected); + Element element = getElement(expected); assertNotNull(element); - Principal actual = IdentityReader.read(element); + Principal actual = getPrincipal(element); assertNotNull(actual); assertEquals(expected, actual); - + // UID expected = new NumericPrincipal(123l); - element = IdentityWriter.write(expected); + element = getElement(expected); assertNotNull(element); - actual = IdentityReader.read(element); + actual = getPrincipal(element); assertNotNull(actual); assertEquals(expected, actual); // OpenID expected = new OpenIdPrincipal("bar"); - element = IdentityWriter.write(expected); + element = getElement(expected); assertNotNull(element); - actual = IdentityReader.read(element); + actual = getPrincipal(element); assertNotNull(actual); assertEquals(expected, actual); // HTTP expected = new HttpPrincipal("baz"); - element = IdentityWriter.write(expected); + element = getElement(expected); assertNotNull(element); - actual = IdentityReader.read(element); + actual = getPrincipal(element); assertNotNull(actual); assertEquals(expected, actual); diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserDetailsReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserDetailsReaderWriterTest.java index a7badabb..3a1baaa1 100644 --- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserDetailsReaderWriterTest.java +++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserDetailsReaderWriterTest.java @@ -85,7 +85,7 @@ import static org.junit.Assert.fail; * * @author jburke */ -public class UserDetailsReaderWriterTest +public class UserDetailsReaderWriterTest extends AbstractXML { private static Logger log = Logger.getLogger(UserDetailsReaderWriterTest.class); @@ -96,7 +96,7 @@ public class UserDetailsReaderWriterTest Element element = null; try { - UserDetails ud = UserDetailsReader.read(element); + UserDetails ud = getUserDetails(element); fail("null element should throw ReaderException"); } catch (ReaderException e) {} @@ -104,7 +104,7 @@ public class UserDetailsReaderWriterTest element = new Element("foo"); try { - UserDetails ud = UserDetailsReader.read(element); + UserDetails ud = getUserDetails(element); fail("element not named 'userDetails' should throw ReaderException"); } catch (ReaderException e) {} @@ -112,7 +112,7 @@ public class UserDetailsReaderWriterTest element = new Element(UserDetails.NAME); try { - UserDetails ud = UserDetailsReader.read(element); + UserDetails ud = getUserDetails(element); fail("element without 'type' attribute should throw ReaderException"); } catch (ReaderException e) {} @@ -120,7 +120,7 @@ public class UserDetailsReaderWriterTest element.setAttribute("type", "foo"); try { - UserDetails ud = UserDetailsReader.read(element); + UserDetails ud = getUserDetails(element); fail("element with unknown 'type' attribute should throw ReaderException"); } catch (ReaderException e) {} @@ -132,7 +132,8 @@ public class UserDetailsReaderWriterTest { try { - Element element = UserDetailsWriter.write(null); + UserDetails ud = null; + Element element = getElement(ud); fail("null UserDetails should throw WriterException"); } catch (WriterException e) {} @@ -148,10 +149,10 @@ public class UserDetailsReaderWriterTest expected.country = "country"; expected.email = "email"; expected.institute = "institute"; - Element element = UserDetailsWriter.write(expected); + Element element = getElement(expected); assertNotNull(element); - PersonalDetails actual = (PersonalDetails) UserDetailsReader.read(element); + PersonalDetails actual = (PersonalDetails) getUserDetails(element); assertNotNull(actual); assertEquals(expected, actual); assertEquals(expected.address, actual.address); @@ -166,10 +167,10 @@ public class UserDetailsReaderWriterTest throws Exception { UserDetails expected = new PosixDetails(123l, 456, "/dev/null"); - Element element = UserDetailsWriter.write(expected); + Element element = getElement(expected); assertNotNull(element); - UserDetails actual = UserDetailsReader.read(element); + UserDetails actual = getUserDetails(element); assertNotNull(actual); assertEquals(expected, actual); } diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserListReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserListReaderWriterTest.java new file mode 100644 index 00000000..ddca58a3 --- /dev/null +++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserListReaderWriterTest.java @@ -0,0 +1,92 @@ +package ca.nrc.cadc.ac.xml; + +import ca.nrc.cadc.ac.User; +import ca.nrc.cadc.ac.WriterException; +import ca.nrc.cadc.auth.HttpPrincipal; +import org.apache.log4j.Logger; +import org.junit.Test; + +import javax.security.auth.x500.X500Principal; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +public class UserListReaderWriterTest +{ + private static Logger log = Logger.getLogger(UserListReaderWriterTest.class); + + @Test + public void testReaderExceptions() + throws Exception + { + try + { + String s = null; + UserListReader UserListReader = new UserListReader(); + List<User<Principal>> u = UserListReader.read(s); + fail("null String should throw IllegalArgumentException"); + } + catch (IllegalArgumentException e) {} + + try + { + InputStream in = null; + UserListReader userListReader = new UserListReader(); + List<User<Principal>> u = userListReader.read(in); + fail("null InputStream should throw IOException"); + } + catch (IOException e) {} + + try + { + Reader r = null; + UserListReader userListReader = new UserListReader(); + List<User<Principal>> u = userListReader.read(r); + fail("null element should throw ReaderException"); + } + catch (IllegalArgumentException e) {} + } + + @Test + public void testWriterExceptions() + throws Exception + { + try + { + UserListWriter userListWriter = new UserListWriter(); + userListWriter.write(null, new StringBuilder()); + fail("null User should throw WriterException"); + } + catch (WriterException e) {} + } + + @Test + public void testMinimalReadWrite() + throws Exception + { + List<User<Principal>> expected = new ArrayList<User<Principal>>(); + expected.add(new User<Principal>(new HttpPrincipal("foo"))); + expected.add(new User<Principal>(new X500Principal("cn=foo,o=bar"))); + + StringBuilder xml = new StringBuilder(); + UserListWriter userListWriter = new UserListWriter(); + userListWriter.write(expected, xml); + assertFalse(xml.toString().isEmpty()); + + UserListReader userListReader = new UserListReader(); + List<User<Principal>> actual = userListReader.read(xml.toString()); + assertNotNull(actual); + assertEquals(expected.size(), actual.size()); + assertEquals(expected.get(0), actual.get(0)); + assertEquals(expected.get(1), actual.get(1)); + } + +} \ No newline at end of file diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserReaderWriterTest.java index 4e8d9f2b..c420e7ca 100644 --- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserReaderWriterTest.java +++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserReaderWriterTest.java @@ -102,7 +102,7 @@ public class UserReaderWriterTest { String s = null; UserReader userReader = new UserReader(); - User<? extends Principal> u = userReader.read(s); + User<Principal> u = userReader.read(s); fail("null String should throw IllegalArgumentException"); } catch (IllegalArgumentException e) {} @@ -111,7 +111,7 @@ public class UserReaderWriterTest { InputStream in = null; UserReader userReader = new UserReader(); - User<? extends Principal> u = userReader.read(in); + User<Principal> u = userReader.read(in); fail("null InputStream should throw IOException"); } catch (IOException e) {} @@ -120,7 +120,7 @@ public class UserReaderWriterTest { Reader r = null; UserReader userReader = new UserReader(); - User<? extends Principal> u = userReader.read(r); + User<Principal> u = userReader.read(r); fail("null Reader should throw IllegalArgumentException"); } catch (IllegalArgumentException e) {} @@ -143,7 +143,7 @@ public class UserReaderWriterTest public void testReadWrite() throws Exception { - User<? extends Principal> expected = new User<Principal>(new HttpPrincipal("foo")); + User<Principal> expected = new User<Principal>(new HttpPrincipal("foo")); expected.getIdentities().add(new NumericPrincipal(123l)); expected.details.add(new PersonalDetails("firstname", "lastname")); -- GitLab