diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index 7bb5f94f15..1e58fd5de7 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -1045,7 +1045,17 @@ deploy_status_partial=PARTIAL FAILURE reason=Reason snapshot=Snapshot deploy_to_help=A comma separated list of servers to deploy the website to.

Each entry can be a host name or an IP address and may also contain an RMI port number. If an RMI port number is not specified the default of {0} will be used.

Example: liveserver1, liveserver2:50900

-content_launch_date=Content Launch Date +content_launch=Content Launch +launch_date=Launch Date +expiration_date_header=Content Expiration +expiration_date=Expiration Date +expire_date_label=Expires +apply_to_all=Apply To All +set_expiration_date=Set expiration date for all modified items. +change_expiration_date_change=Note: To change individual expiration dates click the 'Change Expiration Date' action icon. +change_expiration_date_title=Change Expiration Date +change_expiration_date_desc=This dialog allows you to change the expiration date for a modified item. +expired_content_for_review=Expired Content For Review # New User Wizard messages new_user_title=New User Wizard diff --git a/config/alfresco/web-client-config-dialogs.xml b/config/alfresco/web-client-config-dialogs.xml index 7256afd7ce..e54b0161d1 100644 --- a/config/alfresco/web-client-config-dialogs.xml +++ b/config/alfresco/web-client-config-dialogs.xml @@ -185,6 +185,10 @@ + + + + + + + + diff --git a/config/alfresco/web-client-config-properties.xml b/config/alfresco/web-client-config-properties.xml index 8e1dd14b43..bedb064b3d 100644 --- a/config/alfresco/web-client-config-properties.xml +++ b/config/alfresco/web-client-config-properties.xml @@ -401,9 +401,9 @@ - + - + @@ -445,8 +445,17 @@ + + + + + + + + + - + @@ -456,4 +465,10 @@ + + + + + + diff --git a/config/alfresco/web-client-config-wcm.xml b/config/alfresco/web-client-config-wcm.xml index 18fb63915a..69c04eb082 100644 --- a/config/alfresco/web-client-config-wcm.xml +++ b/config/alfresco/web-client-config-wcm.xml @@ -9,6 +9,10 @@ wcmwf:submit + + wcmwf:changerequest + + diff --git a/source/java/org/alfresco/web/bean/dialog/DialogManager.java b/source/java/org/alfresco/web/bean/dialog/DialogManager.java index f9bc76d72e..17ae35deb3 100644 --- a/source/java/org/alfresco/web/bean/dialog/DialogManager.java +++ b/source/java/org/alfresco/web/bean/dialog/DialogManager.java @@ -51,6 +51,16 @@ public final class DialogManager private DialogState currentDialogState; private Map paramsToApply; + /** + * Sets the parameters the next dialog will initialise with + * + * @param params The parameters + */ + public void setupParameters(Map params) + { + this.paramsToApply = params; + } + /** * Action handler used to setup parameters for the dialog being launched * diff --git a/source/java/org/alfresco/web/bean/generator/DatePickerGenerator.java b/source/java/org/alfresco/web/bean/generator/DatePickerGenerator.java index fbf16ffa67..c8f3c4db90 100644 --- a/source/java/org/alfresco/web/bean/generator/DatePickerGenerator.java +++ b/source/java/org/alfresco/web/bean/generator/DatePickerGenerator.java @@ -51,6 +51,7 @@ public class DatePickerGenerator extends BaseComponentGenerator private boolean initialiseIfNull = false; private int yearCount = 30; private int startYear = Calendar.getInstance().get(Calendar.YEAR) + 2; + private String noneLabel = null; private static final String MSG_DATE = "date_pattern"; @@ -106,6 +107,27 @@ public class DatePickerGenerator extends BaseComponentGenerator this.initialiseIfNull = initialiseIfNull; } + /** + * Returns the label to use when there is no date set. + * + * @return The 'None' label to use + */ + public String getNoneLabel() + { + return this.noneLabel; + } + + /** + * Sets the label to use when there is no date set. + * Setting this to null will use the default label. + * + * @param noneLabel The 'None' label + */ + public void setNoneLabel(String noneLabel) + { + this.noneLabel = noneLabel; + } + @SuppressWarnings("unchecked") public UIComponent generate(FacesContext context, String id) { @@ -117,7 +139,11 @@ public class DatePickerGenerator extends BaseComponentGenerator component.getAttributes().put("yearCount", this.yearCount); component.getAttributes().put("initialiseIfNull", new Boolean(this.initialiseIfNull)); component.getAttributes().put("style", "margin-right: 7px;"); - + if (this.noneLabel != null) + { + component.getAttributes().put("noneLabel", this.noneLabel); + } + return component; } diff --git a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java index e0baa5c997..1bc0a1e56f 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java @@ -144,6 +144,9 @@ public class AVMBrowseBean implements IContextListener /** list of the deployment monitor ids currently executing */ private List deploymentMonitorIds = new ArrayList(); + /** List of expired paths to submit */ + private List expiredNodes = Collections.emptyList(); + /* component references */ private UIRichList foldersRichList; private UIRichList filesRichList; @@ -454,6 +457,26 @@ public class AVMBrowseBean implements IContextListener this.deploymentMonitorIds = deploymentMonitorIds; } + /** + * Returns the list of expired nodes. Used by the submit dialog to retrieve + * nodes to potentially submit when a user completes a change request + * task dealing with content expiration. + * + * @return The list of expired nodes + */ + public List getExpiredNodes() + { + return this.expiredNodes; + } + + /** + * @param expiredNodes List of nodes in the users sandbox that have expired + */ + public void setExpiredNodes(List expiredNodes) + { + this.expiredNodes = expiredNodes; + } + /** * @return list of available root webapp folders for this Web project */ @@ -829,6 +852,17 @@ public class AVMBrowseBean implements IContextListener setupSandboxActionImpl(store, username, true); } + + /** + * Setup the context for a sandbox browse action + * + * @param store The store name for the action + * @param username The authority pertinent to the action (null for staging store actions) + */ + public void setupSandboxAction(String store, String username) + { + setupSandboxActionImpl(store, username, true); + } /** * Setup the context for a sandbox browse action diff --git a/source/java/org/alfresco/web/bean/wcm/ChangeExpirationDateDialog.java b/source/java/org/alfresco/web/bean/wcm/ChangeExpirationDateDialog.java new file mode 100644 index 0000000000..0158308cb3 --- /dev/null +++ b/source/java/org/alfresco/web/bean/wcm/ChangeExpirationDateDialog.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program 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 2 + * of the License, or (at your option) any later version. + + * 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. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.web.bean.wcm; + +import java.util.Date; +import java.util.Map; + +import javax.faces.context.FacesContext; + +import org.alfresco.web.app.servlet.FacesHelper; +import org.alfresco.web.bean.dialog.BaseDialogBean; +import org.alfresco.web.bean.dialog.IDialogBean; + +/** + * Bean implementation for the Change Expiration Date dialog. + * + * @author gavinc + */ +public class ChangeExpirationDateDialog extends BaseDialogBean +{ + private String path; + private Date expirationDate; + private Map expirationDates; + + @Override + public void init(Map parameters) + { + super.init(parameters); + + this.path = parameters.get("avmpath"); + + // get hold of the "SubmitDialog" and retrieve the map of expiration dates + IDialogBean bean = (IDialogBean)FacesHelper.getManagedBean( + FacesContext.getCurrentInstance(), "SubmitDialog"); + if (bean != null) + { + SubmitDialog dialog = (SubmitDialog)bean; + this.expirationDates = dialog.getExpiredDates(); + this.expirationDate = this.expirationDates.get(this.path); + } + } + + @Override + protected String finishImpl(FacesContext context, String outcome) throws Exception + { + if (this.expirationDates != null) + { + this.expirationDates.put(this.path, this.expirationDate); + } + + return outcome; + } + + @Override + public boolean getFinishButtonDisabled() + { + return false; + } + + /** + * @return The expiration date + */ + public Date getExpirationDate() + { + return this.expirationDate; + } + + /** + * @param expirationDate The expiration date + */ + public void setExpirationDate(Date expirationDate) + { + this.expirationDate = expirationDate; + } +} diff --git a/source/java/org/alfresco/web/bean/wcm/ManageChangeRequestTaskDialog.java b/source/java/org/alfresco/web/bean/wcm/ManageChangeRequestTaskDialog.java new file mode 100644 index 0000000000..07530c8584 --- /dev/null +++ b/source/java/org/alfresco/web/bean/wcm/ManageChangeRequestTaskDialog.java @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program 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 2 + * of the License, or (at your option) any later version. + + * 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. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.web.bean.wcm; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.faces.context.FacesContext; +import javax.transaction.UserTransaction; + +import org.alfresco.model.WCMModel; +import org.alfresco.repo.avm.AVMNodeConverter; +import org.alfresco.repo.avm.wf.AVMSubmittedAspect; +import org.alfresco.sandbox.SandboxConstants; +import org.alfresco.service.cmr.avm.AVMNodeDescriptor; +import org.alfresco.service.cmr.avmsync.AVMDifference; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; +import org.alfresco.util.Pair; +import org.alfresco.web.app.AlfrescoNavigationHandler; +import org.alfresco.web.app.Application; +import org.alfresco.web.app.servlet.FacesHelper; +import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.bean.repository.User; +import org.alfresco.web.bean.workflow.ManageTaskDialog; +import org.alfresco.web.bean.workflow.WorkflowUtil; +import org.alfresco.web.ui.common.Utils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Bean implementation for the "Manage Task" dialog when dealing + * with the "Change Request" task specifically. + * + * @author gavinc + */ +public class ManageChangeRequestTaskDialog extends ManageTaskDialog +{ + protected AVMBrowseBean avmBrowseBean; + protected AVMSubmittedAspect avmSubmittedAspect; + + private final static Log logger = LogFactory.getLog(ManageChangeRequestTaskDialog.class); + + /** + * @param avmBrowseBean AVMBrowseBean instance + */ + public void setAvmBrowseBean(AVMBrowseBean avmBrowseBean) + { + this.avmBrowseBean = avmBrowseBean; + } + + /** + * Sets the avm submitted aspect service to use + * + * @param avmSubmittedAspect AVMSubmittedAspect instance + */ + public void setAvmSubmittedAspect(AVMSubmittedAspect avmSubmittedAspect) + { + this.avmSubmittedAspect = avmSubmittedAspect; + } + + @Override + public String transition() + { + String outcome = getDefaultFinishOutcome(); + + if (logger.isDebugEnabled()) + logger.debug("Transitioning change request task: " + this.task.id); + + FacesContext context = FacesContext.getCurrentInstance(); + UserTransaction tx = null; + + try + { + tx = Repository.getUserTransaction(context); + tx.begin(); + + // prepare the edited parameters for saving + Map params = WorkflowUtil.prepareTaskParams(this.taskNode); + + // update the task with the updated parameters and resources + this.workflowService.updateTask(this.task.id, params, null, null); + + // get the list of nodes that have expired (comparing workflow store to + // the users main store) + List submitPaths = new ArrayList(); + List submitNodes = new ArrayList(); + Pair pkgPath = AVMNodeConverter.ToAVMVersionPath(this.workflowPackage); + AVMNodeDescriptor pkgDesc = this.avmService.lookup(pkgPath.getFirst(), pkgPath.getSecond()); + String targetPath = pkgDesc.getIndirection(); + List diffs = this.avmSyncService.compare(pkgPath.getFirst(), + pkgPath.getSecond(), -1, targetPath, null); + for (AVMDifference diff : diffs) + { + AVMNodeDescriptor node = this.avmService.lookup(diff.getDestinationVersion(), + diff.getDestinationPath()); + if (node != null) + { + submitNodes.add(node); + submitPaths.add(diff.getDestinationPath()); + } + } + + // update the users main store with the changes from the workflow store + this.avmSyncService.update(diffs, null, false, false, true, true, null, null); + + // start the submission dialog with the list of paths to submit + if (logger.isDebugEnabled()) + logger.debug("starting submit dialog with expired paths: " + submitPaths); + + // get hold of the node ref that represents the web project the expired items + // belong to and get the name of the users main store + NodeRef userStoreNodeRef = (NodeRef)this.nodeService.getProperty( + this.workflowPackage, WCMModel.PROP_AVM_DIR_INDIRECTION); + String userStoreAvmPath = AVMNodeConverter.ToAVMVersionPath(userStoreNodeRef).getSecond(); + String userStoreName = AVMUtil.getStoreName(userStoreAvmPath); + String stagingStoreName = this.avmService.getStoreProperty(userStoreName, + SandboxConstants.PROP_WEBSITE_NAME).getStringValue(); + NodeRef webProjectRef = AVMUtil.getWebProjectNodeFromStore(stagingStoreName); + + // update the UI context to the web project + this.browseBean.clickSpace(webProjectRef); + this.avmBrowseBean.setupSandboxAction(userStoreName, + Application.getCurrentUser(context).getUserName()); + + // setup the context for the submit dialog and initialise it + this.avmBrowseBean.setExpiredNodes(submitNodes); + Map dialogParams = new HashMap(1); + dialogParams.put(SubmitDialog.PARAM_STARTED_FROM_WORKFLOW, Boolean.TRUE.toString()); + Application.getDialogManager().setupParameters(dialogParams); + + // signal the default transition to the workflow task + this.workflowService.endTask(this.task.id, null); + + // commit the changes + tx.commit(); + + // if we get this far close the task dialog and open the submit dialog + outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + + AlfrescoNavigationHandler.OUTCOME_SEPARATOR + + AlfrescoNavigationHandler.DIALOG_PREFIX + "submitSandboxItems"; + } + catch (Throwable e) + { + // rollback the transaction + try { if (tx != null) {tx.rollback();} } catch (Exception ex) {} + Utils.addErrorMessage(formatErrorMessage(e), e); + outcome = this.getErrorOutcome(e); + } + + return outcome; + } +} diff --git a/source/java/org/alfresco/web/bean/wcm/SandboxFactory.java b/source/java/org/alfresco/web/bean/wcm/SandboxFactory.java index 9edce7fa99..05298856d4 100644 --- a/source/java/org/alfresco/web/bean/wcm/SandboxFactory.java +++ b/source/java/org/alfresco/web/bean/wcm/SandboxFactory.java @@ -39,6 +39,7 @@ import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.QName; +import org.alfresco.util.DNSNameMangler; import org.alfresco.util.GUID; import org.alfresco.util.DNSNameMangler; import org.alfresco.web.bean.repository.Repository; @@ -312,7 +313,7 @@ public final class SandboxFactory * Create a workflow sandbox for the named store. * * Various store meta-data properties are set including: - * Identifier for store-types: .sandbox.author.main and .sandbox.author.preview + * Identifier for store-types: .sandbox.workflow.main and .sandbox.workflow.preview * Store-id: .sandbox-id. (unique across all stores in the sandbox) * DNS: .dns. = * Website Name: .website.name = website name @@ -328,7 +329,7 @@ public final class SandboxFactory final String stagingStoreName = AVMUtil.buildStagingStoreName(storeId); - // create the user 'main' store + // create the workflow 'main' store final String packageName = AVMUtil.STORE_WORKFLOW + "-" + GUID.generate(); final String mainStoreName = AVMUtil.buildWorkflowMainStoreName(storeId, packageName); @@ -368,14 +369,14 @@ public final class SandboxFactory // snapshot the store avmService.createSnapshot(mainStoreName, null, null); - // create the user 'preview' store + // create the workflow 'preview' store final String previewStoreName = AVMUtil.buildWorkflowPreviewStoreName(storeId, packageName); avmService.createStore(previewStoreName); if (logger.isDebugEnabled()) - logger.debug("Created user sandbox preview store: " + previewStoreName); + logger.debug("Created workflow sandbox preview store: " + previewStoreName); - // create a layered directory pointing to 'www' in the user 'main' store + // create a layered directory pointing to 'www' in the workflow 'main' store avmService.createLayeredDirectory(AVMUtil.buildStoreRootPath(mainStoreName), previewStoreName + ":/", JNDIConstants.DIR_DEFAULT_WWW); @@ -398,7 +399,7 @@ public final class SandboxFactory // The preview worfkflow store depends on the main workflow store (dist=1) tagStoreBackgroundLayer(avmService,previewStoreName, mainStoreName,1); - // The preview user store depends on the main staging store (dist=2) + // The preview workflow store depends on the main staging store (dist=2) tagStoreBackgroundLayer(avmService,previewStoreName, stagingStoreName,2); diff --git a/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java index 6b909dd884..60a38c1e9b 100644 --- a/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java @@ -45,11 +45,13 @@ import org.alfresco.model.WCMAppModel; import org.alfresco.repo.avm.AVMDAOs; import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.repo.avm.wf.AVMSubmittedAspect; +import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.avmsync.AVMDifference; import org.alfresco.service.cmr.avmsync.AVMSyncService; +import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.workflow.WorkflowDefinition; @@ -74,8 +76,8 @@ import org.alfresco.web.ui.common.Utils; import org.alfresco.web.ui.common.component.UIListItem; import org.alfresco.web.ui.wcm.WebResources; import org.alfresco.util.VirtServerUtils; - - +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; /** * Submit items for WCM workflow dialog. @@ -84,6 +86,7 @@ import org.alfresco.util.VirtServerUtils; */ public class SubmitDialog extends BaseDialogBean { + public static final String PARAM_STARTED_FROM_WORKFLOW = "startedFromWorkflow"; private static final String SPACE_ICON = "/images/icons/" + BrowseBean.SPACE_SMALL_DEFAULT + ".gif"; private static final String MSG_DELETED_ITEM = "avm_node_deleted"; private static final String MSG_ERR_WORKFLOW_CONFIG = "submit_workflow_config_error"; @@ -91,12 +94,16 @@ public class SubmitDialog extends BaseDialogBean private String comment; private String label; private String[] workflowSelectedValue; + private boolean enteringExpireDate = false; + private boolean startedFromWorkflow = false; + private Date defaultExpireDate; private Date launchDate; private List submitItems; private List warningItems; private HashSet workflows; private Map formWorkflowMap; + private Map expirationDates; private List workflowItems; // The virtualization server might need to be notified @@ -119,6 +126,8 @@ public class SubmitDialog extends BaseDialogBean /** Current workflow for dialog context */ protected WorkflowConfiguration actionWorkflow = null; + private static Log logger = LogFactory.getLog(SubmitDialog.class); + /** * @param avmService The AVM Service to set. */ @@ -181,9 +190,15 @@ public class SubmitDialog extends BaseDialogBean this.warningItems = null; this.workflowItems = null; this.workflows = new HashSet(4); + this.expirationDates = new HashMap(8); + this.defaultExpireDate = new Date(); this.workflowSelectedValue = null; this.launchDate = null; + // determine if the dialog has been started from a workflow + Boolean bool = new Boolean(this.parameters.get(PARAM_STARTED_FROM_WORKFLOW)); + this.startedFromWorkflow = bool; + // walk all the web forms attached the website, and lookup the workflow defaults for each NodeRef websiteRef = this.avmBrowseBean.getWebsite().getNodeRef(); List webFormRefs = this.nodeService.getChildAssocs( @@ -290,6 +305,9 @@ public class SubmitDialog extends BaseDialogBean srcPath.substring(srcPath.indexOf(':'),srcPath.length()); } + // process the expiration date (if any) + processExpirationDate(srcPath); + srcPaths.add(srcPath); } @@ -297,7 +315,7 @@ public class SubmitDialog extends BaseDialogBean AVMWorkflowUtil.createWorkflowPackage(srcPaths, sandboxInfo, path, - avmSubmittedAspect, + this.avmSubmittedAspect, this.avmSyncService, this.avmService, this.workflowService, @@ -356,6 +374,9 @@ public class SubmitDialog extends BaseDialogBean { this.virtUpdatePath = destPath; } + + // process the expiration date (if any) + processExpirationDate(srcPath); } // write changes to layer so files are marked as modified @@ -427,7 +448,39 @@ public class SubmitDialog extends BaseDialogBean { this.label = label; } - + + /** + * @return The default expiration date + */ + public Date getDefaultExpireDate() + { + return this.defaultExpireDate; + } + + /** + * @param defaultExpireDate The default expiration date + */ + public void setDefaultExpireDate(Date defaultExpireDate) + { + this.defaultExpireDate = defaultExpireDate; + } + + /** + * @return true if a default expiration date is being entered + */ + public boolean isEnteringExpireDate() + { + return this.enteringExpireDate; + } + + /** + * @return Map of expiration dates for the modified items + */ + public Map getExpiredDates() + { + return this.expirationDates; + } + /** * @return Returns the workflow Selected Value. */ @@ -598,32 +651,43 @@ public class SubmitDialog extends BaseDialogBean tx.begin(); List selected; - if (this.avmBrowseBean.getAllItemsAction()) + if (this.startedFromWorkflow) { - String webapp = this.avmBrowseBean.getWebapp(); - String userStore = AVMUtil.buildStoreWebappPath(this.avmBrowseBean.getSandbox(), webapp); - String stagingStore = AVMUtil.buildStoreWebappPath(this.avmBrowseBean.getStagingStore(), webapp); - List diffs = this.avmSyncService.compare(-1, userStore, -1, stagingStore, nameMatcher); - selected = new ArrayList(diffs.size()); - for (AVMDifference diff : diffs) - { - AVMNodeDescriptor node = this.avmService.lookup(-1, diff.getSourcePath(), true); - selected.add(node); - } - } - else if (this.avmBrowseBean.getAvmActionNode() == null) - { - // multiple items selected - selected = this.avmBrowseBean.getSelectedSandboxItems(); + // if the dialog was started from a workflow the AVM browse bean should + // have the list of nodes that need submitting + selected = this.avmBrowseBean.getExpiredNodes(); } else { - // single item selected - AVMNodeDescriptor node = - this.avmService.lookup(-1, this.avmBrowseBean.getAvmActionNode().getPath(), true); - selected = new ArrayList(1); - selected.add(node); + // if the dialog was started from the UI determine what nodes the user selected to submit + if (this.avmBrowseBean.getAllItemsAction()) + { + String webapp = this.avmBrowseBean.getWebapp(); + String userStore = AVMUtil.buildStoreWebappPath(this.avmBrowseBean.getSandbox(), webapp); + String stagingStore = AVMUtil.buildStoreWebappPath(this.avmBrowseBean.getStagingStore(), webapp); + List diffs = this.avmSyncService.compare(-1, userStore, -1, stagingStore, nameMatcher); + selected = new ArrayList(diffs.size()); + for (AVMDifference diff : diffs) + { + AVMNodeDescriptor node = this.avmService.lookup(-1, diff.getSourcePath(), true); + selected.add(node); + } + } + else if (this.avmBrowseBean.getAvmActionNode() == null) + { + // multiple items selected + selected = this.avmBrowseBean.getSelectedSandboxItems(); + } + else + { + // single item selected + AVMNodeDescriptor node = + this.avmService.lookup(-1, this.avmBrowseBean.getAvmActionNode().getPath(), true); + selected = new ArrayList(1); + selected.add(node); + } } + if (selected != null) { Set submittedPaths = new HashSet(selected.size()); @@ -723,6 +787,34 @@ public class SubmitDialog extends BaseDialogBean } } + /** + * Sets up the expiration date for the given source path + * + * @param srcPath The path to set the expiration date for + */ + private void processExpirationDate(String srcPath) + { + // if an expiration date has been set for this item we need to + // add the expires aspect and the date supplied + Date expirationDate = this.expirationDates.get(srcPath); + if (expirationDate != null) + { + // make sure the aspect is present + if (this.avmService.hasAspect(-1, srcPath, WCMAppModel.ASPECT_EXPIRES) == false) + { + this.avmService.addAspect(srcPath, WCMAppModel.ASPECT_EXPIRES); + } + + // set the expiration date + this.avmService.setNodeProperty(srcPath, WCMAppModel.PROP_EXPIRATIONDATE, + new PropertyValue(DataTypeDefinition.DATETIME, expirationDate)); + + if (logger.isDebugEnabled()) + logger.debug("Set expiration date of " + expirationDate + + " for " + srcPath); + } + } + /** * Action method to setup a workflow for dialog context for the current row */ @@ -757,6 +849,37 @@ public class SubmitDialog extends BaseDialogBean this.actionWorkflow = actionWorkflow; } + /** + * Applies the entered default date to all modified items + * + * @param event The event + */ + public void applyDefaultExpireDateToAll(ActionEvent event) + { + if (logger.isDebugEnabled()) + logger.debug("applying default expiration date of " + this.defaultExpireDate + " to all modified items"); + + List items = this.getSubmitItems(); + for (ItemWrapper item : items) + { + if (item.descriptor.getType() == 0) + { + this.expirationDates.put(item.descriptor.getPath(), this.defaultExpireDate); + } + } + + this.enteringExpireDate = false; + } + + /** + * Toggles the enteringExpireDate flag + * + * @param event The event + */ + public void enterExpireDate(ActionEvent event) + { + this.enteringExpireDate = true; + } /** * Simple structure class to wrap form workflow name and default parameter values @@ -866,6 +989,11 @@ public class SubmitDialog extends BaseDialogBean this.descriptor = descriptor; } + public boolean getExpirable() + { + return this.descriptor.isFile() && (this.descriptor.isDeleted() == false); + } + public boolean getDeleted() { return descriptor.isDeleted(); @@ -886,6 +1014,19 @@ public class SubmitDialog extends BaseDialogBean return ISO8601DateFormat.format(new Date(descriptor.getModDate())); } + public String getExpirationDate() + { + String expireDate = null; + + Date date = expirationDates.get(this.descriptor.getPath()); + if (date != null) + { + expireDate = ISO8601DateFormat.format(date); + } + + return expireDate; + } + public String getDescription() { if (descriptor.isDeleted() == false) @@ -904,6 +1045,11 @@ public class SubmitDialog extends BaseDialogBean return descriptor.getPath().substring(descriptor.getPath().indexOf(rootPath) + rootPath.length()); } + public String getFullPath() + { + return descriptor.getPath(); + } + public String getUrl() { return DownloadContentServlet.generateBrowserURL( diff --git a/source/java/org/alfresco/web/bean/wizard/WizardManager.java b/source/java/org/alfresco/web/bean/wizard/WizardManager.java index b76036e4b8..d3e846a710 100644 --- a/source/java/org/alfresco/web/bean/wizard/WizardManager.java +++ b/source/java/org/alfresco/web/bean/wizard/WizardManager.java @@ -61,7 +61,7 @@ public final class WizardManager private Map paramsToApply; /** - * Action handler used to setup parameters for the wizard being launched + * Sets the parameters the next wizard will initialise with * * @param params The parameters */ diff --git a/source/java/org/alfresco/web/bean/workflow/StartWorkflowWizard.java b/source/java/org/alfresco/web/bean/workflow/StartWorkflowWizard.java index 6b3f802832..08ed2eab46 100644 --- a/source/java/org/alfresco/web/bean/workflow/StartWorkflowWizard.java +++ b/source/java/org/alfresco/web/bean/workflow/StartWorkflowWizard.java @@ -675,6 +675,7 @@ public class StartWorkflowWizard extends BaseWizardBean ConfigElement config = Application.getConfigService(fc).getGlobalConfig().getConfigElement("wcm"); if (config != null) { + // get the main WCM workflows ConfigElement workflowConfig = config.getChild("workflows"); if (workflowConfig != null) { @@ -691,6 +692,23 @@ public class StartWorkflowWizard extends BaseWizardBean if (logger.isWarnEnabled()) logger.warn("WARNING: Unable to find WCM 'workflows' config element definition."); } + + // get the admin WCM workflows + ConfigElement adminWorkflowConfig = config.getChild("admin-workflows"); + if (adminWorkflowConfig != null) + { + StringTokenizer t = new StringTokenizer(adminWorkflowConfig.getValue().trim(), ", "); + while (t.hasMoreTokens()) + { + String wfName = "jbpm$" + t.nextToken(); + wcmWorkflows.put(wfName, wfName); + } + } + else + { + if (logger.isWarnEnabled()) + logger.warn("WARNING: Unable to find WCM 'admin-workflows' config element definition."); + } } else { diff --git a/source/java/org/alfresco/web/ui/common/renderer/DatePickerRenderer.java b/source/java/org/alfresco/web/ui/common/renderer/DatePickerRenderer.java index f20a1b76f8..586b2ec417 100644 --- a/source/java/org/alfresco/web/ui/common/renderer/DatePickerRenderer.java +++ b/source/java/org/alfresco/web/ui/common/renderer/DatePickerRenderer.java @@ -301,7 +301,13 @@ public class DatePickerRenderer extends BaseRenderer { out.write(" color: #666666; font-style: italic;\">"); } - out.write(Application.getMessage(context, "none")); + // work out which label to use + String noneLabel = (String)component.getAttributes().get("noneLabel"); + if (noneLabel == null || noneLabel.length() == 0) + { + noneLabel = Application.getMessage(context, "none"); + } + out.write(noneLabel); if (disabled.booleanValue() == false) { out.write(""); diff --git a/source/java/org/alfresco/web/ui/common/tag/InputDatePickerTag.java b/source/java/org/alfresco/web/ui/common/tag/InputDatePickerTag.java index 1061ff109f..a2ac7456c2 100644 --- a/source/java/org/alfresco/web/ui/common/tag/InputDatePickerTag.java +++ b/source/java/org/alfresco/web/ui/common/tag/InputDatePickerTag.java @@ -69,6 +69,7 @@ public class InputDatePickerTag extends HtmlComponentTag this.showTime = null; this.disabled = null; this.initIfNull = null; + this.noneLabel = null; } /** @@ -82,6 +83,7 @@ public class InputDatePickerTag extends HtmlComponentTag setIntProperty(component, "startYear", this.startYear); setIntProperty(component, "yearCount", this.yearCount); setStringProperty(component, "value", this.value); + setStringProperty(component, "noneLabel", this.noneLabel); setBooleanProperty(component, "showTime", this.showTime); setBooleanProperty(component, "disabled", this.disabled); setBooleanProperty(component, "initialiseIfNull", this.initIfNull); @@ -149,10 +151,21 @@ public class InputDatePickerTag extends HtmlComponentTag this.initIfNull = initialiseIfNull; } + /** + * Sets the explicit label to use when there is no date set + * + * @param noneLabel 'None' label to use + */ + public void setNoneLabel(String noneLabel) + { + this.noneLabel = noneLabel; + } + private String startYear = null; private String yearCount = null; private String value = null; private String showTime = null; private String disabled = null; private String initIfNull = null; + private String noneLabel = null; } diff --git a/source/web/WEB-INF/alfresco.tld b/source/web/WEB-INF/alfresco.tld index c826ba413b..a1e09d9fec 100644 --- a/source/web/WEB-INF/alfresco.tld +++ b/source/web/WEB-INF/alfresco.tld @@ -91,6 +91,15 @@ None button thus disallowing the user to set the date back to null. + + + noneLabel + false + true + + Label to use when there is no date currently set + + diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml index d6a5c2688c..36ad1c4caa 100644 --- a/source/web/WEB-INF/faces-config-beans.xml +++ b/source/web/WEB-INF/faces-config-beans.xml @@ -1775,6 +1775,63 @@ #{AVMSyncService} + + + + The bean that backs up the Manage Change Request Task Dialog + + ManageChangeRequestTaskDialog + org.alfresco.web.bean.wcm.ManageChangeRequestTaskDialog + session + + nodeService + #{NodeService} + + + fileFolderService + #{FileFolderService} + + + searchService + #{SearchService} + + + navigator + #{NavigationBean} + + + browseBean + #{BrowseBean} + + + dictionaryService + #{DictionaryService} + + + namespaceService + #{NamespaceService} + + + workflowService + #{WorkflowService} + + + avmService + #{AVMService} + + + avmSyncService + #{AVMSyncService} + + + avmSubmittedAspect + #{AVMSubmittedAspect} + + + avmBrowseBean + #{AVMBrowseBean} + + @@ -2936,6 +2993,15 @@ nodeService #{NodeService} + + + + + The bean that backs up the Change Expiration Date Dialog + + ChangeExpirationDateDialog + org.alfresco.web.bean.wcm.ChangeExpirationDateDialog + session diff --git a/source/web/images/icons/change_expire_date.gif b/source/web/images/icons/change_expire_date.gif new file mode 100644 index 0000000000..9b8cd14eb7 Binary files /dev/null and b/source/web/images/icons/change_expire_date.gif differ diff --git a/source/web/images/icons/change_expire_date_large.gif b/source/web/images/icons/change_expire_date_large.gif new file mode 100644 index 0000000000..fa9676a735 Binary files /dev/null and b/source/web/images/icons/change_expire_date_large.gif differ diff --git a/source/web/jsp/wcm/change-expiration-date.jsp b/source/web/jsp/wcm/change-expiration-date.jsp new file mode 100644 index 0000000000..1036d472bb --- /dev/null +++ b/source/web/jsp/wcm/change-expiration-date.jsp @@ -0,0 +1,43 @@ +<%-- + * Copyright (C) 2005-2007 Alfresco Software Limited. + + * This program 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 2 + * of the License, or (at your option) any later version. + + * 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. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" +--%> +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + +<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> +<%@ page isELIgnored="false" %> + + + + + + + + + \ No newline at end of file diff --git a/source/web/jsp/wcm/submit-dialog.jsp b/source/web/jsp/wcm/submit-dialog.jsp index cd83bac9d4..2a9b8a7833 100644 --- a/source/web/jsp/wcm/submit-dialog.jsp +++ b/source/web/jsp/wcm/submit-dialog.jsp @@ -67,10 +67,13 @@ - + + + @@ -103,18 +106,40 @@ - - + - + columnClasses="noBrColumn,rightHandColumn"> + + + + + + + + + + + + + + + + + + @@ -228,15 +253,30 @@ - <%-- Actions column --%> - + <%-- Expiration Date column --%> + - + - - + + + + <%-- Actions column --%> + + + + + + + + + +