org.geoserver.security.xml.XMLRoleStore.java Source code

Java tutorial

Introduction

Here is the source code for org.geoserver.security.xml.XMLRoleStore.java

Source

/* Copyright (c) 2001 - 2013 OpenPlans - www.openplans.org. All rights reserved.
 * This code is licensed under the GPL 2.0 license, available at the root
 * application directory.
 */
package org.geoserver.security.xml;

import static org.geoserver.security.xml.XMLConstants.A_GROUPNAME_RR;
import static org.geoserver.security.xml.XMLConstants.A_PARENTID_RR;
import static org.geoserver.security.xml.XMLConstants.A_PROPERTY_NAME_RR;
import static org.geoserver.security.xml.XMLConstants.A_ROLEID_RR;
import static org.geoserver.security.xml.XMLConstants.A_ROLEREFID_RR;
import static org.geoserver.security.xml.XMLConstants.A_USERNAME_RR;
import static org.geoserver.security.xml.XMLConstants.A_VERSION_RR;
import static org.geoserver.security.xml.XMLConstants.E_GROUPLIST_RR;
import static org.geoserver.security.xml.XMLConstants.E_GROUPROLES_RR;
import static org.geoserver.security.xml.XMLConstants.E_PROPERTY_RR;
import static org.geoserver.security.xml.XMLConstants.E_ROLELIST_RR;
import static org.geoserver.security.xml.XMLConstants.E_ROLEREF_RR;
import static org.geoserver.security.xml.XMLConstants.E_ROLEREGISTRY_RR;
import static org.geoserver.security.xml.XMLConstants.E_ROLE_RR;
import static org.geoserver.security.xml.XMLConstants.E_USERLIST_RR;
import static org.geoserver.security.xml.XMLConstants.E_USERROLES_RR;
import static org.geoserver.security.xml.XMLConstants.NS_RR;
import static org.geoserver.security.xml.XMLConstants.VERSION_RR_1_0;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.SortedSet;
import java.util.logging.Logger;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.io.IOUtils;

