org.pentaho.platform.uifoundation.component.xml.PropertiesPanelUIComponent.java Source code

Java tutorial

Introduction

Here is the source code for org.pentaho.platform.uifoundation.component.xml.PropertiesPanelUIComponent.java

Source

/*
 * This program is free software; you can redistribute it and/or modify it under the 
 * terms of the GNU General Public License, version 2 as published by the Free Software 
 * Foundation.
 *
 * You should have received a copy of the GNU General Public License along with this 
 * program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.html 
 * or from the Free Software Foundation, Inc., 
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * This program 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.
 *
 *
 * Copyright 2006 - 2008 Pentaho Corporation.  All rights reserved. 
 * 
 * Created Mar 14, 2006 
 * @author wseyler
 */

package org.pentaho.platform.uifoundation.component.xml;

import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TreeMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.pentaho.platform.api.engine.IAclSolutionFile;
import org.pentaho.platform.api.engine.IParameterProvider;
import org.pentaho.platform.api.engine.IPentahoSession;
import org.pentaho.platform.api.engine.IPentahoUrlFactory;
import org.pentaho.platform.api.engine.IPermissionMask;
import org.pentaho.platform.api.engine.IPermissionRecipient;
import org.pentaho.platform.api.engine.ISolutionFile;
import org.pentaho.platform.api.engine.IUserDetailsRoleListService;
import org.pentaho.platform.api.engine.PentahoAccessControlException;
import org.pentaho.platform.api.repository.ISolutionRepository;
import org.pentaho.platform.engine.core.system.PentahoSystem;
import org.pentaho.platform.engine.security.SimplePermissionMask;
import org.pentaho.platform.engine.security.SimpleRole;
import org.pentaho.platform.engine.security.SimpleUser;
import org.pentaho.platform.engine.security.acls.PentahoAclEntry;
import org.pentaho.platform.repository.hibernate.HibernateUtil;
import org.pentaho.platform.uifoundation.messages.Messages;

/**
 * TODO mlowery Need to remove direct references to PentahoAclEntry permission constants. Instead, reference 
 * ISolutionRepository permission constants.
 */
public class PropertiesPanelUIComponent extends XmlComponent {

    private static final long serialVersionUID = 1L;

    private static final Log logger = LogFactory.getLog(PropertiesPanelUIComponent.class);

    private static final String TYPE_PARAM = "type"; //$NON-NLS-1$

    private static final String ACTION_PARAM = "action"; //$NON-NLS-1$

    private static final String ADD_NAME_PARAM = "add_name"; //$NON-NLS-1$

    private static final String PATH_PARAM = "path"; //$NON-NLS-1$

    private static final String LIST_ACTION = "list"; //$NON-NLS-1$

    private static final String ADD_BTN_PARAM = "addBtn"; //$NON-NLS-1$

    private static final String UPDATE_BTN_PARAM = "updateBtn"; //$NON-NLS-1$

    private static final String ROLE_TYPE = "role"; //$NON-NLS-1$

    private static final String PERM_TYPE = "perm"; //$NON-NLS-1$

    private static final String ROLE_PREFIX = PropertiesPanelUIComponent.ROLE_TYPE + "_"; //$NON-NLS-1$
    // NOTE: not related to PentahoAclEntry.PERMISSION_PREFIX
    private static final String PERMISSION_PREFIX = PropertiesPanelUIComponent.PERM_TYPE + "_"; //$NON-NLS-1$

    private static final String USER_TYPE = "user"; //$NON-NLS-1$

    private static final String USER_PREFIX = PropertiesPanelUIComponent.USER_TYPE + "_"; //$NON-NLS-1$

    private static final String PERMISSION_SEPERATOR = "#"; //$NON-NLS-1$

    private static final String DELETE_PREFIX = "delete_"; //$NON-NLS-1$

    private static final String NO_FILE_PATH_NODE_NAME = "no-file-path"; //$NON-NLS-1$

    private static final String SET_PERMISSIONS_DENIED_NAME = "set-permissions-denied"; //$NON-NLS-1$

