All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencms.workflow.CmsDefaultWorkflowManager Maven / Gradle / Ivy

Go to download

OpenCms is an enterprise-ready, easy to use website content management system based on Java and XML technology. Offering a complete set of features, OpenCms helps content managers worldwide to create and maintain beautiful websites fast and efficiently.

There is a newer version: 18.0
Show newest version
/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (C) Alkacon Software (http://www.alkacon.com)
 *
 * This library 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 2.1 of the License, or (at your option) any later version.
 *
 * This library 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.
 *
 * For further information about Alkacon Software, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.workflow;

import org.opencms.ade.publish.CmsCurrentPageProject;
import org.opencms.ade.publish.CmsDirectPublishProject;
import org.opencms.ade.publish.CmsMyChangesProject;
import org.opencms.ade.publish.CmsPublish;
import org.opencms.ade.publish.CmsRealProjectVirtualWrapper;
import org.opencms.ade.publish.I_CmsVirtualProject;
import org.opencms.ade.publish.shared.CmsProjectBean;
import org.opencms.ade.publish.shared.CmsPublishListToken;
import org.opencms.ade.publish.shared.CmsPublishOptions;
import org.opencms.ade.publish.shared.CmsPublishResource;
import org.opencms.ade.publish.shared.CmsWorkflow;
import org.opencms.ade.publish.shared.CmsWorkflowAction;
import org.opencms.ade.publish.shared.CmsWorkflowResponse;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsProject;
import org.opencms.file.CmsResource;
import org.opencms.i18n.CmsMessages;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.security.CmsOrganizationalUnit;
import org.opencms.security.CmsRole;
import org.opencms.util.CmsUUID;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.apache.commons.logging.Log;

import com.google.common.collect.Maps;

/**
 * The default implementation of the workflow manager interface, which offers only publish functionality.

*/ public class CmsDefaultWorkflowManager extends A_CmsWorkflowManager { /** The forced publish workflow action. */ public static final String ACTION_FORCE_PUBLISH = "forcepublish"; /** The publish workflow action. */ public static final String ACTION_PUBLISH = "publish"; /** Default value for the maximum number of resources in the initial publish list. */ public static int DEFAULT_RESOURCE_LIMIT = 1000; /** The parameter name for the resource limit. */ public static final String PARAM_RESOURCE_LIMIT = "resourceLimit"; /** The name for the publish action. */ public static final String WORKFLOW_PUBLISH = "WORKFLOW_PUBLISH"; /** The log instance for this class. */ private static final Log LOG = CmsLog.getLog(CmsDefaultWorkflowManager.class); /** The map of registered virtual projects. */ protected Map m_virtualProjects = Maps.newHashMap(); /** The number of resources in the initial publish list above which the resources are not being displayed to the user. */ private int m_resourceLimit = DEFAULT_RESOURCE_LIMIT; /** * Constructor.

*/ public CmsDefaultWorkflowManager() { m_virtualProjects.put(CmsCurrentPageProject.ID, new CmsCurrentPageProject()); m_virtualProjects.put(CmsMyChangesProject.ID, new CmsMyChangesProject()); m_virtualProjects.put(CmsDirectPublishProject.ID, new CmsDirectPublishProject()); } /** * Creates a project bean from a real project.

* * @param cms the CMS context * @param project the project * * @return the bean containing the project information */ public static CmsProjectBean createProjectBeanFromProject(CmsObject cms, CmsProject project) { CmsProjectBean manProj = new CmsProjectBean( project.getUuid(), project.getType().getMode(), org.opencms.ade.publish.Messages.get().getBundle(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).key( org.opencms.ade.publish.Messages.GUI_NORMAL_PROJECT_1, getOuAwareName(cms, project.getName())), project.getDescription()); return manProj; } /** * Returns the simple name if the ou is the same as the current user's ou.

* * @param cms the CMS context * @param name the fully qualified name to check * * @return the simple name if the ou is the same as the current user's ou */ protected static String getOuAwareName(CmsObject cms, String name) { String ou = CmsOrganizationalUnit.getParentFqn(name); if (ou.equals(cms.getRequestContext().getCurrentUser().getOuFqn())) { return CmsOrganizationalUnit.getSimpleName(name); } return CmsOrganizationalUnit.SEPARATOR + name; } /** * @see org.opencms.workflow.I_CmsWorkflowManager#createFormatter(org.opencms.file.CmsObject, org.opencms.ade.publish.shared.CmsWorkflow, org.opencms.ade.publish.shared.CmsPublishOptions) */ public I_CmsPublishResourceFormatter createFormatter( CmsObject cms, CmsWorkflow workflow, CmsPublishOptions options) { CmsDefaultPublishResourceFormatter formatter = new CmsDefaultPublishResourceFormatter(cms); return formatter; } /** * @see org.opencms.workflow.I_CmsWorkflowManager#executeAction(org.opencms.file.CmsObject, org.opencms.ade.publish.shared.CmsWorkflowAction, org.opencms.ade.publish.shared.CmsPublishListToken) */ public CmsWorkflowResponse executeAction(CmsObject cms, CmsWorkflowAction action, CmsPublishListToken token) throws CmsException { if (action.getAction().equals(CmsWorkflowAction.ACTION_CANCEL)) { // Don't need to get the resource list for canceling return new CmsWorkflowResponse(true, action.getAction(), null, null, null); } List resources = getWorkflowResources( cms, token.getWorkflow(), token.getOptions(), false).getWorkflowResources(); return executeAction(cms, action, token.getOptions(), resources); } /** * @see org.opencms.workflow.I_CmsWorkflowManager#executeAction(org.opencms.file.CmsObject, org.opencms.ade.publish.shared.CmsWorkflowAction, org.opencms.ade.publish.shared.CmsPublishOptions, java.util.List) */ @Override public CmsWorkflowResponse executeAction( CmsObject userCms, CmsWorkflowAction action, CmsPublishOptions options, List resources) throws CmsException { String actionKey = action.getAction(); if (CmsWorkflowAction.ACTION_CANCEL.equals(actionKey)) { return new CmsWorkflowResponse(true, actionKey, null, null, null); } else if (ACTION_PUBLISH.equals(actionKey)) { return actionPublish(userCms, options, resources); } else if (ACTION_FORCE_PUBLISH.equals(actionKey)) { return actionForcePublish(userCms, options, resources); } throw new CmsInvalidActionException(actionKey); } /** * Gets the localized label for a given CMS context and key.

* * @param cms the CMS context * @param key the localization key * * @return the localized label */ public String getLabel(CmsObject cms, String key) { CmsMessages messages = Messages.get().getBundle(getLocale(cms)); return messages.key(key); } /** * @see org.opencms.workflow.I_CmsWorkflowManager#getManageableProjects(org.opencms.file.CmsObject, java.util.Map) */ public List getManageableProjects(CmsObject cms, Map params) { List manProjs = new ArrayList(); List projects; try { projects = OpenCms.getOrgUnitManager().getAllManageableProjects(cms, "", true); } catch (CmsException e) { // should never happen LOG.error(e.getLocalizedMessage(), e); return manProjs; } for (CmsProject project : projects) { CmsProjectBean manProj = createProjectBeanFromProject(cms, project); manProjs.add(manProj); } for (I_CmsVirtualProject handler : m_virtualProjects.values()) { CmsProjectBean projectBean = handler.getProjectBean(cms, params); if (projectBean != null) { manProjs.add(projectBean); } } return manProjs; } /** * @see org.opencms.workflow.I_CmsWorkflowManager#getPublishListToken(org.opencms.file.CmsObject, org.opencms.ade.publish.shared.CmsWorkflow, org.opencms.ade.publish.shared.CmsPublishOptions) */ public CmsPublishListToken getPublishListToken(CmsObject cms, CmsWorkflow workflow, CmsPublishOptions options) { return new CmsPublishListToken(workflow, options); } /** * @see org.opencms.workflow.I_CmsWorkflowManager#getRealOrVirtualProject(org.opencms.util.CmsUUID) */ public I_CmsVirtualProject getRealOrVirtualProject(CmsUUID projectId) { I_CmsVirtualProject project = m_virtualProjects.get(projectId); if (project == null) { project = new CmsRealProjectVirtualWrapper(projectId); } return project; } /** * @see org.opencms.workflow.I_CmsWorkflowManager#getResourceLimit() */ public int getResourceLimit() { return m_resourceLimit; } /** * @see org.opencms.workflow.I_CmsWorkflowManager#getWorkflowForWorkflowProject(org.opencms.util.CmsUUID) */ public String getWorkflowForWorkflowProject(CmsUUID projectId) { return WORKFLOW_PUBLISH; } /** * @see org.opencms.workflow.I_CmsWorkflowManager#getWorkflowResources(org.opencms.file.CmsObject, org.opencms.ade.publish.shared.CmsWorkflow, org.opencms.ade.publish.shared.CmsPublishOptions, boolean) */ @Override public CmsWorkflowResources getWorkflowResources( CmsObject cms, CmsWorkflow workflow, CmsPublishOptions options, boolean canOverride) { try { List rawResourceList = new ArrayList(); I_CmsVirtualProject projectHandler = null; projectHandler = getRealOrVirtualProject(options.getProjectId()); if (projectHandler != null) { rawResourceList = projectHandler.getResources(cms, options.getParameters(), workflow.getId()); return new CmsWorkflowResources(rawResourceList); } return new CmsWorkflowResources(rawResourceList); } catch (Exception e) { LOG.error(e.getLocalizedMessage(), e); return new CmsWorkflowResources(Collections. emptyList()); } } /** * @see org.opencms.workflow.I_CmsWorkflowManager#getWorkflows(org.opencms.file.CmsObject) */ public Map getWorkflows(CmsObject cms) { Map result = new LinkedHashMap(); List actions = new ArrayList(); String publishLabel = getLabel(cms, Messages.GUI_WORKFLOW_ACTION_PUBLISH_0); CmsWorkflowAction publishAction = new CmsWorkflowAction(ACTION_PUBLISH, publishLabel, true, true); actions.add(publishAction); String workflowLabel = getLabel(cms, Messages.GUI_WORKFLOW_PUBLISH_0); CmsWorkflow publishWorkflow = new CmsWorkflow(WORKFLOW_PUBLISH, workflowLabel, actions); result.put(WORKFLOW_PUBLISH, publishWorkflow); return result; } /** * @see org.opencms.workflow.A_CmsWorkflowManager#initialize(org.opencms.file.CmsObject) */ @Override public void initialize(CmsObject adminCms) { super.initialize(adminCms); String resourceLimitStr = getParameter(PARAM_RESOURCE_LIMIT, "invalid").trim(); try { m_resourceLimit = Integer.parseInt(resourceLimitStr); } catch (NumberFormatException e) { // ignore, resource limit will remain at the default setting } } /** * The implementation of the "forcepublish" workflow action.

* * @param userCms the user CMS context * @param resources the resources which the action should process * @param options the publish options to use * @return the workflow response * * @throws CmsException if something goes wrong */ protected CmsWorkflowResponse actionForcePublish( CmsObject userCms, CmsPublishOptions options, List resources) throws CmsException { CmsPublish publish = new CmsPublish(userCms, options.getParameters()); publish.publishResources(resources); CmsWorkflowResponse response = new CmsWorkflowResponse( true, "", new ArrayList(), new ArrayList(), null); return response; } /** * The implementation of the "publish" workflow action.

* * @param userCms the user CMS context * @param options the publish options * @param resources the resources which the action should process * * @return the workflow response * @throws CmsException if something goes wrong */ protected CmsWorkflowResponse actionPublish( CmsObject userCms, CmsPublishOptions options, final List resources) throws CmsException { final CmsPublish publish = new CmsPublish(userCms, options); // use FutureTask to get the broken links, because we can then use a different thread if it takes too long final FutureTask> brokenResourcesGetter = new FutureTask>( new Callable>() { public List call() throws Exception { return publish.getBrokenResources(resources); } }); Thread brokenResourcesThread = new Thread(brokenResourcesGetter); brokenResourcesThread.start(); try { List brokenResources = brokenResourcesGetter.get(10, TimeUnit.SECONDS); if (brokenResources.size() == 0) { publish.publishResources(resources); CmsWorkflowResponse response = new CmsWorkflowResponse( true, "", new ArrayList(), new ArrayList(), null); return response; } else { String brokenResourcesLabel = getLabel(userCms, Messages.GUI_BROKEN_LINKS_0); boolean canForcePublish = OpenCms.getWorkplaceManager().getDefaultUserSettings().isAllowBrokenRelations() || OpenCms.getRoleManager().hasRole(userCms, CmsRole.VFS_MANAGER); List actions = new ArrayList(); if (canForcePublish) { String forceLabel = getLabel(userCms, Messages.GUI_WORKFLOW_ACTION_FORCE_PUBLISH_0); actions.add(new CmsWorkflowAction(ACTION_FORCE_PUBLISH, forceLabel, true, true)); } CmsWorkflowResponse response = new CmsWorkflowResponse( false, brokenResourcesLabel, brokenResources, actions, null); return response; } } catch (TimeoutException e) { // Things are taking too long, do them in a different thread and just return "OK" to the client Thread thread = new Thread() { @SuppressWarnings("synthetic-access") @Override public void run() { LOG.info( "Checking broken relations is taking too long, using a different thread for checking and publishing now."); try { // Make sure the computation is finished by calling get() without a timeout parameter // We don't need the actual result of the get(), though; we just get the set of resource paths from the validator object brokenResourcesGetter.get(); List resourcesToPublish = new ArrayList(resources); Iterator resIter = resourcesToPublish.iterator(); while (resIter.hasNext()) { CmsResource currentRes = resIter.next(); if (publish.getRelationValidator().keySet().contains(currentRes.getRootPath())) { resIter.remove(); LOG.info( "Excluding resource from publish list because relations would be broken: " + currentRes.getRootPath()); } } publish.publishResources(resourcesToPublish); } catch (Exception ex) { LOG.error(ex.getLocalizedMessage(), ex); } } }; thread.start(); CmsWorkflowResponse response = new CmsWorkflowResponse( true, "", new ArrayList(), new ArrayList(), null); return response; } catch (InterruptedException e) { // shouldn't happen; log exception LOG.error(e.getLocalizedMessage()); return null; } catch (ExecutionException e) { // shouldn't happen; log exception LOG.error(e.getLocalizedMessage()); return null; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy