From e76d9f91214d75fab1dba5cd6f50a17c29afce04 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Sun, 20 Jan 2013 21:26:18 +0100 Subject: [PATCH] Implemented XML parsing and writing by using basic Java implementation --- config/PrivilegeModel.xml | 7 + pom.xml | 5 - .../handler/XmlPersistenceHandler.java | 495 +++--------------- .../helper/BootstrapConfigurationHelper.java | 102 +--- .../helper/InitializationHelper.java | 204 -------- .../eitchnet/privilege/helper/XmlHelper.java | 135 +++-- .../internal/PrivilegeContainerModel.java | 167 ++++++ .../eitchnet/privilege/xml/ElementParser.java | 36 ++ .../privilege/xml/ElementParserAdapter.java | 48 ++ .../privilege/xml/InitializationHelper.java | 106 ++++ .../xml/PrivilegeConfigDomWriter.java | 121 +++++ .../xml/PrivilegeConfigSaxReader.java | 183 +++++++ .../xml/PrivilegeModelDomWriter.java | 160 ++++++ .../xml/PrivilegeModelSaxReader.java | 347 ++++++++++++ .../privilege/test/PrivilegeTest.java | 2 +- .../ch/eitchnet/privilege/test/XmlTest.java | 219 ++++++++ 16 files changed, 1580 insertions(+), 757 deletions(-) delete mode 100644 src/main/java/ch/eitchnet/privilege/helper/InitializationHelper.java create mode 100644 src/main/java/ch/eitchnet/privilege/model/internal/PrivilegeContainerModel.java create mode 100644 src/main/java/ch/eitchnet/privilege/xml/ElementParser.java create mode 100644 src/main/java/ch/eitchnet/privilege/xml/ElementParserAdapter.java create mode 100644 src/main/java/ch/eitchnet/privilege/xml/InitializationHelper.java create mode 100644 src/main/java/ch/eitchnet/privilege/xml/PrivilegeConfigDomWriter.java create mode 100644 src/main/java/ch/eitchnet/privilege/xml/PrivilegeConfigSaxReader.java create mode 100644 src/main/java/ch/eitchnet/privilege/xml/PrivilegeModelDomWriter.java create mode 100644 src/main/java/ch/eitchnet/privilege/xml/PrivilegeModelSaxReader.java create mode 100644 src/test/java/ch/eitchnet/privilege/test/XmlTest.java diff --git a/config/PrivilegeModel.xml b/config/PrivilegeModel.xml index 396878bc4..4c788b66e 100644 --- a/config/PrivilegeModel.xml +++ b/config/PrivilegeModel.xml @@ -71,6 +71,13 @@ along with Privilege. If not, see . true + + + + hello + goodbye + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 875dcab4f..2776e6b91 100644 --- a/pom.xml +++ b/pom.xml @@ -81,11 +81,6 @@ 4.10 test - - maven - dom4j - 1.7-20060614 - ch.eitchnet ch.eitchnet.utils diff --git a/src/main/java/ch/eitchnet/privilege/handler/XmlPersistenceHandler.java b/src/main/java/ch/eitchnet/privilege/handler/XmlPersistenceHandler.java index 6ea6fda2e..60d5828c7 100644 --- a/src/main/java/ch/eitchnet/privilege/handler/XmlPersistenceHandler.java +++ b/src/main/java/ch/eitchnet/privilege/handler/XmlPersistenceHandler.java @@ -20,28 +20,22 @@ package ch.eitchnet.privilege.handler; import java.io.File; -import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedList; import java.util.List; -import java.util.Locale; import java.util.Map; -import java.util.Set; -import org.dom4j.DocumentFactory; -import org.dom4j.Element; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ch.eitchnet.privilege.base.PrivilegeException; import ch.eitchnet.privilege.helper.XmlConstants; import ch.eitchnet.privilege.helper.XmlHelper; -import ch.eitchnet.privilege.model.UserState; -import ch.eitchnet.privilege.model.internal.Privilege; import ch.eitchnet.privilege.model.internal.Role; import ch.eitchnet.privilege.model.internal.User; +import ch.eitchnet.privilege.xml.PrivilegeModelDomWriter; +import ch.eitchnet.privilege.xml.PrivilegeModelSaxReader; /** * {@link PersistenceHandler} implementation which reads the configuration from XML files. These configuration is passed @@ -138,120 +132,6 @@ public class XmlPersistenceHandler implements PersistenceHandler { this.roleMapDirty = true; } - /** - * @see ch.eitchnet.privilege.handler.PersistenceHandler#persist() - */ - @Override - public boolean persist() { - - // get models file name - String modelFileName = this.parameterMap.get(XmlConstants.XML_PARAM_MODEL_FILE); - if (modelFileName == null || modelFileName.isEmpty()) { - throw new PrivilegeException("[" + PersistenceHandler.class.getName() + "] Defined parameter " - + XmlConstants.XML_PARAM_MODEL_FILE + " is invalid"); - } - - // get model file - File modelFile = new File(this.modelPath); - boolean modelFileUnchanged = modelFile.exists() && modelFile.lastModified() == this.modelsFileDate; - if (modelFileUnchanged && !this.roleMapDirty && !this.userMapDirty) { - XmlPersistenceHandler.logger - .warn("Not persisting as current file is unchanged and model data is not dirty"); - return false; - } - - DocumentFactory docFactory = DocumentFactory.getInstance(); - - // create root element - Element rootElement = docFactory.createElement(XmlConstants.XML_ROOT_PRIVILEGE_USERS_AND_ROLES); - - // USERS - // build XML DOM of users - List users = XmlPersistenceHandler.toDomUsers(this.userMap); - Element usersElement = docFactory.createElement(XmlConstants.XML_USERS); - for (Element userElement : users) { - usersElement.add(userElement); - } - rootElement.add(usersElement); - - // ROLES - // build XML DOM of roles - List roles = XmlPersistenceHandler.toDomRoles(this.roleMap); - Element rolesElement = docFactory.createElement(XmlConstants.XML_ROLES); - for (Element roleElement : roles) { - rolesElement.add(roleElement); - } - rootElement.add(rolesElement); - - // now write the file - XmlHelper.writeElement(rootElement, modelFile); - - // reset dirty states - this.userMapDirty = false; - this.roleMapDirty = false; - - return true; - } - - /** - * @see ch.eitchnet.privilege.handler.PersistenceHandler#reload() - */ - @Override - public boolean reload() { - - // validate file exists - File modelsFile = new File(this.modelPath); - if (!modelsFile.exists()) { - throw new PrivilegeException("[" + PersistenceHandler.class.getName() + "] Defined parameter " - + XmlConstants.XML_PARAM_MODEL_FILE + " is invalid as models file does not exist at path " - + modelsFile.getAbsolutePath()); - } - - this.roleMap = Collections.synchronizedMap(new HashMap()); - this.userMap = Collections.synchronizedMap(new HashMap()); - - // parse models xml file to XML document - Element modelsRootElement = XmlHelper.parseDocument(modelsFile).getRootElement(); - this.modelsFileDate = modelsFile.lastModified(); - - // ROLES - // get roles element - Element rolesElement = modelsRootElement.element(XmlConstants.XML_ROLES); - // read roles - Map roles = readRoles(rolesElement); - this.roleMap = roles; - - // USERS - // get users element - Element usersElement = modelsRootElement.element(XmlConstants.XML_USERS); - // read users - Map users = readUsers(usersElement); - this.userMap = users; - - this.userMapDirty = false; - this.roleMapDirty = false; - - XmlPersistenceHandler.logger.info("Read " + this.userMap.size() + " Users"); - XmlPersistenceHandler.logger.info("Read " + this.roleMap.size() + " Roles"); - - // validate we have a user with PrivilegeAdmin access - boolean privilegeAdminExists = false; - for (String username : this.userMap.keySet()) { - User user = this.userMap.get(username); - if (user.hasRole(PrivilegeHandler.PRIVILEGE_ADMIN_ROLE)) { - privilegeAdminExists = true; - break; - } - } - - if (!privilegeAdminExists) { - XmlPersistenceHandler.logger.warn("No User with role '" + PrivilegeHandler.PRIVILEGE_ADMIN_ROLE - + "' exists. Privilege modifications will not be possible!"); - } - - return true; - } - /** * @see ch.eitchnet.privilege.handler.PersistenceHandler#initialize(java.util.Map) */ @@ -284,317 +164,94 @@ public class XmlPersistenceHandler implements PersistenceHandler { } /** - * Parses {@link User} objects from their XML representations - * - * @param usersRootElement - * the element containing suer elements - * - * @return the map of converted {@link User} objects + * @see ch.eitchnet.privilege.handler.PersistenceHandler#reload() */ - protected Map readUsers(Element usersRootElement) { + @Override + public boolean reload() { - Map userMap = new HashMap(); - - @SuppressWarnings("unchecked") - List userElements = usersRootElement.elements(XmlConstants.XML_USER); - for (Element userElement : userElements) { - - String userId = userElement.attributeValue(XmlConstants.XML_ATTR_USER_ID); - - String username = userElement.attributeValue(XmlConstants.XML_ATTR_USERNAME); - String password = userElement.attributeValue(XmlConstants.XML_ATTR_PASSWORD); - - String firstname = userElement.element(XmlConstants.XML_FIRSTNAME).getTextTrim(); - String surname = userElement.element(XmlConstants.XML_SURNAME).getTextTrim(); - - UserState userState = UserState.valueOf(userElement.element(XmlConstants.XML_STATE).getTextTrim()); - - // TODO better parsing needed - String localeName = userElement.element(XmlConstants.XML_LOCALE).getTextTrim(); - Locale locale = new Locale(localeName); - - // read roles - Element rolesElement = userElement.element(XmlConstants.XML_ROLES); - @SuppressWarnings("unchecked") - List rolesElementList = rolesElement.elements(XmlConstants.XML_ROLE); - Set roles = new HashSet(); - for (Element roleElement : rolesElementList) { - String roleName = roleElement.getTextTrim(); - if (roleName.isEmpty()) { - XmlPersistenceHandler.logger.error("User " + username - + " has a role defined with no name, Skipped."); - } else if (!this.roleMap.containsKey(roleName)) { - XmlPersistenceHandler.logger.error("User " + username + " has a inexistant role " + roleName - + ", Skipped."); - } else { - roles.add(roleName); - } - } - - // read properties - Element propertiesElement = userElement.element(XmlConstants.XML_PROPERTIES); - Map propertyMap = XmlPersistenceHandler.convertToPropertyMap(propertiesElement); - - // create user - User user = new User(userId, username, password, firstname, surname, userState, roles, locale, propertyMap); - - // put user in map - userMap.put(username, user); - XmlPersistenceHandler.logger.info("Loaded user " + user); + // validate file exists + File modelsFile = new File(this.modelPath); + if (!modelsFile.exists()) { + throw new PrivilegeException("[" + PersistenceHandler.class.getName() + "] Defined parameter " + + XmlConstants.XML_PARAM_MODEL_FILE + " is invalid as models file does not exist at path " + + modelsFile.getAbsolutePath()); } - return userMap; + this.roleMap = Collections.synchronizedMap(new HashMap()); + this.userMap = Collections.synchronizedMap(new HashMap()); + + // parse models xml file to XML document + PrivilegeModelSaxReader xmlHandler = new PrivilegeModelSaxReader(); + XmlHelper.parseDocument(modelsFile, xmlHandler); + + this.modelsFileDate = modelsFile.lastModified(); + + // ROLES + List roles = xmlHandler.getRoles(); + for (Role role : roles) { + this.roleMap.put(role.getName(), role); + } + + // USERS + List users = xmlHandler.getUsers(); + for (User user : users) { + this.userMap.put(user.getUsername(), user); + } + + this.userMapDirty = false; + this.roleMapDirty = false; + + XmlPersistenceHandler.logger.info("Read " + this.userMap.size() + " Users"); + XmlPersistenceHandler.logger.info("Read " + this.roleMap.size() + " Roles"); + + // validate we have a user with PrivilegeAdmin access + boolean privilegeAdminExists = false; + for (String username : this.userMap.keySet()) { + User user = this.userMap.get(username); + if (user.hasRole(PrivilegeHandler.PRIVILEGE_ADMIN_ROLE)) { + privilegeAdminExists = true; + break; + } + } + + if (!privilegeAdminExists) { + XmlPersistenceHandler.logger.warn("No User with role '" + PrivilegeHandler.PRIVILEGE_ADMIN_ROLE + + "' exists. Privilege modifications will not be possible!"); + } + + return true; } /** - * Parses {@link Role} objects from their XML representations - * - * @param rolesRootElement - * the element containing role elements - * - * @return the map of converted {@link Role} objects + * @see ch.eitchnet.privilege.handler.PersistenceHandler#persist() */ - protected Map readRoles(Element rolesRootElement) { + @Override + public boolean persist() { - Map roleMap = new HashMap(); - - @SuppressWarnings("unchecked") - List roleElements = rolesRootElement.elements(XmlConstants.XML_ROLE); - for (Element roleElement : roleElements) { - - String roleName = roleElement.attributeValue(XmlConstants.XML_ATTR_NAME); - - Map privilegeMap = readPrivileges(roleElement); - - Role role = new Role(roleName, privilegeMap); - roleMap.put(roleName, role); + // get models file name + String modelFileName = this.parameterMap.get(XmlConstants.XML_PARAM_MODEL_FILE); + if (modelFileName == null || modelFileName.isEmpty()) { + throw new PrivilegeException("[" + PersistenceHandler.class.getName() + "] Defined parameter " + + XmlConstants.XML_PARAM_MODEL_FILE + " is invalid"); } - return roleMap; - } - - /** - * Parses {@link Privilege} objects from their XML representation to their objects - * - * @param roleParentElement - * the parent on which the Privilege XML elements are - * - * @return the map of {@link Privilege} objects - */ - protected Map readPrivileges(Element roleParentElement) { - - Map privilegeMap = new HashMap(); - - @SuppressWarnings("unchecked") - List privilegeElements = roleParentElement.elements(XmlConstants.XML_PRIVILEGE); - for (Element privilegeElement : privilegeElements) { - - String privilegeName = privilegeElement.attributeValue(XmlConstants.XML_ATTR_NAME); - String privilegePolicy = privilegeElement.attributeValue(XmlConstants.XML_ATTR_POLICY); - - Element allAllowedE = privilegeElement.element(XmlConstants.XML_ALL_ALLOWED); - boolean allAllowed = false; - if (allAllowedE != null) { - allAllowed = Boolean.valueOf(allAllowedE.getTextTrim()).booleanValue(); - } - - @SuppressWarnings("unchecked") - List denyElements = privilegeElement.elements(XmlConstants.XML_DENY); - Set denyList = new HashSet(denyElements.size()); - for (Element denyElement : denyElements) { - String denyValue = denyElement.getTextTrim(); - if (!denyValue.isEmpty()) - denyList.add(denyValue); - } - - @SuppressWarnings("unchecked") - List allowElements = privilegeElement.elements(XmlConstants.XML_ALLOW); - Set allowList = new HashSet(allowElements.size()); - for (Element allowElement : allowElements) { - String allowValue = allowElement.getTextTrim(); - if (!allowValue.isEmpty()) - allowList.add(allowValue); - } - - Privilege privilege = new Privilege(privilegeName, privilegePolicy, allAllowed, denyList, allowList); - privilegeMap.put(privilegeName, privilege); + // get model file + File modelFile = new File(this.modelPath); + boolean modelFileUnchanged = modelFile.exists() && modelFile.lastModified() == this.modelsFileDate; + if (modelFileUnchanged && !this.roleMapDirty && !this.userMapDirty) { + XmlPersistenceHandler.logger + .warn("Not persisting as current file is unchanged and model data is not dirty"); + return false; } - return privilegeMap; - } + // delegate writing + PrivilegeModelDomWriter modelWriter = new PrivilegeModelDomWriter(getAllUsers(), getAllRoles(), modelFile); + modelWriter.write(); - /** - * Converts {@link User} objects to their XML representations - * - * @param userMap - * the map of users to convert - * - * @return the list of XML User elements - */ - protected static List toDomUsers(Map userMap) { + // reset dirty states + this.userMapDirty = false; + this.roleMapDirty = false; - List usersAsElements = new ArrayList(userMap.size()); - - DocumentFactory documentFactory = DocumentFactory.getInstance(); - - synchronized (userMap) { - for (String userName : userMap.keySet()) { - - // get the user object - User user = userMap.get(userName); - - // create the user element - Element userElement = documentFactory.createElement(XmlConstants.XML_USER); - userElement.addAttribute(XmlConstants.XML_ATTR_USER_ID, user.getUserId()); - userElement.addAttribute(XmlConstants.XML_ATTR_USERNAME, user.getUsername()); - userElement.addAttribute(XmlConstants.XML_ATTR_PASSWORD, user.getPassword()); - - // add first name element - Element firstnameElement = documentFactory.createElement(XmlConstants.XML_FIRSTNAME); - firstnameElement.setText(user.getFirstname()); - userElement.add(firstnameElement); - - // add surname element - Element surnameElement = documentFactory.createElement(XmlConstants.XML_SURNAME); - surnameElement.setText(user.getSurname()); - userElement.add(surnameElement); - - // add state element - Element stateElement = documentFactory.createElement(XmlConstants.XML_STATE); - stateElement.setText(user.getUserState().toString()); - userElement.add(stateElement); - - // add locale element - Element localeElement = documentFactory.createElement(XmlConstants.XML_LOCALE); - localeElement.setText(user.getLocale().toString()); - userElement.add(localeElement); - - // add all the role elements - Element rolesElement = documentFactory.createElement(XmlConstants.XML_ROLES); - userElement.add(rolesElement); - for (String roleName : user.getRoles()) { - Element roleElement = documentFactory.createElement(XmlConstants.XML_ROLE); - roleElement.setText(roleName); - rolesElement.add(roleElement); - } - - // add element to return list - usersAsElements.add(userElement); - } - } - - return usersAsElements; - } - - /** - * Converts {@link Role} objects to their XML representations - * - * @param roleMap - * the roles to convert - * - * @return the list of XML Role elements - */ - protected static List toDomRoles(Map roleMap) { - - List rolesAsElements = new ArrayList(roleMap.size()); - - DocumentFactory documentFactory = DocumentFactory.getInstance(); - - synchronized (roleMap) { - for (String roleName : roleMap.keySet()) { - - // get the role object - Role role = roleMap.get(roleName); - - // create the role element - Element roleElement = documentFactory.createElement(XmlConstants.XML_ROLE); - roleElement.addAttribute(XmlConstants.XML_ATTR_NAME, role.getName()); - - // add all the privileges - XmlPersistenceHandler.toDomPrivileges(roleElement, role.getPrivilegeMap()); - - // add element to return list - rolesAsElements.add(roleElement); - } - } - - return rolesAsElements; - } - - /** - * Converts {@link Privilege} objects to their XML representation - * - * @param roleParentElement - * the XML element of the parent {@link Role} - * @param privilegeMap - * the map of {@link Privilege}s to convert - */ - protected static void toDomPrivileges(Element roleParentElement, Map privilegeMap) { - - DocumentFactory documentFactory = DocumentFactory.getInstance(); - - for (Privilege privilege : privilegeMap.values()) { - - // create the privilege element - Element privilegeElement = documentFactory.createElement(XmlConstants.XML_PRIVILEGE); - privilegeElement.addAttribute(XmlConstants.XML_ATTR_NAME, privilege.getName()); - privilegeElement.addAttribute(XmlConstants.XML_ATTR_POLICY, privilege.getPolicy()); - - // add the all allowed element - Element allAllowedElement = documentFactory.createElement(XmlConstants.XML_ALL_ALLOWED); - allAllowedElement.setText(Boolean.toString(privilege.isAllAllowed())); - privilegeElement.add(allAllowedElement); - - // add all the deny values - for (String denyValue : privilege.getDenyList()) { - Element denyValueElement = documentFactory.createElement(XmlConstants.XML_DENY); - denyValueElement.setText(denyValue); - privilegeElement.add(denyValueElement); - } - - // add all the allow values - for (String allowValue : privilege.getAllowList()) { - Element allowValueElement = documentFactory.createElement(XmlConstants.XML_ALLOW); - allowValueElement.setText(allowValue); - privilegeElement.add(allowValueElement); - } - - // add element to parent - roleParentElement.add(privilegeElement); - } - } - - /** - * Converts an {@link XmlConstants#XML_PROPERTIES} element containing {@link XmlConstants#XML_PROPERTY} elements to - * a {@link Map} of String key/value pairs - * - * @param element - * the XML {@link Element} with name {@link XmlConstants#XML_PROPERTIES} containing - * {@link XmlConstants#XML_PROPERTY} elements - * - * @return the {@link Map} of the property name/value combinations from the given {@link Element} - */ - @SuppressWarnings("unchecked") - protected static Map convertToPropertyMap(Element element) { - - // if element is null then there are no properties, so return empty map - if (element == null) - return Collections.emptyMap(); - - List elements = element.elements(XmlConstants.XML_PROPERTY); - - // if elements is null or empty then there are no properties, so return empty map - if (elements == null || elements.isEmpty()) - return Collections.emptyMap(); - - Map propertyMap = new HashMap(); - - for (Element property : elements) { - String name = property.attributeValue(XmlConstants.XML_ATTR_NAME); - String value = property.attributeValue(XmlConstants.XML_ATTR_VALUE); - propertyMap.put(name, value); - } - - return propertyMap; + return true; } } diff --git a/src/main/java/ch/eitchnet/privilege/helper/BootstrapConfigurationHelper.java b/src/main/java/ch/eitchnet/privilege/helper/BootstrapConfigurationHelper.java index 9f9bde839..56970e63b 100644 --- a/src/main/java/ch/eitchnet/privilege/helper/BootstrapConfigurationHelper.java +++ b/src/main/java/ch/eitchnet/privilege/helper/BootstrapConfigurationHelper.java @@ -20,12 +20,12 @@ package ch.eitchnet.privilege.helper; import java.io.File; - -import org.dom4j.Document; -import org.dom4j.DocumentFactory; -import org.dom4j.Element; +import java.util.HashMap; +import java.util.Map; import ch.eitchnet.privilege.handler.PrivilegeHandler; +import ch.eitchnet.privilege.model.internal.PrivilegeContainerModel; +import ch.eitchnet.privilege.xml.PrivilegeConfigDomWriter; /** *

@@ -46,7 +46,7 @@ import ch.eitchnet.privilege.handler.PrivilegeHandler; */ public class BootstrapConfigurationHelper { - // private static final Logger logger = LoggerFactory.getLogger(BootstrapConfigurationHelper.class); + // private static final Logger logger = Loggerdoc.getLogger(BootstrapConfigurationHelper.class); private static String path; @@ -81,81 +81,29 @@ public class BootstrapConfigurationHelper { throw new RuntimeException("Could not create path " + pathF.getAbsolutePath()); } + Map parameterMap = new HashMap(); + Map encryptionHandlerParameterMap = new HashMap(); + Map persistenceHandlerParameterMap = new HashMap(); + // TODO ask other questions... + parameterMap.put("autoPersistOnPasswordChange", "true"); + encryptionHandlerParameterMap.put("hashAlgorithm", "SHA-256"); + persistenceHandlerParameterMap.put("basePath", "./target/test"); + persistenceHandlerParameterMap.put("modelXmlFile", "PrivilegeModel.xml"); + + PrivilegeContainerModel containerModel = new PrivilegeContainerModel(); + containerModel.setParameterMap(parameterMap); + containerModel.setEncryptionHandlerClassName(defaultEncryptionHandler); + containerModel.setEncryptionHandlerParameterMap(encryptionHandlerParameterMap); + containerModel.setPersistenceHandlerClassName(defaultPersistenceHandler); + containerModel.setPersistenceHandlerParameterMap(persistenceHandlerParameterMap); + + containerModel.addPolicy("DefaultPrivilege", "ch.eitchnet.privilege.policy.DefaultPrivilege"); // now perform work: - BootstrapConfigurationHelper.createXmlPrivilegeContainer(); - BootstrapConfigurationHelper.createPolicyConfiguration(); - BootstrapConfigurationHelper.createModel(); - } - - /** - * - */ - private static void createModel() { - // TODO Auto-generated method stub - - } - - /** - * - */ - private static void createPolicyConfiguration() { - // TODO Auto-generated method stub - - } - - /** - * - */ - private static void createXmlPrivilegeContainer() { - - // create document root - DocumentFactory factory = DocumentFactory.getInstance(); - Document doc = factory.createDocument(XmlHelper.DEFAULT_ENCODING); - doc.setName(XmlConstants.XML_ROOT_PRIVILEGE); - Element rootElement = factory.createElement(XmlConstants.XML_ROOT_PRIVILEGE); - doc.setRootElement(rootElement); - - Element containerElement = factory.createElement(XmlConstants.XML_CONTAINER); - - Element parameterElement; - Element parametersElement; - - // create PersistenceHandler - Element persistenceHandlerElem = factory.createElement(XmlConstants.XML_HANDLER_PERSISTENCE); - containerElement.add(persistenceHandlerElem); - persistenceHandlerElem.addAttribute(XmlConstants.XML_ATTR_CLASS, - BootstrapConfigurationHelper.defaultPersistenceHandler); - parametersElement = factory.createElement(XmlConstants.XML_PARAMETERS); - persistenceHandlerElem.add(parametersElement); - // Parameter basePath - parameterElement = factory.createElement(XmlConstants.XML_PARAMETER); - parameterElement.addAttribute(XmlConstants.XML_ATTR_NAME, XmlConstants.XML_PARAM_BASE_PATH); - parameterElement.addAttribute(XmlConstants.XML_ATTR_VALUE, BootstrapConfigurationHelper.basePath); - parametersElement.add(parameterElement); - // Parameter modelXmlFile - parameterElement = factory.createElement(XmlConstants.XML_PARAMETER); - parameterElement.addAttribute(XmlConstants.XML_ATTR_NAME, XmlConstants.XML_PARAM_MODEL_FILE); - parameterElement.addAttribute(XmlConstants.XML_ATTR_VALUE, BootstrapConfigurationHelper.modelFileName); - parametersElement.add(parameterElement); - - // create EncryptionHandler - Element encryptionHandlerElem = factory.createElement(XmlConstants.XML_HANDLER_ENCRYPTION); - containerElement.add(encryptionHandlerElem); - encryptionHandlerElem.addAttribute(XmlConstants.XML_ATTR_CLASS, - BootstrapConfigurationHelper.defaultEncryptionHandler); - parametersElement = factory.createElement(XmlConstants.XML_PARAMETERS); - encryptionHandlerElem.add(parametersElement); - // Parameter hashAlgorithm - parameterElement = factory.createElement(XmlConstants.XML_PARAMETER); - parameterElement.addAttribute(XmlConstants.XML_ATTR_NAME, XmlConstants.XML_PARAM_HASH_ALGORITHM); - parameterElement.addAttribute(XmlConstants.XML_ATTR_VALUE, BootstrapConfigurationHelper.hashAlgorithm); - parametersElement.add(parameterElement); - - // write the container file to disk - File privilegeContainerFile = new File(BootstrapConfigurationHelper.path + "/" + File configFile = new File(BootstrapConfigurationHelper.path + "/" + BootstrapConfigurationHelper.defaultPrivilegeContainerXmlFile); - XmlHelper.writeDocument(doc, privilegeContainerFile); + PrivilegeConfigDomWriter configSaxWriter = new PrivilegeConfigDomWriter(containerModel, configFile); + configSaxWriter.write(); } } diff --git a/src/main/java/ch/eitchnet/privilege/helper/InitializationHelper.java b/src/main/java/ch/eitchnet/privilege/helper/InitializationHelper.java deleted file mode 100644 index 401cdb5fd..000000000 --- a/src/main/java/ch/eitchnet/privilege/helper/InitializationHelper.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2010 - 2012 - * - * This file is part of Privilege. - * - * Privilege is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Privilege is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Privilege. If not, see . - * - */ -package ch.eitchnet.privilege.helper; - -import java.io.File; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.dom4j.Element; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import ch.eitchnet.privilege.base.PrivilegeException; -import ch.eitchnet.privilege.handler.DefaultPrivilegeHandler; -import ch.eitchnet.privilege.handler.EncryptionHandler; -import ch.eitchnet.privilege.handler.PersistenceHandler; -import ch.eitchnet.privilege.handler.PrivilegeHandler; -import ch.eitchnet.privilege.policy.PrivilegePolicy; -import ch.eitchnet.utils.helper.StringHelper; - -/** - * This class implements the initializing of the {@link PrivilegeHandler} by loading an XML file containing the - * configuration - * - * @author Robert von Burg - */ -public class InitializationHelper { - - private static final Logger logger = LoggerFactory.getLogger(InitializationHelper.class); - - /** - * Initializes the {@link DefaultPrivilegeHandler} from the configuration file - * - * @param privilegeXmlFile - * a {@link File} reference to the XML file containing the configuration for Privilege - * - * @return the {@link PrivilegeHandler} instance loaded from the configuration file - */ - public static PrivilegeHandler initializeFromXml(File privilegeXmlFile) { - - // make sure file exists - if (!privilegeXmlFile.exists()) { - throw new PrivilegeException("Privilege file does not exist at path " + privilegeXmlFile.getAbsolutePath()); - } - - // parse container xml file to XML document - Element rootElement = XmlHelper.parseDocument(privilegeXmlFile).getRootElement(); - Element containerElement = rootElement.element(XmlConstants.XML_CONTAINER); - - // instantiate encryption handler - Element encryptionHandlerElement = containerElement.element(XmlConstants.XML_HANDLER_ENCRYPTION); - String encryptionHandlerClassName = encryptionHandlerElement.attributeValue(XmlConstants.XML_ATTR_CLASS); - EncryptionHandler encryptionHandler = ClassHelper.instantiateClass(encryptionHandlerClassName); - - // instantiate persistence handler - Element persistenceHandlerElement = containerElement.element(XmlConstants.XML_HANDLER_PERSISTENCE); - String persistenceHandlerClassName = persistenceHandlerElement.attributeValue(XmlConstants.XML_ATTR_CLASS); - PersistenceHandler persistenceHandler = ClassHelper.instantiateClass(persistenceHandlerClassName); - - // instantiate privilege handler - DefaultPrivilegeHandler privilegeHandler = new DefaultPrivilegeHandler(); - - // get policies - Element policiesElement = rootElement.element(XmlConstants.XML_POLICIES); - Map> policyMap = InitializationHelper.convertToPolicyMap(policiesElement); - - try { - - // get parameters - Element parameterElement = encryptionHandlerElement.element(XmlConstants.XML_PARAMETERS); - Map parameterMap = InitializationHelper.convertToParameterMap(parameterElement); - - // initialize encryption handler - encryptionHandler.initialize(parameterMap); - - } catch (Exception e) { - InitializationHelper.logger.error(e.getMessage(), e); - throw new PrivilegeException("EncryptionHandler " + encryptionHandlerClassName - + " could not be initialized"); - } - - try { - - // get parameters - Element parameterElement = persistenceHandlerElement.element(XmlConstants.XML_PARAMETERS); - Map parameterMap = InitializationHelper.convertToParameterMap(parameterElement); - - // initialize persistence handler - persistenceHandler.initialize(parameterMap); - - } catch (Exception e) { - InitializationHelper.logger.error(e.getMessage(), e); - throw new PrivilegeException("PersistenceHandler " + persistenceHandlerElement - + " could not be initialized"); - } - - try { - - // get parameters - Element parameterElement = containerElement.element(XmlConstants.XML_PARAMETERS); - Map parameterMap = InitializationHelper.convertToParameterMap(parameterElement); - - // initialize privilege handler - privilegeHandler.initialize(parameterMap, encryptionHandler, persistenceHandler, policyMap); - - } catch (Exception e) { - InitializationHelper.logger.error(e.getMessage(), e); - throw new PrivilegeException("PrivilegeHandler " + privilegeHandler.getClass().getName() - + " could not be initialized"); - } - - return privilegeHandler; - } - - /** - * Converts an {@link XmlConstants#XML_PARAMETERS} element containing {@link XmlConstants#XML_PARAMETER} elements to - * a {@link Map} of String key/value pairs - * - * @param element - * the XML {@link Element} with name {@link XmlConstants#XML_PARAMETERS} containing - * {@link XmlConstants#XML_PARAMETER} elements - * - * @return the {@link Map} of the parameter name/value combinations from the given {@link Element} - */ - @SuppressWarnings("unchecked") - public static Map convertToParameterMap(Element element) { - - // if element is null then there are no parameters, so return empty map - if (element == null) - return Collections.emptyMap(); - - List elements = element.elements(XmlConstants.XML_PARAMETER); - - // if elements is null or empty then there are no parameters, so return empty map - if (elements == null || elements.isEmpty()) - return Collections.emptyMap(); - - Map parameterMap = new HashMap(); - - for (Element parameter : elements) { - String name = parameter.attributeValue(XmlConstants.XML_ATTR_NAME); - String value = parameter.attributeValue(XmlConstants.XML_ATTR_VALUE); - - // replace any defined system properties - value = StringHelper.replaceSystemPropertiesIn(value); - - parameterMap.put(name, value); - } - - return parameterMap; - } - - /** - * Converts an {@link XmlConstants#XML_POLICIES} element containing {@link XmlConstants#XML_POLICY} elements to a - * {@link Map} of String/Class pairs - * - * @param element - * the XML {@link Element} with name {@link XmlConstants#XML_POLICIES} containing - * {@link XmlConstants#XML_POLICY} elements - * - * @return the {@link Map} of the policy name/class combinations from the given {@link Element} - */ - @SuppressWarnings("unchecked") - public static Map> convertToPolicyMap(Element element) { - - Map> policyMap = new HashMap>(); - - List policyElements = element.elements(XmlConstants.XML_POLICY); - for (Element policyElement : policyElements) { - String policyName = policyElement.attributeValue(XmlConstants.XML_ATTR_NAME); - String policyClass = policyElement.attributeValue(XmlConstants.XML_ATTR_CLASS); - - Class clazz; - try { - clazz = ClassHelper.loadClass(policyClass); - } catch (PrivilegeException e) { - throw new PrivilegeException("The Policy with name " + policyName + " does not exist", e); - } - - policyMap.put(policyName, clazz); - } - - return policyMap; - } -} diff --git a/src/main/java/ch/eitchnet/privilege/helper/XmlHelper.java b/src/main/java/ch/eitchnet/privilege/helper/XmlHelper.java index 900c8ca87..c3507efea 100644 --- a/src/main/java/ch/eitchnet/privilege/helper/XmlHelper.java +++ b/src/main/java/ch/eitchnet/privilege/helper/XmlHelper.java @@ -20,24 +20,30 @@ package ch.eitchnet.privilege.helper; import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import org.dom4j.Document; -import org.dom4j.DocumentException; -import org.dom4j.DocumentFactory; -import org.dom4j.Element; -import org.dom4j.io.OutputFormat; -import org.dom4j.io.SAXReader; -import org.dom4j.io.XMLWriter; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; import ch.eitchnet.privilege.base.PrivilegeException; +import ch.eitchnet.utils.exceptions.XmlException; /** * Helper class for performing XML based tasks using Dom4J @@ -61,22 +67,22 @@ public class XmlHelper { * * @return a {@link Document} object containing the dom4j {@link Element}s of the XML file */ - public static Document parseDocument(File xmlFile) { + public static void parseDocument(File xmlFile, DefaultHandler xmlHandler) { try { - InputStream inStream = new FileInputStream(xmlFile); + SAXParserFactory spf = SAXParserFactory.newInstance(); - SAXReader reader = new SAXReader(); - Document document = reader.read(inStream); + SAXParser sp = spf.newSAXParser(); + XmlHelper.logger.info("Parsing XML document " + xmlFile.getAbsolutePath()); + sp.parse(xmlFile, xmlHandler); - XmlHelper.logger.info("Read XML document " + document.getRootElement().getName()); - return document; - - } catch (FileNotFoundException e) { - throw new PrivilegeException("The XML file does not exist or is not readable: " + xmlFile.getAbsolutePath()); - } catch (DocumentException e) { - throw new PrivilegeException("the XML file " + xmlFile.getAbsolutePath() + " is not parseable:", e); + } catch (ParserConfigurationException e) { + throw new PrivilegeException("Failed to initialize a SAX Parser: " + e.getLocalizedMessage(), e); + } catch (SAXException e) { + throw new PrivilegeException("The XML file " + xmlFile.getAbsolutePath() + " is not parseable:", e); + } catch (IOException e) { + throw new PrivilegeException("The XML could not be read: " + xmlFile.getAbsolutePath()); } } @@ -87,40 +93,40 @@ public class XmlHelper { * the {@link Document} to write to the file system * @param file * the {@link File} describing the path on the file system where the XML file should be written to + * + * @throws RuntimeException + * if something went wrong while creating the XML configuration, or writing the element */ - public static void writeDocument(Document document, File file) { + public static void writeDocument(Document document, File file) throws RuntimeException { - XmlHelper.logger.info("Exporting document element " + document.getName() + " to " + file.getAbsolutePath()); - - OutputStream fileOutputStream = null; + XmlHelper.logger.info("Exporting document element " + document.getNodeName() + " to " + file.getAbsolutePath()); try { - fileOutputStream = new FileOutputStream(file); - - String aEncodingScheme = document.getXMLEncoding(); - if (aEncodingScheme == null || aEncodingScheme.isEmpty()) { - aEncodingScheme = XmlHelper.DEFAULT_ENCODING; + String encoding = document.getInputEncoding(); + if (encoding == null || encoding.isEmpty()) { + encoding = XmlHelper.DEFAULT_ENCODING; } - OutputFormat outformat = OutputFormat.createPrettyPrint(); - outformat.setEncoding(aEncodingScheme); - XMLWriter writer = new XMLWriter(fileOutputStream, outformat); - writer.write(document); - writer.flush(); + + // Set up a transformer + TransformerFactory transfac = TransformerFactory.newInstance(); + Transformer transformer = transfac.newTransformer(); + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); + transformer.setOutputProperty(OutputKeys.ENCODING, encoding); + transformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2"); + //transformer.setOutputProperty("{http://xml.apache.org/xalan}line-separator", "\t"); + + // Transform to file + StreamResult result = new StreamResult(file); + Source xmlSource = new DOMSource(document); + transformer.transform(xmlSource, result); } catch (Exception e) { throw new PrivilegeException("Exception while exporting to file: " + e, e); - } finally { - - if (fileOutputStream != null) { - try { - fileOutputStream.close(); - } catch (IOException e) { - XmlHelper.logger.error("Could not close file output stream: " + e, e); - } - } } } @@ -131,13 +137,40 @@ public class XmlHelper { * the {@link Element} to write to the file system * @param file * the {@link File} describing the path on the file system where the XML file should be written to + * @param encoding + * encoding to use to write the file + * + * @throws RuntimeException + * if something went wrong while creating the XML configuration, or writing the element */ - public static void writeElement(Element rootElement, File file) { - - Document document = DocumentFactory.getInstance().createDocument(XmlHelper.DEFAULT_ENCODING); - document.setRootElement(rootElement); - document.setName(rootElement.getName()); + public static void writeElement(Element rootElement, File file, String encoding) throws RuntimeException { + Document document = createDocument(); + document.appendChild(rootElement); XmlHelper.writeDocument(document, file); } + + /** + * Returns a new document instance + * + * @return a new document instance + * + * @throws RuntimeException + * if something went wrong while creating the XML configuration + */ + public static Document createDocument() throws RuntimeException { + try { + + DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbfac.newDocumentBuilder(); + Document document = docBuilder.newDocument(); + + return document; + + } catch (DOMException e) { + throw new XmlException("Failed to create Document: " + e.getLocalizedMessage(), e); + } catch (ParserConfigurationException e) { + throw new XmlException("Failed to create Document: " + e.getLocalizedMessage(), e); + } + } } diff --git a/src/main/java/ch/eitchnet/privilege/model/internal/PrivilegeContainerModel.java b/src/main/java/ch/eitchnet/privilege/model/internal/PrivilegeContainerModel.java new file mode 100644 index 000000000..9fff19710 --- /dev/null +++ b/src/main/java/ch/eitchnet/privilege/model/internal/PrivilegeContainerModel.java @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2012, Robert von Burg + * + * All rights reserved. + * + * This file is part of the XXX. + * + * XXX is free software: you can redistribute + * it and/or modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * XXX is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XXX. If not, see + * . + */ +package ch.eitchnet.privilege.model.internal; + +import java.util.HashMap; +import java.util.Map; + +import ch.eitchnet.privilege.base.PrivilegeException; +import ch.eitchnet.privilege.policy.PrivilegePolicy; + +public class PrivilegeContainerModel { + + String encryptionHandlerClassName; + Map encryptionHandlerParameterMap; + String persistenceHandlerClassName; + Map persistenceHandlerParameterMap; + Map parameterMap; + + private Map> policies = new HashMap>(); + + /** + * @return the parameterMap + */ + public Map getParameterMap() { + return this.parameterMap; + } + + /** + * @param parameterMap + * the parameterMap to set + */ + public void setParameterMap(Map parameterMap) { + this.parameterMap = parameterMap; + } + + /** + * @return the encryptionHandlerClassName + */ + public String getEncryptionHandlerClassName() { + return this.encryptionHandlerClassName; + } + + /** + * @param encryptionHandlerClassName + * the encryptionHandlerClassName to set + */ + public void setEncryptionHandlerClassName(String encryptionHandlerClassName) { + this.encryptionHandlerClassName = encryptionHandlerClassName; + } + + /** + * @return the encryptionHandlerParameterMap + */ + public Map getEncryptionHandlerParameterMap() { + return this.encryptionHandlerParameterMap; + } + + /** + * @param encryptionHandlerParameterMap + * the encryptionHandlerParameterMap to set + */ + public void setEncryptionHandlerParameterMap(Map encryptionHandlerParameterMap) { + this.encryptionHandlerParameterMap = encryptionHandlerParameterMap; + } + + /** + * @return the persistenceHandlerClassName + */ + public String getPersistenceHandlerClassName() { + return this.persistenceHandlerClassName; + } + + /** + * @param persistenceHandlerClassName + * the persistenceHandlerClassName to set + */ + public void setPersistenceHandlerClassName(String persistenceHandlerClassName) { + this.persistenceHandlerClassName = persistenceHandlerClassName; + } + + /** + * @return the persistenceHandlerParameterMap + */ + public Map getPersistenceHandlerParameterMap() { + return this.persistenceHandlerParameterMap; + } + + /** + * @param persistenceHandlerParameterMap + * the persistenceHandlerParameterMap to set + */ + public void setPersistenceHandlerParameterMap(Map persistenceHandlerParameterMap) { + this.persistenceHandlerParameterMap = persistenceHandlerParameterMap; + } + + /** + * @param name + * @param policyClass + */ + public void addPolicy(String privilegeName, String policyClassName) { + + try { + + // load class and try to create a new instance + @SuppressWarnings("unchecked") + Class clazz = (Class) Class.forName(policyClassName); + clazz.newInstance(); + + this.policies.put(privilegeName, clazz); + + } catch (InstantiationException e) { + throw new PrivilegeException("Configured Privilege Policy " + privilegeName + " with class " + + policyClassName + " could not be instantiated.", e); + } catch (IllegalAccessException e) { + throw new PrivilegeException("Configured Privilege Policy " + privilegeName + " with class " + + policyClassName + " can not be accessed.", e); + } catch (ClassNotFoundException e) { + throw new PrivilegeException("Configured Privilege Policy " + privilegeName + " with class " + + policyClassName + " does not exist.", e); + } + } + + /** + * @return the policies + */ + public Map> getPolicies() { + return this.policies; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("PrivilegeContainerModel [encryptionHandlerClassName="); + builder.append(this.encryptionHandlerClassName); + builder.append(", encryptionHandlerParameterMap="); + builder.append(this.encryptionHandlerParameterMap.size()); + builder.append(", persistenceHandlerClassName="); + builder.append(this.persistenceHandlerClassName); + builder.append(", persistenceHandlerParameterMap="); + builder.append(this.persistenceHandlerParameterMap.size()); + builder.append(", parameterMap="); + builder.append(this.parameterMap.size()); + builder.append(", policies="); + builder.append(this.policies.size()); + builder.append("]"); + return builder.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/ch/eitchnet/privilege/xml/ElementParser.java b/src/main/java/ch/eitchnet/privilege/xml/ElementParser.java new file mode 100644 index 000000000..35e75f251 --- /dev/null +++ b/src/main/java/ch/eitchnet/privilege/xml/ElementParser.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2012, Robert von Burg + * + * All rights reserved. + * + * This file is part of the XXX. + * + * XXX is free software: you can redistribute + * it and/or modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * XXX is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XXX. If not, see + * . + */ +package ch.eitchnet.privilege.xml; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; + +public interface ElementParser { + + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException; + + public void characters(char[] ch, int start, int length) throws SAXException; + + public void endElement(String uri, String localName, String qName) throws SAXException; + + public void notifyChild(ElementParser child); +} \ No newline at end of file diff --git a/src/main/java/ch/eitchnet/privilege/xml/ElementParserAdapter.java b/src/main/java/ch/eitchnet/privilege/xml/ElementParserAdapter.java new file mode 100644 index 000000000..a881bc2b1 --- /dev/null +++ b/src/main/java/ch/eitchnet/privilege/xml/ElementParserAdapter.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012, Robert von Burg + * + * All rights reserved. + * + * This file is part of the XXX. + * + * XXX is free software: you can redistribute + * it and/or modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * XXX is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XXX. If not, see + * . + */ +package ch.eitchnet.privilege.xml; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; + +public abstract class ElementParserAdapter implements ElementParser { + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + // empty implementation + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + // empty implementation + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + // empty implementation + } + + @Override + public void notifyChild(ElementParser child) { + // empty implementation + } +} \ No newline at end of file diff --git a/src/main/java/ch/eitchnet/privilege/xml/InitializationHelper.java b/src/main/java/ch/eitchnet/privilege/xml/InitializationHelper.java new file mode 100644 index 000000000..edc7ec37b --- /dev/null +++ b/src/main/java/ch/eitchnet/privilege/xml/InitializationHelper.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2010 - 2012 + * + * This file is part of Privilege. + * + * Privilege is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Privilege is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Privilege. If not, see . + * + */ +package ch.eitchnet.privilege.xml; + +import java.io.File; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ch.eitchnet.privilege.base.PrivilegeException; +import ch.eitchnet.privilege.handler.DefaultPrivilegeHandler; +import ch.eitchnet.privilege.handler.EncryptionHandler; +import ch.eitchnet.privilege.handler.PersistenceHandler; +import ch.eitchnet.privilege.handler.PrivilegeHandler; +import ch.eitchnet.privilege.helper.ClassHelper; +import ch.eitchnet.privilege.helper.XmlHelper; +import ch.eitchnet.privilege.model.internal.PrivilegeContainerModel; +import ch.eitchnet.privilege.policy.PrivilegePolicy; + +/** + * This class implements the initializing of the {@link PrivilegeHandler} by loading an XML file containing the + * configuration + * + * @author Robert von Burg + */ +public class InitializationHelper { + + private static final Logger logger = LoggerFactory.getLogger(InitializationHelper.class); + + /** + * Initializes the {@link DefaultPrivilegeHandler} from the configuration file + * + * @param privilegeXmlFile + * a {@link File} reference to the XML file containing the configuration for Privilege + * + * @return the {@link PrivilegeHandler} instance loaded from the configuration file + */ + public static PrivilegeHandler initializeFromXml(File privilegeXmlFile) { + + // make sure file exists + if (!privilegeXmlFile.exists()) { + throw new PrivilegeException("Privilege file does not exist at path " + privilegeXmlFile.getAbsolutePath()); + } + + // parse configuration file + PrivilegeContainerModel containerModel = new PrivilegeContainerModel(); + PrivilegeConfigSaxReader xmlHandler = new PrivilegeConfigSaxReader(containerModel); + XmlHelper.parseDocument(privilegeXmlFile, xmlHandler); + + // initialize encryption handler + String encryptionHandlerClassName = containerModel.getEncryptionHandlerClassName(); + EncryptionHandler encryptionHandler = ClassHelper.instantiateClass(encryptionHandlerClassName); + Map parameterMap = containerModel.getEncryptionHandlerParameterMap(); + try { + encryptionHandler.initialize(parameterMap); + } catch (Exception e) { + InitializationHelper.logger.error(e.getMessage(), e); + throw new PrivilegeException("EncryptionHandler " + encryptionHandlerClassName + + " could not be initialized"); + } + + // initialize persistence handler + String persistenceHandlerClassName = containerModel.getPersistenceHandlerClassName(); + PersistenceHandler persistenceHandler = ClassHelper.instantiateClass(persistenceHandlerClassName); + parameterMap = containerModel.getPersistenceHandlerParameterMap(); + try { + persistenceHandler.initialize(parameterMap); + } catch (Exception e) { + InitializationHelper.logger.error(e.getMessage(), e); + throw new PrivilegeException("PersistenceHandler " + persistenceHandlerClassName + + " could not be initialized"); + } + + // initialize privilege handler + DefaultPrivilegeHandler privilegeHandler = new DefaultPrivilegeHandler(); + parameterMap = containerModel.getParameterMap(); + Map> policyMap = containerModel.getPolicies(); + try { + privilegeHandler.initialize(parameterMap, encryptionHandler, persistenceHandler, policyMap); + } catch (Exception e) { + InitializationHelper.logger.error(e.getMessage(), e); + throw new PrivilegeException("PrivilegeHandler " + privilegeHandler.getClass().getName() + + " could not be initialized"); + } + + return privilegeHandler; + } +} diff --git a/src/main/java/ch/eitchnet/privilege/xml/PrivilegeConfigDomWriter.java b/src/main/java/ch/eitchnet/privilege/xml/PrivilegeConfigDomWriter.java new file mode 100644 index 000000000..4826da315 --- /dev/null +++ b/src/main/java/ch/eitchnet/privilege/xml/PrivilegeConfigDomWriter.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2012, Robert von Burg + * + * All rights reserved. + * + * This file is part of the XXX. + * + * XXX is free software: you can redistribute + * it and/or modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * XXX is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XXX. If not, see + * . + */ +package ch.eitchnet.privilege.xml; + +import java.io.File; +import java.util.Map.Entry; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import ch.eitchnet.privilege.helper.XmlConstants; +import ch.eitchnet.privilege.helper.XmlHelper; +import ch.eitchnet.privilege.model.internal.PrivilegeContainerModel; +import ch.eitchnet.privilege.policy.PrivilegePolicy; + +/** + * @author Robert von Burg + * + */ +public class PrivilegeConfigDomWriter { + + private final PrivilegeContainerModel containerModel; + private final File configFile; + + /** + * + */ + public PrivilegeConfigDomWriter(PrivilegeContainerModel containerModel, File configFile) { + this.containerModel = containerModel; + this.configFile = configFile; + } + + /** + * + */ + public void write() { + + // create document root + Document doc = XmlHelper.createDocument(); + Element rootElement = doc.createElement(XmlConstants.XML_ROOT_PRIVILEGE); + doc.appendChild(rootElement); + + Element containerElement = doc.createElement(XmlConstants.XML_CONTAINER); + rootElement.appendChild(containerElement); + + Element parameterElement; + Element parametersElement; + + // Parameters + parametersElement = doc.createElement(XmlConstants.XML_PARAMETERS); + containerElement.appendChild(parametersElement); + for (Entry entry : this.containerModel.getParameterMap().entrySet()) { + parameterElement = doc.createElement(XmlConstants.XML_PARAMETER); + parameterElement.setAttribute(XmlConstants.XML_ATTR_NAME, entry.getKey()); + parameterElement.setAttribute(XmlConstants.XML_ATTR_VALUE, entry.getValue()); + parametersElement.appendChild(parameterElement); + } + + // create EncryptionHandler + Element encryptionHandlerElem = doc.createElement(XmlConstants.XML_HANDLER_ENCRYPTION); + containerElement.appendChild(encryptionHandlerElem); + encryptionHandlerElem.setAttribute(XmlConstants.XML_ATTR_CLASS, + this.containerModel.getEncryptionHandlerClassName()); + // Parameters + parametersElement = doc.createElement(XmlConstants.XML_PARAMETERS); + encryptionHandlerElem.appendChild(parametersElement); + for (Entry entry : this.containerModel.getEncryptionHandlerParameterMap().entrySet()) { + parameterElement = doc.createElement(XmlConstants.XML_PARAMETER); + parameterElement.setAttribute(XmlConstants.XML_ATTR_NAME, entry.getKey()); + parameterElement.setAttribute(XmlConstants.XML_ATTR_VALUE, entry.getValue()); + parametersElement.appendChild(parameterElement); + } + + // create PersistenceHandler + Element persistenceHandlerElem = doc.createElement(XmlConstants.XML_HANDLER_PERSISTENCE); + containerElement.appendChild(persistenceHandlerElem); + persistenceHandlerElem.setAttribute(XmlConstants.XML_ATTR_CLASS, + this.containerModel.getPersistenceHandlerClassName()); + // Parameters + parametersElement = doc.createElement(XmlConstants.XML_PARAMETERS); + persistenceHandlerElem.appendChild(parametersElement); + for (Entry entry : this.containerModel.getPersistenceHandlerParameterMap().entrySet()) { + parameterElement = doc.createElement(XmlConstants.XML_PARAMETER); + parameterElement.setAttribute(XmlConstants.XML_ATTR_NAME, entry.getKey()); + parameterElement.setAttribute(XmlConstants.XML_ATTR_VALUE, entry.getValue()); + parametersElement.appendChild(parameterElement); + } + + // Policies + Element policiesElem = doc.createElement(XmlConstants.XML_POLICIES); + rootElement.appendChild(policiesElem); + for (Entry> entry : this.containerModel.getPolicies().entrySet()) { + Element policyElem = doc.createElement(XmlConstants.XML_POLICY); + policyElem.setAttribute(XmlConstants.XML_ATTR_NAME, entry.getKey()); + policyElem.setAttribute(XmlConstants.XML_ATTR_CLASS, entry.getValue().getName()); + policiesElem.appendChild(policyElem); + } + + // write the container file to disk + XmlHelper.writeDocument(doc, this.configFile); + } +} diff --git a/src/main/java/ch/eitchnet/privilege/xml/PrivilegeConfigSaxReader.java b/src/main/java/ch/eitchnet/privilege/xml/PrivilegeConfigSaxReader.java new file mode 100644 index 000000000..95fb910d1 --- /dev/null +++ b/src/main/java/ch/eitchnet/privilege/xml/PrivilegeConfigSaxReader.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2012, Robert von Burg + * + * All rights reserved. + * + * This file is part of the XXX. + * + * XXX is free software: you can redistribute + * it and/or modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * XXX is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XXX. If not, see + * . + */ +package ch.eitchnet.privilege.xml; + +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import ch.eitchnet.privilege.model.internal.PrivilegeContainerModel; + +/** + * @author Robert von Burg + * + */ +public class PrivilegeConfigSaxReader extends DefaultHandler { + + // private static final Logger logger = LoggerFactory.getLogger(PrivilegeConfigSaxReader.class); + + private Stack buildersStack = new Stack(); + + private PrivilegeContainerModel containerModel; + + public PrivilegeConfigSaxReader(PrivilegeContainerModel containerModel) { + this.containerModel = containerModel; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + + if (qName.equals("Container")) { + this.buildersStack.add(new ContainerParser()); + } else if (qName.equals("Parameters")) { + this.buildersStack.add(new ParametersParser()); + } else if (qName.equals("Policies")) { + this.buildersStack.add(new PoliciesParser()); + } + + if (!this.buildersStack.isEmpty()) + this.buildersStack.peek().startElement(uri, localName, qName, attributes); + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + if (!this.buildersStack.isEmpty()) + this.buildersStack.peek().characters(ch, start, length); + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + + if (!this.buildersStack.isEmpty()) + this.buildersStack.peek().endElement(uri, localName, qName); + + ElementParser elementParser = null; + if (qName.equals("Container")) { + elementParser = this.buildersStack.pop(); + } else if (qName.equals("Parameters")) { + elementParser = this.buildersStack.pop(); + } else if (qName.equals("Policies")) { + elementParser = this.buildersStack.pop(); + } + + if (!this.buildersStack.isEmpty() && elementParser != null) + this.buildersStack.peek().notifyChild(elementParser); + } + + public class ContainerParser extends ElementParserAdapter { + +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// + + private String currentElement; + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + if (qName.equals("Container")) { + this.currentElement = qName; + } else if (qName.equals("EncryptionHandler")) { + this.currentElement = qName; + PrivilegeConfigSaxReader.this.containerModel + .setEncryptionHandlerClassName(attributes.getValue("class")); + } else if (qName.equals("PersistenceHandler")) { + this.currentElement = qName; + PrivilegeConfigSaxReader.this.containerModel.setPersistenceHandlerClassName(attributes + .getValue("class")); + } + } + + @Override + public void notifyChild(ElementParser child) { + if (!(child instanceof ParametersParser)) + return; + + ParametersParser parametersChild = (ParametersParser) child; + + if (this.currentElement.equals("Container")) { + PrivilegeConfigSaxReader.this.containerModel.setParameterMap(parametersChild.getParameterMap()); + } else if (this.currentElement.equals("EncryptionHandler")) { + PrivilegeConfigSaxReader.this.containerModel.setEncryptionHandlerParameterMap(parametersChild + .getParameterMap()); + } else if (this.currentElement.equals("PersistenceHandler")) { + PrivilegeConfigSaxReader.this.containerModel.setPersistenceHandlerParameterMap(parametersChild + .getParameterMap()); + } + } + } + + class ParametersParser extends ElementParserAdapter { + +// + + private Map parameterMap = new HashMap(); + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + if (qName.equals("Parameter")) { + String key = attributes.getValue("name"); + String value = attributes.getValue("value"); + this.parameterMap.put(key, value); + } + } + + /** + * @return the parameterMap + */ + public Map getParameterMap() { + return this.parameterMap; + } + } + + class PoliciesParser extends ElementParserAdapter { + +// + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + if (qName.equals("Policy")) { + String policyName = attributes.getValue("name"); + String policyClassName = attributes.getValue("class"); + + PrivilegeConfigSaxReader.this.containerModel.addPolicy(policyName, policyClassName); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/ch/eitchnet/privilege/xml/PrivilegeModelDomWriter.java b/src/main/java/ch/eitchnet/privilege/xml/PrivilegeModelDomWriter.java new file mode 100644 index 000000000..e740dce35 --- /dev/null +++ b/src/main/java/ch/eitchnet/privilege/xml/PrivilegeModelDomWriter.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2012, Robert von Burg + * + * All rights reserved. + * + * This file is part of the XXX. + * + * XXX is free software: you can redistribute + * it and/or modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * XXX is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XXX. If not, see + * . + */ +package ch.eitchnet.privilege.xml; + +import java.io.File; +import java.util.List; +import java.util.Map.Entry; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import ch.eitchnet.privilege.helper.XmlConstants; +import ch.eitchnet.privilege.helper.XmlHelper; +import ch.eitchnet.privilege.model.internal.Privilege; +import ch.eitchnet.privilege.model.internal.Role; +import ch.eitchnet.privilege.model.internal.User; + +/** + * @author Robert von Burg + * + */ +public class PrivilegeModelDomWriter { + + private List users; + private List roles; + private File modelFile; + + /** + * + */ + public PrivilegeModelDomWriter(List users, List roles, File modelFile) { + this.users = users; + this.roles = roles; + this.modelFile = modelFile; + } + + public void write() { + + // create document root + Document doc = XmlHelper.createDocument(); + Element rootElement = doc.createElement(XmlConstants.XML_ROOT_PRIVILEGE_USERS_AND_ROLES); + doc.appendChild(rootElement); + + Element usersElement = doc.createElement(XmlConstants.XML_USERS); + rootElement.appendChild(usersElement); + + for (User user : this.users) { + + // create the user element + Element userElement = doc.createElement(XmlConstants.XML_USER); + usersElement.appendChild(userElement); + + userElement.setAttribute(XmlConstants.XML_ATTR_USER_ID, user.getUserId()); + userElement.setAttribute(XmlConstants.XML_ATTR_USERNAME, user.getUsername()); + userElement.setAttribute(XmlConstants.XML_ATTR_PASSWORD, user.getPassword()); + + // add first name element + Element firstnameElement = doc.createElement(XmlConstants.XML_FIRSTNAME); + firstnameElement.setTextContent(user.getFirstname()); + userElement.appendChild(firstnameElement); + + // add surname element + Element surnameElement = doc.createElement(XmlConstants.XML_SURNAME); + surnameElement.setTextContent(user.getSurname()); + userElement.appendChild(surnameElement); + + // add state element + Element stateElement = doc.createElement(XmlConstants.XML_STATE); + stateElement.setTextContent(user.getUserState().toString()); + userElement.appendChild(stateElement); + + // add locale element + Element localeElement = doc.createElement(XmlConstants.XML_LOCALE); + localeElement.setTextContent(user.getLocale().toString()); + userElement.appendChild(localeElement); + + // add all the role elements + Element rolesElement = doc.createElement(XmlConstants.XML_ROLES); + userElement.appendChild(rolesElement); + for (String roleName : user.getRoles()) { + Element roleElement = doc.createElement(XmlConstants.XML_ROLE); + roleElement.setTextContent(roleName); + rolesElement.appendChild(roleElement); + } + + // add the parameters + Element parametersElement = doc.createElement(XmlConstants.XML_PARAMETERS); + userElement.appendChild(parametersElement); + for (Entry entry : user.getProperties().entrySet()) { + Element paramElement = doc.createElement(XmlConstants.XML_PARAMETER); + paramElement.setAttribute(XmlConstants.XML_ATTR_NAME, entry.getKey()); + paramElement.setAttribute(XmlConstants.XML_ATTR_VALUE, entry.getValue()); + parametersElement.appendChild(paramElement); + } + } + + Element rolesElement = doc.createElement(XmlConstants.XML_ROLES); + rootElement.appendChild(rolesElement); + + for (Role role : this.roles) { + + // create the role element + Element roleElement = doc.createElement(XmlConstants.XML_ROLE); + rolesElement.appendChild(roleElement); + + roleElement.setAttribute(XmlConstants.XML_ATTR_NAME, role.getName()); + + for (Privilege privilege : role.getPrivilegeMap().values()) { + + // create the privilege element + Element privilegeElement = doc.createElement(XmlConstants.XML_PRIVILEGE); + roleElement.appendChild(privilegeElement); + + privilegeElement.setAttribute(XmlConstants.XML_ATTR_NAME, privilege.getName()); + privilegeElement.setAttribute(XmlConstants.XML_ATTR_POLICY, privilege.getPolicy()); + + // add the all allowed element + Element allAllowedElement = doc.createElement(XmlConstants.XML_ALL_ALLOWED); + allAllowedElement.setTextContent(Boolean.toString(privilege.isAllAllowed())); + privilegeElement.appendChild(allAllowedElement); + + // add all the deny values + for (String denyValue : privilege.getDenyList()) { + Element denyValueElement = doc.createElement(XmlConstants.XML_DENY); + denyValueElement.setTextContent(denyValue); + privilegeElement.appendChild(denyValueElement); + } + + // add all the allow values + for (String allowValue : privilege.getAllowList()) { + Element allowValueElement = doc.createElement(XmlConstants.XML_ALLOW); + allowValueElement.setTextContent(allowValue); + privilegeElement.appendChild(allowValueElement); + } + } + } + + // write the container file to disk + XmlHelper.writeDocument(doc, this.modelFile); + } +} diff --git a/src/main/java/ch/eitchnet/privilege/xml/PrivilegeModelSaxReader.java b/src/main/java/ch/eitchnet/privilege/xml/PrivilegeModelSaxReader.java new file mode 100644 index 000000000..c79378489 --- /dev/null +++ b/src/main/java/ch/eitchnet/privilege/xml/PrivilegeModelSaxReader.java @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2012, Robert von Burg + * + * All rights reserved. + * + * This file is part of the XXX. + * + * XXX is free software: you can redistribute + * it and/or modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * XXX is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XXX. If not, see + * . + */ +package ch.eitchnet.privilege.xml; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.Stack; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import ch.eitchnet.privilege.model.UserState; +import ch.eitchnet.privilege.model.internal.Privilege; +import ch.eitchnet.privilege.model.internal.Role; +import ch.eitchnet.privilege.model.internal.User; +import ch.eitchnet.utils.helper.StringHelper; + +/** + * @author Robert von Burg + * + */ +public class PrivilegeModelSaxReader extends DefaultHandler { + + private static final Logger logger = LoggerFactory.getLogger(PrivilegeModelSaxReader.class); + + private Stack buildersStack = new Stack(); + + private List users; + private List roles; + + private boolean insideUser; + + /** + * + */ + public PrivilegeModelSaxReader() { + this.users = new ArrayList(); + this.roles = new ArrayList(); + } + + /** + * @return the users + */ + public List getUsers() { + return this.users; + } + + /** + * @return the roles + */ + public List getRoles() { + return this.roles; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + + if (qName.equals("Users")) { + this.buildersStack.add(new UserParser()); + this.insideUser = true; + } else if (qName.equals("Properties")) { + this.buildersStack.add(new PropertyParser()); + } else if (qName.equals("Roles") && !this.insideUser) { + this.buildersStack.add(new RoleParser()); + } + + if (!this.buildersStack.isEmpty()) + this.buildersStack.peek().startElement(uri, localName, qName, attributes); + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + if (!this.buildersStack.isEmpty()) + this.buildersStack.peek().characters(ch, start, length); + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + + if (!this.buildersStack.isEmpty()) + this.buildersStack.peek().endElement(uri, localName, qName); + + ElementParser elementParser = null; + if (qName.equals("Users")) { + elementParser = this.buildersStack.pop(); + this.insideUser = false; + PrivilegeModelSaxReader.logger.info("Popping for Users"); + } else if (qName.equals("Properties")) { + elementParser = this.buildersStack.pop(); + PrivilegeModelSaxReader.logger.info("Popping for Properties"); + } else if (qName.equals("Roles") && !this.insideUser) { + elementParser = this.buildersStack.pop(); + PrivilegeModelSaxReader.logger.info("Popping for Roles"); + } + + if (!this.buildersStack.isEmpty() && elementParser != null) + this.buildersStack.peek().notifyChild(elementParser); + } + +// +// +// true +// +// +// +// +// true +// +// +// true +// +// + + public class RoleParser extends ElementParserAdapter { + + private StringBuilder text; + + private String roleName; + private String privilegeName; + private String privilegePolicy; + private boolean allAllowed; + private Set denyList; + private Set allowList; + + private Map privileges; + + /** + * + */ + public RoleParser() { + init(); + } + + /** + * + */ + private void init() { + this.privileges = new HashMap(); + + this.text = null; + + this.roleName = null; + this.privilegeName = null; + this.privilegePolicy = null; + this.allAllowed = false; + this.denyList = new HashSet(); + this.allowList = new HashSet(); + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + + this.text = new StringBuilder(); + + if (qName.equals("Role")) { + this.roleName = attributes.getValue("name"); + } else if (qName.equals("Privilege")) { + this.privilegeName = attributes.getValue("name"); + this.privilegePolicy = attributes.getValue("policy"); + } + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + if (this.text != null) + this.text.append(ch, start, length); + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + + if (qName.equals("AllAllowed")) { + this.allAllowed = StringHelper.parseBoolean(this.text.toString().trim()); + } else if (qName.equals("Allow")) { + this.allowList.add(this.text.toString().trim()); + } else if (qName.equals("Deny")) { + this.denyList.add(this.text.toString().trim()); + } else if (qName.equals("Privilege")) { + + Privilege privilege = new Privilege(this.privilegeName, this.privilegePolicy, this.allAllowed, + this.denyList, this.allowList); + this.privileges.put(this.privilegeName, privilege); + + } else if (qName.equals("Role")) { + + Role role = new Role(this.roleName, this.privileges); + + PrivilegeModelSaxReader.this.roles.add(role); + PrivilegeModelSaxReader.logger.info("New Role: " + role); + init(); + } + } + } + +// +// Application +// Administrator +// ENABLED +// en_GB +// +// PrivilegeAdmin +// AppUser +// +// +// +// +// +// + + public class UserParser extends ElementParserAdapter { + + StringBuilder text; + + String userId; + String username; + String password; + String firstName; + String surname; + UserState userState; + Locale locale; + Set userRoles; + Map parameters; + + public UserParser() { + this.userRoles = new HashSet(); + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + + this.text = new StringBuilder(); + + if (qName.equals("User")) { + this.userId = attributes.getValue("userId"); + this.username = attributes.getValue("username"); + this.password = attributes.getValue("password"); + } + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + this.text.append(ch, start, length); + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + + if (qName.equals("Firstname")) { + this.firstName = this.text.toString().trim(); + } else if (qName.equals("Surname")) { + this.surname = this.text.toString().trim(); + } else if (qName.equals("State")) { + this.userState = UserState.valueOf(this.text.toString().trim()); + } else if (qName.equals("Locale")) { + this.locale = Locale.forLanguageTag(this.text.toString().trim()); + } else if (qName.equals("Role")) { + this.userRoles.add(this.text.toString().trim()); + } else if (qName.equals("User")) { + + User user = new User(this.userId, this.username, this.password, this.firstName, this.surname, + this.userState, this.userRoles, this.locale, this.parameters); + + StringBuilder builder = new StringBuilder(); + builder.append("UserParser [userId="); + builder.append(this.userId); + builder.append(", username="); + builder.append(this.username); + builder.append(", password="); + builder.append(this.password); + builder.append(", firstName="); + builder.append(this.firstName); + builder.append(", surname="); + builder.append(this.surname); + builder.append(", userState="); + builder.append(this.userState); + builder.append(", locale="); + builder.append(this.locale); + builder.append(", userRoles="); + builder.append(this.userRoles.size()); + builder.append(", parameters="); + builder.append(this.parameters.size()); + builder.append("]"); + PrivilegeModelSaxReader.logger.info(builder.toString()); + + PrivilegeModelSaxReader.this.users.add(user); + + } + } + + @Override + public void notifyChild(ElementParser child) { + if (child instanceof PropertyParser) { + this.parameters = ((PropertyParser) child).parameterMap; + } + } + } + + class PropertyParser extends ElementParserAdapter { + +// + + private Map parameterMap = new HashMap(); + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + if (qName.equals("Property")) { + String key = attributes.getValue("name"); + String value = attributes.getValue("value"); + this.parameterMap.put(key, value); + } + } + + /** + * @return the parameterMap + */ + public Map getParameterMap() { + return this.parameterMap; + } + } +} diff --git a/src/test/java/ch/eitchnet/privilege/test/PrivilegeTest.java b/src/test/java/ch/eitchnet/privilege/test/PrivilegeTest.java index 47e2c69e7..e7854c128 100644 --- a/src/test/java/ch/eitchnet/privilege/test/PrivilegeTest.java +++ b/src/test/java/ch/eitchnet/privilege/test/PrivilegeTest.java @@ -37,7 +37,6 @@ import ch.eitchnet.privilege.base.AccessDeniedException; import ch.eitchnet.privilege.base.PrivilegeException; import ch.eitchnet.privilege.handler.PrivilegeHandler; import ch.eitchnet.privilege.helper.CertificateThreadLocal; -import ch.eitchnet.privilege.helper.InitializationHelper; import ch.eitchnet.privilege.model.Certificate; import ch.eitchnet.privilege.model.PrivilegeRep; import ch.eitchnet.privilege.model.Restrictable; @@ -47,6 +46,7 @@ import ch.eitchnet.privilege.model.UserState; import ch.eitchnet.privilege.test.model.TestRestrictable; import ch.eitchnet.privilege.test.model.TestSystemUserAction; import ch.eitchnet.privilege.test.model.TestSystemUserActionDeny; +import ch.eitchnet.privilege.xml.InitializationHelper; import ch.eitchnet.utils.helper.FileHelper; /** diff --git a/src/test/java/ch/eitchnet/privilege/test/XmlTest.java b/src/test/java/ch/eitchnet/privilege/test/XmlTest.java new file mode 100644 index 000000000..3b8de44f0 --- /dev/null +++ b/src/test/java/ch/eitchnet/privilege/test/XmlTest.java @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2012, Robert von Burg + * + * All rights reserved. + * + * This file is part of the XXX. + * + * XXX is free software: you can redistribute + * it and/or modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * XXX is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XXX. If not, see + * . + */ +package ch.eitchnet.privilege.test; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import junit.framework.Assert; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ch.eitchnet.privilege.handler.DefaultEncryptionHandler; +import ch.eitchnet.privilege.handler.XmlPersistenceHandler; +import ch.eitchnet.privilege.helper.XmlHelper; +import ch.eitchnet.privilege.model.UserState; +import ch.eitchnet.privilege.model.internal.Privilege; +import ch.eitchnet.privilege.model.internal.PrivilegeContainerModel; +import ch.eitchnet.privilege.model.internal.Role; +import ch.eitchnet.privilege.model.internal.User; +import ch.eitchnet.privilege.xml.PrivilegeConfigDomWriter; +import ch.eitchnet.privilege.xml.PrivilegeConfigSaxReader; +import ch.eitchnet.privilege.xml.PrivilegeModelDomWriter; +import ch.eitchnet.privilege.xml.PrivilegeModelSaxReader; +import ch.eitchnet.utils.helper.FileHelper; +import ch.eitchnet.utils.helper.StringHelper; + +/** + * @author Robert von Burg + * + */ +public class XmlTest { + + /** + * + */ + private static final String TARGET_TEST = "./target/test"; + private static final Logger logger = LoggerFactory.getLogger(XmlTest.class); + + /** + * @throws Exception + * if something goes wrong + */ + @BeforeClass + public static void init() throws Exception { + + File tmpDir = new File("target/test"); + if (tmpDir.exists()) + FileHelper.deleteFile(tmpDir, false); + tmpDir.mkdirs(); + } + + @AfterClass + public static void destroy() throws Exception { + + File tmpDir = new File("target/test"); + if (!tmpDir.exists()) + return; + + File tmpFile = new File("target/test/PrivilegeTest.xml"); + if (tmpFile.exists() && !tmpFile.delete()) { + throw new RuntimeException("Tmp still exists and can not be deleted at " + tmpFile.getAbsolutePath()); + } + + tmpFile = new File("target/test/PrivilegeModelTest.xml"); + if (tmpFile.exists() && !tmpFile.delete()) { + throw new RuntimeException("Tmp still exists and can not be deleted at " + tmpFile.getAbsolutePath()); + } + + // and temporary parent + if (!tmpDir.delete()) { + throw new RuntimeException("Could not remove temporary parent for tmp " + tmpFile); + } + } + + @Test + public void canReadConfig() { + + PrivilegeContainerModel containerModel = new PrivilegeContainerModel(); + PrivilegeConfigSaxReader saxReader = new PrivilegeConfigSaxReader(containerModel); + File xmlFile = new File("config/Privilege.xml"); + XmlHelper.parseDocument(xmlFile, saxReader); + logger.info(containerModel.toString()); + + // assert all objects read + Assert.assertNotNull(containerModel.getParameterMap()); + Assert.assertNotNull(containerModel.getPolicies()); + Assert.assertNotNull(containerModel.getEncryptionHandlerClassName()); + Assert.assertNotNull(containerModel.getEncryptionHandlerParameterMap()); + Assert.assertNotNull(containerModel.getPersistenceHandlerClassName()); + Assert.assertNotNull(containerModel.getPersistenceHandlerParameterMap()); + + Assert.assertEquals(1, containerModel.getParameterMap().size()); + Assert.assertEquals(1, containerModel.getPolicies().size()); + Assert.assertEquals(1, containerModel.getEncryptionHandlerParameterMap().size()); + Assert.assertEquals(2, containerModel.getPersistenceHandlerParameterMap().size()); + + // TODO extend assertions to actual model + } + + @Test + public void canWriteConfig() { + + Map parameterMap = new HashMap(); + Map encryptionHandlerParameterMap = new HashMap(); + Map persistenceHandlerParameterMap = new HashMap(); + + // TODO ask other questions... + parameterMap.put("autoPersistOnPasswordChange", "true"); + encryptionHandlerParameterMap.put("hashAlgorithm", "SHA-256"); + persistenceHandlerParameterMap.put("basePath", TARGET_TEST); + persistenceHandlerParameterMap.put("modelXmlFile", "PrivilegeModel.xml"); + + PrivilegeContainerModel containerModel = new PrivilegeContainerModel(); + containerModel.setParameterMap(parameterMap); + containerModel.setEncryptionHandlerClassName(DefaultEncryptionHandler.class.getName()); + containerModel.setEncryptionHandlerParameterMap(encryptionHandlerParameterMap); + containerModel.setPersistenceHandlerClassName(XmlPersistenceHandler.class.getName()); + containerModel.setPersistenceHandlerParameterMap(persistenceHandlerParameterMap); + + containerModel.addPolicy("DefaultPrivilege", "ch.eitchnet.privilege.policy.DefaultPrivilege"); + + File configFile = new File("./target/test/PrivilegeTest.xml"); + PrivilegeConfigDomWriter configSaxWriter = new PrivilegeConfigDomWriter(containerModel, configFile); + configSaxWriter.write(); + + String fileHash = StringHelper.getHexString(FileHelper.hashFileSha256(configFile)); + Assert.assertEquals("22d4ba39605d49c758184d9bd63beae5ccf8786f3dabbab45cd9f59c2afbcbd0", fileHash); + } + + @Test + public void canReadModel() { + + PrivilegeModelSaxReader xmlHandler = new PrivilegeModelSaxReader(); + File xmlFile = new File("config/PrivilegeModel.xml"); + XmlHelper.parseDocument(xmlFile, xmlHandler); + + List users = xmlHandler.getUsers(); + Assert.assertNotNull(users); + List roles = xmlHandler.getRoles(); + Assert.assertNotNull(roles); + + Assert.assertEquals(2, users.size()); + Assert.assertEquals(4, roles.size()); + + // TODO extend assertions to actual model + } + + @Test + public void canWriteModel() { + + Map propertyMap; + Set userRoles; + Map privilegeMap; + + List users = new ArrayList(); + propertyMap = new HashMap(); + propertyMap.put("prop1", "value1"); + userRoles = new HashSet(); + userRoles.add("role1"); + users.add(new User("1", "user1", "blabla", "Bob", "White", UserState.DISABLED, userRoles, Locale.ENGLISH, + propertyMap)); + + propertyMap = new HashMap(); + propertyMap.put("prop2", "value2"); + userRoles = new HashSet(); + userRoles.add("role2"); + users.add(new User("2", "user2", "haha", "Leonard", "Sheldon", UserState.ENABLED, userRoles, Locale.ENGLISH, + propertyMap)); + + List roles = new ArrayList(); + privilegeMap = new HashMap(); + privilegeMap.put("priv1", new Privilege("priv1", "DefaultPrivilege", true, null, null)); + roles.add(new Role("role1", privilegeMap)); + + privilegeMap = new HashMap(); + Set denyList = new HashSet(); + denyList.add("myself"); + Set allowList = new HashSet(); + allowList.add("other"); + privilegeMap.put("priv2", new Privilege("priv2", "DefaultPrivilege", false, denyList, allowList)); + roles.add(new Role("role2", privilegeMap)); + + File modelFile = new File("./target/test/PrivilegeModelTest.xml"); + PrivilegeModelDomWriter configSaxWriter = new PrivilegeModelDomWriter(users, roles, modelFile); + configSaxWriter.write(); + + String fileHash = StringHelper.getHexString(FileHelper.hashFileSha256(modelFile)); + Assert.assertEquals("8e1e82278162f21b1654c2e059570bbcb3cb63b053c1dd784bc8e225e8cfd04f", fileHash); + } +}