    private static final String NO_ACLS_NODE_NAME = "no-acls"; //$NON-NLS-1$

    private static final String INPUT_PAGE_NODE_NAME = "input-page"; //$NON-NLS-1$

    private static final String FILE_PATH_NODE_NAME = "file-path"; //$NON-NLS-1$

    private static final String IS_DIR_NODE_NAME = "is-directory"; //$NON-NLS-1$

    private static final String RECIPIENTS_NODE_NAME = "recipients"; //$NON-NLS-1$

    private static final String ROLE_NODE_NAME = "role"; //$NON-NLS-1$

    private static final String USER_NODE_NAME = "user"; //$NON-NLS-1$

    private static final String PERMISSION_NAMES_NODE_NAME = "permission-names"; //$NON-NLS-1$

    private static final String NAME_NODE_NAME = "name"; //$NON-NLS-1$

    private static final String ACCESS_CONTROL_LIST_NODE_NAME = "ac-list"; //$NON-NLS-1$

    private static final String ACCESS_CONTROL_NODE_NAME = "access-control"; //$NON-NLS-1$

    private static final String RECIPIENT_NODE_NAME = "recipient"; //$NON-NLS-1$

    private static final String PERMISSION_NODE_NAME = "permission"; //$NON-NLS-1$

    private static final String PERMITTED_NODE_NAME = "permitted"; //$NON-NLS-1$

    private static final String EMPTY_STRING = ""; //$NON-NLS-1$

    private static final String TRUE = "true"; //$NON-NLS-1$

    private static final String FALSE = "false"; //$NON-NLS-1$

    private static final String ON = "on"; //$NON-NLS-1$

    private static final String DISPLAY_PATH_NODE_NAME = "display-path"; //$NON-NLS-1$

    protected IPentahoSession session = null;

    protected String baseUrl = null;