import org.geoserver.security.GeoServerRoleService;
import org.geoserver.security.file.LockFile;
import org.geoserver.security.impl.AbstractRoleStore;
import org.geoserver.security.impl.GeoServerRole;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class XMLRoleStore extends AbstractRoleStore {

    static Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geoserver.security.xml");
    protected File roleFile;
    protected LockFile lockFile = null;
    /**
     * Validate against schema on load/store,
     * default = true;
     */
    private boolean validatingXMLSchema = true;

    public boolean isValidatingXMLSchema() {
        return validatingXMLSchema;
    }

    public void setValidatingXMLSchema(boolean validatingXMLSchema) {
        this.validatingXMLSchema = validatingXMLSchema;
    }

    /* (non-Javadoc)
     * @see org.geoserver.security.impl.AbstractRoleStore#initializeFromService(org.geoserver.security.GeoserverRoleService)
     */
    public void initializeFromService(GeoServerRoleService service) throws IOException {
        this.roleFile = ((XMLRoleService) service).roleFile;
        this.validatingXMLSchema = ((XMLRoleService) service).isValidatingXMLSchema();
        super.initializeFromService(service);

    }

    @Override
    protected void serialize() throws IOException {

        DocumentBuilder builder = null;
        try {
            builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        } catch (ParserConfigurationException e1) {
            throw new IOException(e1);
        }
        Document doc = builder.newDocument();

        Element rolereg = doc.createElement(E_ROLEREGISTRY_RR);
        doc.appendChild(rolereg);
        rolereg.setAttribute(javax.xml.XMLConstants.XMLNS_ATTRIBUTE, NS_RR);
        rolereg.setAttribute(A_VERSION_RR, VERSION_RR_1_0);

        Element rolelist = doc.createElement(E_ROLELIST_RR);
        rolereg.appendChild(rolelist);

        for (GeoServerRole roleObject : helper.roleMap.values()) {
            Element role = doc.createElement(E_ROLE_RR);
            rolelist.appendChild(role);
            role.setAttribute(A_ROLEID_RR, roleObject.getAuthority());
            GeoServerRole parentObject = helper.role_parentMap.get(roleObject);
            if (parentObject != null) {
                role.setAttribute(A_PARENTID_RR, parentObject.getAuthority());
            }
            for (Object key : roleObject.getProperties().keySet()) {
                Element property = doc.createElement(E_PROPERTY_RR);
                role.appendChild(property);
                property.setAttribute(A_PROPERTY_NAME_RR, key.toString());
                property.setTextContent(roleObject.getProperties().getProperty(key.toString()));
            }
        }

        Element userList = doc.createElement(E_USERLIST_RR);
        rolereg.appendChild(userList);
        for (String userName : helper.user_roleMap.keySet()) {
            Element userroles = doc.createElement(E_USERROLES_RR);
            userList.appendChild(userroles);
            userroles.setAttribute(A_USERNAME_RR, userName);
            SortedSet<GeoServerRole> roleObjects = helper.user_roleMap.get(userName);
            for (GeoServerRole roleObject : roleObjects) {
                Element ref = doc.createElement(E_ROLEREF_RR);
                userroles.appendChild(ref);
                ref.setAttribute(A_ROLEREFID_RR, roleObject.getAuthority());
            }
        }

        Element groupList = doc.createElement(E_GROUPLIST_RR);
        rolereg.appendChild(groupList);

        for (String groupName : helper.group_roleMap.keySet()) {
            Element grouproles = doc.createElement(E_GROUPROLES_RR);
            groupList.appendChild(grouproles);
            grouproles.setAttribute(A_GROUPNAME_RR, groupName);
            SortedSet<GeoServerRole> roleObjects = helper.group_roleMap.get(groupName);
            for (GeoServerRole roleObject : roleObjects) {
                Element ref = doc.createElement(E_ROLEREF_RR);
                grouproles.appendChild(ref);
                ref.setAttribute(A_ROLEREFID_RR, roleObject.getAuthority());
            }
        }

        // serialize the dom
        try {
            //            TODO, wait for JAVA 6
            //            if (isValidatingXMLSchema()) {
            //                XMLValidator.Singleton.validateRoleRegistry(doc);
            //            }

            Transformer tx = TransformerFactory.newInstance().newTransformer();
            tx.setOutputProperty(OutputKeys.METHOD, "XML");
            tx.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            tx.setOutputProperty(OutputKeys.INDENT, "yes");

            OutputStream out = new BufferedOutputStream(new FileOutputStream(roleFile));
            try {
                tx.transform(new DOMSource(doc), new StreamResult(out));
                out.flush();
            } finally {
                IOUtils.closeQuietly(out);
            }

            /* standard java, but there is no possibility to set 
             * the number of chars to indent, each line is starting at 
             * column 0
            Source source = new DOMSource(doc);
            // Prepare the output file            
            Result result = new StreamResult(
                new OutputStreamWriter(new FileOutputStream(roleFile),"UTF-8"));
                
            TransformerFactory fac = TransformerFactory.newInstance();
            Transformer xformer = fac.newTransformer();                        
            xformer.setOutputProperty(OutputKeys.INDENT, "yes");            
            xformer.transform(source, result);
            */

        } catch (Exception e) {
            throw new IOException(e);
        }
    }

    @Override
    protected void deserialize() throws IOException {
        super.deserialize();
        releaseLock();
    }

    @Override
    public String toString() {
        return getName();
    }

    protected void ensureLock() throws IOException {
        if (lockFile != null)
            return; // we have one
        lockFile = new LockFile(roleFile);
        try {
            lockFile.writeLock();
        } catch (IOException ex) { // cannot obtain lock
            lockFile = null; // assert lockFile == null
            throw ex; // throw again
        }
    }

    protected void releaseLock() {
        if (lockFile == null)
            return; // we have none        
        lockFile.writeUnLock();
        lockFile = null;
    }

    @Override
    public void addRole(GeoServerRole role) throws IOException {
        ensureLock();
        super.addRole(role);
    }

    @Override
    public void updateRole(GeoServerRole role) throws IOException {
        ensureLock();
        super.updateRole(role);
    }

    @Override
    public boolean removeRole(GeoServerRole role) throws IOException {
        ensureLock();
        return super.removeRole(role);
    }

    @Override
    public void store() throws IOException {
        ensureLock();
        super.store();
        releaseLock();
    }

    @Override
    public void disAssociateRoleFromGroup(GeoServerRole role, String groupname) throws IOException {
        ensureLock();
        super.disAssociateRoleFromGroup(role, groupname);
    }

    @Override
    public void associateRoleToGroup(GeoServerRole role, String groupname) throws IOException {
        ensureLock();
        super.associateRoleToGroup(role, groupname);
    }

    @Override
    public void associateRoleToUser(GeoServerRole role, String username) throws IOException {
        ensureLock();
        super.associateRoleToUser(role, username);
    }

    @Override
    public void disAssociateRoleFromUser(GeoServerRole role, String username) throws IOException {
        ensureLock();
        super.disAssociateRoleFromUser(role, username);
    }

    @Override
    public void setParentRole(GeoServerRole role, GeoServerRole parentRole) throws IOException {
        ensureLock();
        super.setParentRole(role, parentRole);
    }

    @Override
    public void clear() throws IOException {
        ensureLock();
        super.clear();
    }
}