org.jboss.dashboard.workspace.CopyManagerImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.dashboard.workspace.CopyManagerImpl.java

Source

/**
 * Copyright (C) 2012 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jboss.dashboard.workspace;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.jboss.dashboard.SecurityServices;
import org.jboss.dashboard.database.hibernate.HibernateTxFragment;
import org.jboss.dashboard.security.*;
import org.jboss.dashboard.ui.UIServices;
import org.jboss.dashboard.ui.panel.PanelDriver;
import org.jboss.dashboard.ui.resources.GraphicElement;
import org.jboss.dashboard.workspace.copyoptions.CopyOption;
import org.jboss.dashboard.workspace.copyoptions.SectionCopyOption;
import org.jboss.dashboard.workspace.events.EventConstants;
import org.jboss.dashboard.workspace.events.WorkspaceDuplicationEvent;
import org.jboss.dashboard.workspace.events.WorkspaceListener;

import javax.enterprise.context.ApplicationScoped;
import java.lang.reflect.Method;
import java.security.Permission;
import java.security.Principal;
import java.util.*;

@ApplicationScoped
public class CopyManagerImpl implements CopyManager {

    /**
     * Logger
     */
    private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CopyManagerImpl.class.getName());

    public PanelInstance copy(final PanelInstance panelInstance, final WorkspaceImpl workspace) throws Exception {

        final PanelInstance[] results = new PanelInstance[] { null };
        HibernateTxFragment txFragment = new HibernateTxFragment() {
            protected void txFragment(Session session) throws Exception {
                log.debug("Copying PanelInstance " + panelInstance.getId() + " to Workspace " + workspace.getId());
                PanelInstance panelInstanceCopy = (PanelInstance) panelInstance.clone();
                panelInstanceCopy.setWorkspace(workspace);
                if (workspace.getId().equals(panelInstance.getWorkspace().getId())) {//Instance in same workspace-> can't reuse the id
                    panelInstanceCopy.setInstanceId(null);
                }

                // Store panel instance.
                if (log.isDebugEnabled())
                    log.debug("Storing panelInstance copy " + panelInstanceCopy);
                UIServices.lookup().getPanelsManager().store(panelInstanceCopy);

                log.debug("Setting PanelInstance parameters.");
                Set<PanelParameter> panelParams = panelInstance.getPanelParams();
                if (panelParams != null) {
                    Set<PanelParameter> paramsClone = new HashSet<PanelParameter>();
                    for (PanelParameter param : panelParams) {
                        log.debug("Copying parameter " + param);
                        PanelParameter paramClone = (PanelParameter) param.clone();
                        paramClone.setPanelInstance(panelInstanceCopy);
                        paramsClone.add(paramClone);
                    }
                    panelInstanceCopy.setPanelParams(paramsClone);
                }

                // Store panel instance with parameters.
                log.debug("Storing panelInstance copy with parameters");
                UIServices.lookup().getPanelsManager().store(panelInstanceCopy);

                panelInstanceCopy.init();

                copyPermissions(panelInstance, panelInstanceCopy);
                copyResources(panelInstance, panelInstanceCopy);

                //Internal data
                PanelDriver driver = panelInstance.getProvider().getDriver();
                try {
                    driver.replicateData(panelInstance, panelInstanceCopy);
                } catch (Exception e) {
                    log.warn("Cannot replicate data for PanelInstance " + panelInstance.getId()
                            + ". Method replicateData(PanelInstance src, PanelInstance des), throwed exception.",
                            e);
                    //TODO: Think of a way to inform the cloner which panels failed to copy, and prompt to accept the clonated workspace or delete it.
                }
                workspace.addPanelInstance(panelInstanceCopy);
                UIServices.lookup().getWorkspacesManager().store(workspace);
                log.debug("PanelInstance with id " + panelInstance.getId() + " has been copied to id "
                        + panelInstanceCopy.getId());
                results[0] = panelInstanceCopy;
            }
        };

        txFragment.execute();
        return results[0];
    }

    public Panel copy(final Panel panel, final Section section, final LayoutRegion region) throws Exception {
        return copy(panel, section, region, panel.getInstance());
    }

    public Panel copy(final Panel panel, final Section section, final LayoutRegion region,
            final PanelInstance instance) throws Exception {
        log.debug("Copying panel " + panel.getPanelId());

        final Panel[] results = new Panel[] { null };
        HibernateTxFragment txFragment = new HibernateTxFragment() {
            protected void txFragment(Session session) throws Exception {
                Section panelSection = section;
                LayoutRegion panelRegion = region;
                if (section == null)
                    panelSection = panel.getSection();//Same section
                if (region == null)
                    panelRegion = panel.getRegion(); //Same region

                // Clone panel
                Panel panelCopy = (Panel) panel.clone();
                panelCopy.setSection(panelSection);
                panelCopy.setInstanceId(instance.getInstanceId());
                panelCopy.getProvider().getDriver().fireBeforePanelPlacedInRegion(panelCopy, panelRegion);
                if (region != null)
                    panelCopy.setLayoutRegionId(panelRegion.getId());

                if (section.getId().equals(panel.getSection().getId())
                        && section.getWorkspace().getId().equals(panel.getWorkspace().getId())) {//Panel in same section -> can't reuse the id
                    panelCopy.setPanelId(null);
                }

                // Store the panel in order to ensure it an id is generated for it before assign the panel to the section.
                UIServices.lookup().getPanelsManager().store(panelCopy);

                // Add panel to section
                panelSection.assignPanel(panelCopy, panelRegion);
                UIServices.lookup().getSectionsManager().store(section);
                panelCopy.getProvider().getDriver().fireAfterPanelPlacedInRegion(panelCopy, null);
                log.debug("Panel " + panel.getPanelId() + " was copied to panel " + panelCopy.getPanelId());
                results[0] = panelCopy;

                //Copy resources
                copyResources(panel, panelCopy);
            }
        };

        txFragment.execute();
        return results[0];
    }

    public Section copy(final Section section, final WorkspaceImpl workspace, final SectionCopyOption sco)
            throws Exception {

        final Section[] results = new Section[] { null };
        HibernateTxFragment txFragment = new HibernateTxFragment() {
            protected void txFragment(Session session) throws Exception {
                SectionCopyOption copyOption = sco;
                log.debug("Copying section " + section.getId() + " to Workspace " + workspace.getId());
                if (copyOption == null) {
                    if (workspace.getId().equals(section.getWorkspace().getId()))
                        copyOption = CopyOption.DEFAULT_SECTION_COPY_OPTION_SAME_WORKSPACE;
                    else
                        copyOption = CopyOption.DEFAULT_SECTION_COPY_OPTION_OTHER_WORKSPACE;
                }
                Section sectionCopy = (Section) section.clone();
                sectionCopy.setPosition(-1); //Let the workspace decide the position later
                sectionCopy.setWorkspace(workspace);
                boolean copyingToSameWorkspace = workspace.getId().equals(section.getWorkspace().getId());
                if (copyingToSameWorkspace) {//Section in same workspace-> can't reuse the id
                    sectionCopy.setId(null);
                } else {//Section in different workspace-> can reuse the url
                    sectionCopy.setFriendlyUrl(section.getFriendlyUrl());
                }
                if (log.isDebugEnabled())
                    log.debug("Storing basic section copy to workspace " + workspace.getId());
                UIServices.lookup().getSectionsManager().store(sectionCopy);

                // Add to destination workspace
                if (log.isDebugEnabled())
                    log.debug("Adding cloned section (" + sectionCopy.getId() + ") to workspace "
                            + workspace.getId());
                workspace.addSection(sectionCopy);
                UIServices.lookup().getWorkspacesManager().store(workspace);

                //Resources
                copyResources(section, sectionCopy);

                // Panels inside section
                LayoutRegion[] regions = section.getLayout().getRegions();
                log.debug("Regions in section are " + Arrays.asList(regions));
                Map<String, PanelInstance> panelInstanceMappings = new HashMap<String, PanelInstance>();
                for (LayoutRegion region : regions) {
                    Panel[] panels = section.getPanels(region);
                    if (log.isDebugEnabled())
                        log.debug("Copying " + panels.length + " panels in region " + region);
                    for (int j = 0; panels != null && j < panels.length; j++) {
                        Panel panelClone = null;
                        PanelInstance instanceClone = panels[j].getInstance();
                        String panelInstanceId = panels[j].getInstanceId().toString();
                        if (copyOption.isDuplicatePanelInstance(panelInstanceId)) { //Duplicate Panel instance for this panel.
                            if (panelInstanceMappings.containsKey(panelInstanceId)) {
                                instanceClone = panelInstanceMappings.get(panelInstanceId);
                            } else {
                                instanceClone = copy(panels[j].getInstance(), workspace);
                                panelInstanceMappings.put(panelInstanceId, instanceClone);
                            }
                        }
                        panelClone = copy(panels[j], sectionCopy, null, instanceClone);
                        if (panelClone == null)
                            log.error("Panel " + panels[j].getPanelId() + " failed to copy itself to Section "
                                    + sectionCopy.getId());
                    }
                }

                copyPermissions(section, sectionCopy);
                session.flush();
                session.refresh(sectionCopy); // To fix bug 2011
                results[0] = sectionCopy;
            }
        };
        synchronized (("workspace_" + workspace.getDbid()).intern()) {
            txFragment.execute();
        }
        return results[0];
    }

    public WorkspaceImpl copy(final WorkspaceImpl workspace, final String id) throws Exception {

        final WorkspaceImpl[] results = new WorkspaceImpl[] { null };
        HibernateTxFragment txFragment = new HibernateTxFragment() {
            protected void txFragment(Session session) throws Exception {
                log.debug("Generating copy for Workspace " + workspace.getId() + "->" + id);

                WorkspaceImpl workspaceClone = (WorkspaceImpl) workspace.clone();
                workspaceClone.setId(id);
                UIServices.lookup().getWorkspacesManager().addNewWorkspace(workspaceClone);

                // HOME PAGES
                copyHomePages(workspace, workspaceClone);

                // RESOURCES
                copyResources(workspace, workspaceClone);

                // PERMISSIONS
                log.debug("Setting permissions for " + id);
                copyPermissions(workspace, workspaceClone);

                // PANEL INSTANCES
                log.debug("Copying PanelInstances from Workspace " + workspace.getId() + " to Workspace " + id);
                log.debug("Setting panelInstances for " + id);
                for (PanelInstance pi : workspace.getPanelInstancesSet()) {
                    if (!pi.getWorkspace().getId().equals(workspace.getId())) {
                        log.error("Found a panel instance in workspace, whose workspace id is different!");
                        continue;
                    }

                    log.debug("Copying panelInstance " + pi.getId());
                    copy(pi, workspaceClone);
                }
                log.debug("Storing cloned workspace.");
                UIServices.lookup().getWorkspacesManager().store(workspaceClone);

                // SECTIONS
                log.debug("Copying sections from Workspace " + workspace.getId() + " to Workspace " + id);
                Section[] sections = workspace.getAllSections();
                for (Section originalSection : sections) {
                    Section s = copy(originalSection, workspaceClone,
                            CopyOption.DEFAULT_SECTION_COPY_OPTION_SAME_WORKSPACE);
                    if (s == null)
                        log.error("Cannot copy section " + originalSection.getId());
                    else
                        log.debug("Section " + originalSection.getId() + " copied to " + s.getId());
                }

                // Register workspace
                log.debug("Storing cloned workspace.");
                UIServices.lookup().getWorkspacesManager().store(workspaceClone);
                results[0] = workspaceClone;

                //Fires the workspace duplicated event to all listeners
                List<WorkspaceListener> workspaceListeners = UIServices.lookup().getWorkspacesManager()
                        .getListeners(EventConstants.WORKSPACE_DUPLICATED);
                WorkspaceDuplicationEvent event = new WorkspaceDuplicationEvent(EventConstants.WORKSPACE_DUPLICATED,
                        workspace, workspaceClone);
                log.debug("Firing event " + event);
                for (WorkspaceListener listener : workspaceListeners) {
                    try {
                        listener.workspaceDuplicated(event);
                    } catch (Exception e) {
                        log.warn("Error firing event.", e);
                    }
                }
            }
        };

        txFragment.execute();
        return results[0];
    }

    public WorkspaceImpl copy(final WorkspaceImpl workspace) throws Exception {

        final WorkspaceImpl[] results = new WorkspaceImpl[] { null };
        HibernateTxFragment txFragment = new HibernateTxFragment() {
            protected void txFragment(Session session) throws Exception {
                String generatedId = UIServices.lookup().getWorkspacesManager().generateWorkspaceId();
                results[0] = copy(workspace, generatedId);
            }
        };

        txFragment.execute();
        return results[0];
    }

    // Internal copy methods

    protected void copyHomePages(Workspace workspace, Workspace workspaceClone) throws HibernateException {
        Set<WorkspaceHome> homePages = workspace.getWorkspaceHomes();
        if (homePages != null) {
            for (WorkspaceHome homePage : homePages) {
                WorkspaceHome newHomePage = new WorkspaceHome();
                newHomePage.setWorkspace(workspaceClone);
                newHomePage.setSectionId(homePage.getSectionId());
                newHomePage.setRoleId(homePage.getRoleId());
                workspaceClone.getWorkspaceHomes().add(newHomePage);
            }
        }
    }

    /**
     * Clones Workspace permissions. Copies own to given clone.
     *
     * @param workspace     Workspace whose permissions will be read
     * @param workspaceCopy Workspace whose permissions will be updated with the other ones
     */
    protected void copyPermissions(WorkspaceImpl workspace, WorkspaceImpl workspaceCopy) {
        try {
            log.debug("Copying workspace permissions from Workspace " + workspace.getId() + " to Workspace "
                    + workspaceCopy.getId());

            // Copy WorkspacePermission defined for the given workspace.
            copyPermissions(workspace, workspaceCopy, WorkspacePermission.class, workspaceCopy);

            // Copy SectionPermission defined for all workspace's sections.
            copyPermissions(workspace, workspaceCopy, SectionPermission.class, workspaceCopy);

            // Copy PanelPermission defined for all workspace's panels.
            copyPermissions(workspace, workspaceCopy, PanelPermission.class, workspaceCopy);
        } catch (Exception e) {
            log.error("Processing workspace clone permissions", e);
        }
    }

    /**
     * Clones Panel permissions. Copies own to given clone.
     *
     * @param panelInstance     Panel whose permissions will be read
     * @param panelInstanceCopy Panel whose permissions will be updated with the other ones
     */
    protected void copyPermissions(PanelInstance panelInstance, PanelInstance panelInstanceCopy) {
        try {
            // Copy PanelPermission defined for the given panel.
            log.debug("Copying panel permissions from PanelInstance " + panelInstance.getId() + " to PanelInstance "
                    + panelInstanceCopy.getId());
            copyPermissions(panelInstance, panelInstanceCopy, PanelPermission.class,
                    panelInstanceCopy.getWorkspace());
        } catch (Exception e) {
            log.error("Cannot clone panel instance " + panelInstance.getId() + " permissions.", e);
        }
    }

    /**
     * Clones Section permissions. Copies own to given clone.
     *
     * @param section     Section whose permissions will be read
     * @param sectionCopy Section whose permissions will be updated with the other ones
     */
    protected void copyPermissions(Section section, Section sectionCopy) {
        try {
            // Permissions
            log.debug("Copying section permissions from Section " + section.getId() + " to Section "
                    + sectionCopy.getId());
            copyPermissions(section, sectionCopy, SectionPermission.class, sectionCopy.getWorkspace());
        } catch (Exception e) {
            log.error("Cannot clone section " + section.getId() + " permissions.", e);
        }
    }

    /**
     * Copy permissions define for a given resource and assigns created copies to another resource.
     *
     * @param resource        The resource which permissions are going to be copied.
     * @param resourceCopy    The resource that is going to receive the copied permissions.
     * @param permissionClass The copy is restricted to the given permission class.
     * @param targetWorkspace    The workspace where copied resource will be stored.
     * @throws Exception
     */
    protected void copyPermissions(Object resource, Object resourceCopy,
            Class<? extends Permission> permissionClass, Workspace targetWorkspace) throws Exception {

        // First retrieve permissions (only permissionClass instances) assigned to resource.
        Policy securityPolicy = SecurityServices.lookup().getSecurityPolicy();
        Map<Principal, Permission> permissionMap = securityPolicy.getPermissions(resource, permissionClass);

        for (Principal principal : permissionMap.keySet()) {
            // Copy permission
            DefaultPermission permission = (DefaultPermission) permissionMap.get(principal);
            Method getInstance = permissionClass.getMethod("getInstance",
                    new Class<?>[] { Principal.class, Object.class });
            DefaultPermission permissionCopy = (DefaultPermission) getInstance.invoke(permissionClass,
                    new Object[] { principal, resourceCopy });
            List<String> actionList = (List) permissionClass.getField("LIST_OF_ACTIONS").get(permissionClass);
            for (String action : actionList) {
                if (permission.isActionDenied(action))
                    permissionCopy.denyAction(action);
                else if (permission.isActionGranted(action))
                    permissionCopy.grantAction(action);
                else if (permission.isActionUndefined(action))
                    permissionCopy.removeAction(action);
            }

            // Add permission to security policy if values for it have been specified.
            if (!permissionCopy.isEmpty()) {
                securityPolicy.addPermission(principal, permissionCopy);
                log.debug("Set permission for cloned workspace " + principal.getName() + " "
                        + permissionCopy.toString());
            }
            // If permission is empty then ensure that is not registered into the security policy
            else {
                securityPolicy.removePermission(principal, permissionCopy);
                log.debug("Set permission for cloned workspace: " + principal.getName() + " "
                        + permissionCopy.toString());
            }
        }
        // Make policy changes persistent
        securityPolicy.save();
    }

    protected void copyResources(Workspace workspace, Workspace workspaceClone) throws Exception {
        GraphicElementManager[] managers = UIServices.lookup().getGraphicElementManagers();
        for (GraphicElementManager manager : managers) {
            GraphicElement[] elements = manager.getElements(workspace.getId(), null, null);
            if (elements != null) {
                for (GraphicElement element : elements) {
                    GraphicElement elementClone = (GraphicElement) element.clone();
                    elementClone.setWorkspaceId(workspaceClone.getId());
                    manager.createOrUpdate(elementClone);
                }
            }
        }
    }

    protected void copyResources(Section section, Section sectionClone) throws Exception {
        GraphicElementManager[] managers = UIServices.lookup().getGraphicElementManagers();
        for (GraphicElementManager manager : managers) {
            GraphicElement[] elements = manager.getElements(section.getWorkspace().getId(), section.getId(), null);
            if (elements != null) {
                for (GraphicElement element : elements) {
                    GraphicElement elementClone = (GraphicElement) element.clone();
                    elementClone.setWorkspaceId(sectionClone.getWorkspace().getId());
                    elementClone.setSectionId(sectionClone.getId());
                    manager.createOrUpdate(elementClone);
                }
            }
        }
    }

    protected void copyResources(Panel panel, Panel panelClone) throws Exception {
        GraphicElementManager[] managers = UIServices.lookup().getGraphicElementManagers();
        for (GraphicElementManager manager : managers) {
            if (!manager.getElementScopeDescriptor().isAllowedPanel())
                continue;//Ignore manager, as it does not define elements for panels
            GraphicElement[] elements = manager.getElements(panel.getWorkspace().getId(),
                    panel.getSection().getId(), panel.getPanelId());
            if (elements != null) {
                for (GraphicElement element : elements) {
                    GraphicElement elementClone = (GraphicElement) element.clone();
                    elementClone.setWorkspaceId(panelClone.getWorkspace().getId());
                    elementClone.setSectionId(panelClone.getSection().getId());
                    elementClone.setPanelId(panel.getPanelId());
                    manager.createOrUpdate(elementClone);
                }
            }
        }
    }

    protected void copyResources(PanelInstance panel, PanelInstance panelClone) throws Exception {
        GraphicElementManager[] managers = UIServices.lookup().getGraphicElementManagers();
        for (GraphicElementManager manager : managers) {
            if (!manager.getElementScopeDescriptor().isAllowedInstance())
                continue;//Ignore manager, as it does not define elements for panel instances
            GraphicElement[] elements = manager.getElements(panel.getWorkspace().getId(), null,
                    panel.getInstanceId());
            if (elements != null) {
                for (GraphicElement element : elements) {
                    GraphicElement elementClone = (GraphicElement) element.clone();
                    elementClone.setWorkspaceId(panelClone.getWorkspace().getId());
                    elementClone.setSectionId(null);
                    elementClone.setPanelId(panel.getInstanceId());
                    manager.createOrUpdate(elementClone);
                }
            }
        }
    }
}