    boolean includeUsers = PentahoSystem.getSystemSetting("access-ui/include-users", "true").equals("true"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

    boolean includeRoles = PentahoSystem.getSystemSetting("access-ui/include-roles", "true").equals("true"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

    protected ISolutionRepository repository;

    private List allUsersList;

    private List allRolesList;

    protected IUserDetailsRoleListService userDetailsRoleListService;

    public PropertiesPanelUIComponent(final IPentahoUrlFactory urlFactory, final List messages,
            final IPentahoSession session) {
        super(urlFactory, messages, null);
        this.session = session;
        setXsl("text/html", "PropertiesPanel.xsl"); //$NON-NLS-1$ //$NON-NLS-2$
        setXslProperty("baseUrl", urlFactory.getDisplayUrlBuilder().getUrl()); //$NON-NLS-1$ 
        repository = PentahoSystem.get(ISolutionRepository.class, session);
        if (!repository.supportsAccessControls()) {
            error(Messages.getString("PropertiesPanelUIComponent.ERROR_0001_BAD_CONFIGURATION")); //$NON-NLS-1$
        }
        userDetailsRoleListService = PentahoSystem.getUserDetailsRoleListService();
    }

    @Override
    public Document getXmlContent() {
        if (!repository.supportsAccessControls()) {
            return noACLSPage();
        }

        String actionStr = this.getParameter(PropertiesPanelUIComponent.ACTION_PARAM,
                PropertiesPanelUIComponent.EMPTY_STRING); // No
        // nulls
        String pathStr = this.getParameter(PropertiesPanelUIComponent.PATH_PARAM, null);
        ISolutionFile file = null;
        try {
            HibernateUtil.beginTransaction();
            file = repository.getSolutionFile(pathStr, ISolutionRepository.ACTION_EXECUTE);
        } catch (Exception e) {
            // do nothing since we want file to be null if it wasn't found
            // TODO sbarkdull, arg, let's at least log it
        }

        // default action if none is passed is to list (showInputPage) the acls
        if ((actionStr == null) || actionStr.equalsIgnoreCase(PropertiesPanelUIComponent.LIST_ACTION)
                || actionStr.equalsIgnoreCase(PropertiesPanelUIComponent.EMPTY_STRING)) {
            HibernateUtil.commitTransaction();
            if (file != null) {
                return showInputPage(file);
            }
            return noPathPage();
        } else {
            IParameterProvider request = ((IParameterProvider) getParameterProviders()
                    .get(IParameterProvider.SCOPE_REQUEST));
            if ((request.getParameter(PropertiesPanelUIComponent.ADD_BTN_PARAM) != null)
                    && !request.getParameter(PropertiesPanelUIComponent.ADD_BTN_PARAM).equals("")) { //$NON-NLS-1$
                doAddToAcls(file);
            }
            try {
                if ((request.getParameter(PropertiesPanelUIComponent.UPDATE_BTN_PARAM) != null)
                        && !request.getParameter(PropertiesPanelUIComponent.UPDATE_BTN_PARAM).equals("")) { //$NON-NLS-1$
                    doUpdateAcls(file);
                }
            } catch (PentahoAccessControlException e) {
                HibernateUtil.rollbackTransaction();
                return setPermissionsFailedPage(e.getLocalizedMessage());
            }
            HibernateUtil.commitTransaction();
            repository.resetRepository();
            if (file != null) {
                return showInputPage(file);
            }
            return noPathPage();
        }
    }

    private void doUpdateAcls(final ISolutionFile file) throws PentahoAccessControlException {
        IParameterProvider request = ((IParameterProvider) getParameterProviders()
                .get(IParameterProvider.SCOPE_REQUEST));

        Map permMap = new LinkedHashMap<IPermissionRecipient, IPermissionMask>();
        Iterator it = request.getParameterNames();
        while (it.hasNext()) {
            String name = (String) it.next();
            if (name.startsWith(PropertiesPanelUIComponent.USER_PREFIX)
                    || name.startsWith(PropertiesPanelUIComponent.ROLE_PREFIX)) {
                boolean isRole = name.startsWith(PropertiesPanelUIComponent.ROLE_PREFIX);
                name = name.replaceFirst(
                        isRole ? PropertiesPanelUIComponent.ROLE_PREFIX : PropertiesPanelUIComponent.USER_PREFIX,
                        PropertiesPanelUIComponent.EMPTY_STRING);
                String lineNumber = name.substring(name.lastIndexOf('_') + 1);
                name = name.substring(0, name.lastIndexOf('_'));
                if (!isFlaggedForDelete(name)) { // If this is one being deleted we don't do anything with it
                    IPermissionRecipient permissionRecipient = isRole ? new SimpleRole(name) : new SimpleUser(name);
                    SimplePermissionMask permissionMask = new SimplePermissionMask();
                    Iterator it1 = request.getParameterNames();
                    while (it1.hasNext()) {
                        String perm = (String) it1.next();
                        if (perm.startsWith(PropertiesPanelUIComponent.PERMISSION_PREFIX)) {
                            perm = perm.replaceFirst(PropertiesPanelUIComponent.PERMISSION_PREFIX,
                                    PropertiesPanelUIComponent.EMPTY_STRING);
                            String permNumber = perm.substring(perm.lastIndexOf('_') + 1);
                            if (permNumber.equals(lineNumber)) { // Congratulation... we have a winner!
                                perm = perm.substring(0, perm.lastIndexOf('_'));
                                permissionMask.addPermission(
                                        ((Integer) PentahoAclEntry.getValidPermissionsNameMap().get(perm))
                                                .intValue());
                            }
                        }
                    }
                    permMap.put(permissionRecipient, permissionMask);
                }
            }
        }
        if (file instanceof IAclSolutionFile) {
            repository.setPermissions(file, permMap);
        }
    }

    private boolean isFlaggedForDelete(final String name) {
        IParameterProvider request = ((IParameterProvider) getParameterProviders()
                .get(IParameterProvider.SCOPE_REQUEST));
        return PropertiesPanelUIComponent.ON.equalsIgnoreCase(
                request.getStringParameter(PropertiesPanelUIComponent.DELETE_PREFIX + name, null));
    }

    private void doAddToAcls(final ISolutionFile file) {
        IParameterProvider request = ((IParameterProvider) getParameterProviders()
                .get(IParameterProvider.SCOPE_REQUEST));

        String[] names = request.getStringArrayParameter(PropertiesPanelUIComponent.ADD_NAME_PARAM,
                new String[] {});

        for (String name : names) {
            IPermissionRecipient permissionRecipient = null;
            if (name.startsWith(PropertiesPanelUIComponent.ROLE_PREFIX)) {
                permissionRecipient = new SimpleRole(name.replaceFirst(PropertiesPanelUIComponent.ROLE_PREFIX,
                        PropertiesPanelUIComponent.EMPTY_STRING));
            } else {
                permissionRecipient = new SimpleUser(name.replaceFirst(PropertiesPanelUIComponent.USER_PREFIX,
                        PropertiesPanelUIComponent.EMPTY_STRING));
            }

            SimplePermissionMask permissionMask = new SimplePermissionMask();
            Iterator it = request.getParameterNames();
            while (it.hasNext()) {
                String paramName = it.next().toString();
                if (paramName.startsWith(PropertiesPanelUIComponent.PERMISSION_PREFIX)) {
                    String permKey = paramName.replaceFirst(PropertiesPanelUIComponent.PERMISSION_PREFIX,
                            PropertiesPanelUIComponent.EMPTY_STRING);
                    StringTokenizer tokenizer = new StringTokenizer(permKey,
                            PropertiesPanelUIComponent.PERMISSION_SEPERATOR);
                    String permName = tokenizer.nextToken();
                    String perm = tokenizer.nextToken();

                    if (permName.equals("Untitled-0")) { //$NON-NLS-1$
                        permissionMask.addPermission(
                                ((Integer) PentahoAclEntry.getValidPermissionsNameMap().get(perm)).intValue());
                    }
                }
            }
            if (file instanceof IAclSolutionFile) {
                repository.addPermission(file, permissionRecipient, permissionMask);
            }
        }
    }

    private Document noPathPage() {
        Document document = DocumentHelper.createDocument();
        document.addElement(PropertiesPanelUIComponent.NO_FILE_PATH_NODE_NAME)
                .addText(Messages.getString("PropertiesPanelUIComponent.USER_NO_FILE_SELECTED")); //$NON-NLS-1$

        return document;
    }

    private Document setPermissionsFailedPage(final String msg) {
        Document document = DocumentHelper.createDocument();
        document.addElement(PropertiesPanelUIComponent.SET_PERMISSIONS_DENIED_NAME).addText(msg);

        return document;
    }

    private Document noACLSPage() {
        Document document = DocumentHelper.createDocument();
        document.addElement(PropertiesPanelUIComponent.NO_ACLS_NODE_NAME)
                .addText(Messages.getString("PropertiesPanelUIComponent.ERROR_0001_BAD_CONFIGURATION")); //$NON-NLS-1$

        return document;
    }

    protected Document showInputPage(final ISolutionFile file) {
        Document document = DocumentHelper.createDocument();
        Element root = document.addElement(PropertiesPanelUIComponent.INPUT_PAGE_NODE_NAME)
                .addText(file.getFullPath());

        // Add the info for the file we're working on
        root.addElement(PropertiesPanelUIComponent.FILE_PATH_NODE_NAME).addText(file.getFullPath());
        root.addElement(PropertiesPanelUIComponent.DISPLAY_PATH_NODE_NAME)
                .addText(file.getFullPath()
                        .replaceFirst(repository.getRepositoryName(), PropertiesPanelUIComponent.EMPTY_STRING)
                        .replaceFirst("//", "/")); //$NON-NLS-1$//$NON-NLS-2$
        root.addElement(PropertiesPanelUIComponent.IS_DIR_NODE_NAME)
                .addText(file.isDirectory() ? PropertiesPanelUIComponent.TRUE : PropertiesPanelUIComponent.FALSE);
        Element recipients = root.addElement(PropertiesPanelUIComponent.RECIPIENTS_NODE_NAME);

        Iterator iter = null;
        if (includeRoles) {
            // Add all the possible roles
            List rList = getAllRolesList();
            if (rList != null) {
                iter = rList.iterator();
                while (iter.hasNext()) {
                    recipients.addElement(PropertiesPanelUIComponent.ROLE_NODE_NAME)
                            .addText(iter.next().toString());
                }
            }
        }
        if (includeUsers) {
            // Add all the possible users
            List uList = getAllUsersList();
            if (uList != null) {
                iter = uList.iterator();
                while (iter.hasNext()) {
                    recipients.addElement(PropertiesPanelUIComponent.USER_NODE_NAME)
                            .addText(iter.next().toString());
                }
            }
        }
        // Add the names of all the permissions
        Map permissionsMap = PentahoAclEntry.getValidPermissionsNameMap();
        // permissionsMap.remove(Messages.getString("PentahoAclEntry.USER_SUBSCRIBE")); //$NON-NLS-1$
        Iterator keyIter = permissionsMap.keySet().iterator();
        Element permNames = root.addElement(PropertiesPanelUIComponent.PERMISSION_NAMES_NODE_NAME);
        while (keyIter.hasNext()) {
            permNames.addElement(PropertiesPanelUIComponent.NAME_NODE_NAME).addText(keyIter.next().toString());
        }

        Element acListNode = root.addElement(PropertiesPanelUIComponent.ACCESS_CONTROL_LIST_NODE_NAME);
        TreeMap<IPermissionRecipient, IPermissionMask> sortedMap = new TreeMap<IPermissionRecipient, IPermissionMask>(
                new Comparator<IPermissionRecipient>() {
                    public int compare(IPermissionRecipient arg0, IPermissionRecipient arg1) {
                        return arg0.getName().compareTo(arg1.getName());
                    }
                });
        sortedMap.putAll(repository.getPermissions(file));
        for (Map.Entry<IPermissionRecipient, IPermissionMask> mapEntry : sortedMap.entrySet()) {
            IPermissionRecipient permissionRecipient = mapEntry.getKey();
            Element acNode = acListNode.addElement(PropertiesPanelUIComponent.ACCESS_CONTROL_NODE_NAME);
            Element recipientNode = acNode.addElement(PropertiesPanelUIComponent.RECIPIENT_NODE_NAME);
            recipientNode.setText(permissionRecipient.getName());
            recipientNode.addAttribute(PropertiesPanelUIComponent.TYPE_PARAM,
                    (permissionRecipient instanceof SimpleRole) ? PropertiesPanelUIComponent.ROLE_TYPE
                            : PropertiesPanelUIComponent.USER_TYPE);
            // Add individual permissions for this group
            for (Iterator keyIterator = permissionsMap.keySet().iterator(); keyIterator.hasNext();) {
                Element aPermission = acNode.addElement(PropertiesPanelUIComponent.PERMISSION_NODE_NAME);
                String permName = keyIterator.next().toString();
                aPermission.addElement(PropertiesPanelUIComponent.NAME_NODE_NAME).setText(permName);
                int permMask = ((Integer) permissionsMap.get(permName)).intValue();
                //        boolean isPermitted = repository.hasAccess(permissionRecipient, file, permMask);
                //        broken on purpose
                boolean isPermitted = false;
                aPermission.addElement(PropertiesPanelUIComponent.PERMITTED_NODE_NAME)
                        .addText(isPermitted ? PropertiesPanelUIComponent.TRUE : PropertiesPanelUIComponent.FALSE);
            }
        }
        return document;
    }

    public static void main(String[] args) {

    }

    public List getAllUsersList() {
        if (allUsersList == null) {
            allUsersList = userDetailsRoleListService.getAllUsers();
        }
        return allUsersList;
    }

    public List getAllRolesList() {
        if (allRolesList == null) {
            allRolesList = userDetailsRoleListService.getAllRoles();
        }
        return allRolesList;
    }

    @Override
    public Log getLogger() {
        return PropertiesPanelUIComponent.logger;
    }

    @Override
    public boolean validate() {
        return true;
    }
}