From 1824fcc35d136c44d2d674c31abacf4aaaaf32a6 Mon Sep 17 00:00:00 2001 From: Gavin Cornwell Date: Fri, 8 Aug 2008 21:48:34 +0000 Subject: [PATCH] AVM Compare functionality added to classic (JSF) client git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@10300 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/messages/webclient.properties | 22 + config/alfresco/web-client-config-dialogs.xml | 37 + .../web/bean/wcm/AVMCompareUtils.java | 188 +++ .../web/bean/wcm/CompareSnapshotDialog.java | 192 +++ .../bean/wcm/CompareToAnySnapshotDialog.java | 268 ++++ .../wcm/CompareToCurrentSnapshotDialog.java | 74 ++ .../wcm/CompareToPreviousSnapshotDialog.java | 54 + .../ui/wcm/component/UISandboxSnapshots.java | 1136 +++++++++-------- source/web/WEB-INF/faces-config-beans.xml | 42 + .../web/images/icons/arrow_down_disabled.gif | Bin 0 -> 1071 bytes source/web/images/icons/arrow_up_disabled.gif | Bin 0 -> 1071 bytes .../web/jsp/wcm/compare-to-any-snapshot.jsp | 84 ++ .../jsp/wcm/compare-to-current-snapshot.jsp | 55 + 13 files changed, 1610 insertions(+), 542 deletions(-) create mode 100755 source/java/org/alfresco/web/bean/wcm/AVMCompareUtils.java create mode 100755 source/java/org/alfresco/web/bean/wcm/CompareSnapshotDialog.java create mode 100755 source/java/org/alfresco/web/bean/wcm/CompareToAnySnapshotDialog.java create mode 100755 source/java/org/alfresco/web/bean/wcm/CompareToCurrentSnapshotDialog.java create mode 100755 source/java/org/alfresco/web/bean/wcm/CompareToPreviousSnapshotDialog.java create mode 100755 source/web/images/icons/arrow_down_disabled.gif create mode 100755 source/web/images/icons/arrow_up_disabled.gif create mode 100755 source/web/jsp/wcm/compare-to-any-snapshot.jsp create mode 100755 source/web/jsp/wcm/compare-to-current-snapshot.jsp diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index 866a62f5ab..212752fa50 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -612,6 +612,28 @@ invite_content_step1_desc=Select the users and roles they will play for this con remove_content_user_info=To remove an invited user from this content, click Yes. content_owner=User ''{0}'' is the current owner of this content. +# AVM Compare +snapshot_compare_to_current=Compare To Current Snapshot +snapshot_compare_to_current_description=View list of modifications between snapshot ''{0}'' and current snapshot +snapshot_compare_to_previous=Compare to Previous Snapshot +snapshot_compare_to_previous_description=View list of modifications between snapshot ''{0}'' and ''{1}'' +snapshot_compare_to_any=Compare to Any Snapshot +snapshot_compare_to_any_description=View list of modifications between snapshot ''{0}'' and a user selected snapshot +store_title=Store +version_title=Version +avm_compare_newer=Newer +avm_compare_older=Older +avm_compare_conflict=Conflict +avm_compare_directory=Directory +avm_compare_same=Same +error_version_validate=Number of version is not valid +snapshot_name=Name +snapshot_path=Path +snapshot_status=Status +increment_button_hint=Next valid version +decrement_button_hint=Previous valid version +refresh_button_hint=Refresh + # System Users messages create_user=Create User change_password=Change Password diff --git a/config/alfresco/web-client-config-dialogs.xml b/config/alfresco/web-client-config-dialogs.xml index 1ddf0d3876..af73dfe4be 100644 --- a/config/alfresco/web-client-config-dialogs.xml +++ b/config/alfresco/web-client-config-dialogs.xml @@ -308,6 +308,43 @@ title-id="link_validaton_dialog_title" description-id="link_validaton_dialog_desc" /> + + + + + + + + + + + + + + + + + + diff --git a/source/java/org/alfresco/web/bean/wcm/AVMCompareUtils.java b/source/java/org/alfresco/web/bean/wcm/AVMCompareUtils.java new file mode 100755 index 0000000000..726577889e --- /dev/null +++ b/source/java/org/alfresco/web/bean/wcm/AVMCompareUtils.java @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2005-2008 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.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.faces.context.FacesContext; + +import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.service.cmr.avm.AVMStoreDescriptor; +import org.alfresco.service.cmr.avm.VersionDescriptor; +import org.alfresco.service.cmr.avmsync.AVMDifference; +import org.alfresco.service.cmr.avmsync.AVMSyncService; +import org.alfresco.util.NameMatcher; +import org.alfresco.web.app.Application; + +/** + * AVMCompare Utils + * @author ValerySh + * + */ +public class AVMCompareUtils +{ + + /** + * Get a difference map between two corresponding node trees. + * @param avmSyncService AVMSyncService + * @param srcVersion The version id for the source tree. + * @param srcPath The avm path to the source tree. + * @param dstVersion The version id for the destination tree. + * @param dstPath The avm path to the destination tree. + * @param excluder A NameMatcher used to exclude files from consideration. + * @return list of compared objects + */ + public static List> getComparedNodes(AVMSyncService avmSyncService, int srcVersion, String srcPath, int dstVersion, String dstPath, NameMatcher excluder) + { + FacesContext context = FacesContext.getCurrentInstance(); + List compare = avmSyncService.compare(srcVersion, srcPath, dstVersion, dstPath, excluder); + List> result = new ArrayList>(); + for (AVMDifference diff : compare) + { + String path = diff.getSourcePath(); + Map node = new HashMap(); + String sandboxPath = AVMUtil.getSandboxPath(path); + node.put("path", path.replaceFirst(sandboxPath, "")); + node.put("name", path.substring(path.lastIndexOf("/") + 1)); + + String status; + switch (diff.getDifferenceCode()) + { + case AVMDifference.OLDER: + status = Application.getMessage(context, "avm_compare_older"); + break; + case AVMDifference.NEWER: + status = Application.getMessage(context, "avm_compare_newer"); + break; + case AVMDifference.SAME: + status = Application.getMessage(context, "avm_compare_same"); + break; + case AVMDifference.DIRECTORY: + status = Application.getMessage(context, "avm_compare_directory"); + break; + case AVMDifference.CONFLICT: + status = Application.getMessage(context, "avm_compare_conflict"); + break; + default: + status = ""; + } + node.put("status", status); + + result.add(node); + } + return result; + } + + /** + * checks the version of the first is accessible for Store + * @param avmService AVMService + * @param name The name of the AVMStore + * @param version Version + * @return true if version is first + */ + public static boolean isFirstVersion(AVMService avmService, String name, int version) + { + boolean result = false; + List allVersions = getAllVersionID(avmService, name); + + if (version == Collections.min(allVersions)) + result = true; + return result; + } + + /** + * checks the version of the last is accessible for Store + * @param avmService AVMService + * @param name The name of the AVMStore + * @param version Version + * @return true if version is latest + */ + public static boolean isLatestVersion(AVMService avmService, String name, int version) + { + boolean result = false; + List allVersions = getAllVersionID(avmService, name); + if (version == Collections.max(allVersions)) + result = true; + return result; + } + + /** + * Get the versions id in an AVMStore + * @param avmService AVMService + * @param name The name of the AVMStore + * @return List versions id + */ + public static List getAllVersionID(AVMService avmService, String name) + { + List allVersions = new ArrayList(); + List listVersion = avmService.getStoreVersions(name); + for (VersionDescriptor vd : listVersion) + { + if ((vd.getTag() != null || AVMUtil.isUserStore(name)) && vd.getVersionID() > 2) + { + allVersions.add(vd.getVersionID()); + } + } + + return allVersions; + } + + /** Get Previous Version Id + * @param avmService AVMService + * @param name The name of the AVMStore + * @param version Current version Id + * @return Previous Version Id + */ + public static int getPrevVersionID(AVMService avmService, String name, int version) + { + List allVersions = getAllVersionID(avmService, name); + Collections.sort(allVersions); + int index = allVersions.indexOf(version); + if (index == 0) + return 0; + return allVersions.get(index - 1); + } + + /** + * Receive Stores List + * @param avmService AVMService + * @return List Stores name + */ + public static List receiveStoresList(AVMService avmService) + { + List result = new ArrayList(); + List storeDescs = avmService.getStores(); + for (AVMStoreDescriptor storeDesc : storeDescs) + { + if (!storeDesc.getCreator().equalsIgnoreCase("system") && !AVMUtil.isPreviewStore(storeDesc.getName())) + result.add(storeDesc.getName()); + } + return result; + } +} diff --git a/source/java/org/alfresco/web/bean/wcm/CompareSnapshotDialog.java b/source/java/org/alfresco/web/bean/wcm/CompareSnapshotDialog.java new file mode 100755 index 0000000000..2cdb2c0b1b --- /dev/null +++ b/source/java/org/alfresco/web/bean/wcm/CompareSnapshotDialog.java @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2005-2008 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.text.MessageFormat; +import java.util.List; +import java.util.Map; + +import javax.faces.context.FacesContext; + +import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.service.cmr.avmsync.AVMSyncService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.dialog.BaseDialogBean; +import org.alfresco.web.bean.repository.Repository; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Base class for AVMCompare dialogs + * + * @author Dmitry Lazurkin + * + */ +public abstract class CompareSnapshotDialog extends BaseDialogBean +{ + private static final Log logger = LogFactory.getLog(CompareSnapshotDialog.class); + + private static final long serialVersionUID = 5483551383286687197L; + + private final static String MSG_CLOSE = "close"; + protected AVMBrowseBean avmBrowseBean; + transient private AVMService avmService; + transient private AVMSyncService avmSyncService; + protected NodeRef websiteRef; + protected String store; + protected NodeRef webProjectRef; + protected int version; + protected String sandbox; + protected String storeRoot; + + protected boolean finished = false; + + public abstract List> getComparedNodes(); + + @Override + public void init(Map parameters) + { + super.init(parameters); + + // setup context for dialog + this.sandbox = parameters.get("sandbox"); + + String ver = parameters.get("version"); + if (ver != null && ver.length() > 0) + { + this.version = Integer.parseInt(ver); + } + else + { + this.version = -1; + } + + // get the store + this.store = parameters.get("store"); + this.storeRoot = AVMUtil.buildSandboxRootPath(this.sandbox); + + // get the web project noderef + String webProject = parameters.get("webproject"); + if (webProject == null) + { + this.webProjectRef = this.avmBrowseBean.getWebsite().getNodeRef(); + } + else + { + this.webProjectRef = new NodeRef(webProject); + } + + if (logger.isDebugEnabled()) + { + logger.debug("Initialising dialog compare snapshot: " + this.websiteRef); + } + } + + @Override + public String getContainerDescription() + { + int prev = AVMCompareUtils.getPrevVersionID(getAvmService(), sandbox, version); + return MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), getDescription()), version, prev); + } + + @Override + public String getCancelButtonLabel() + { + return Application.getMessage(FacesContext.getCurrentInstance(), MSG_CLOSE); + } + + @Override + protected String finishImpl(FacesContext context, String outcome) throws Exception + { + return outcome; + } + + /** + * Getter for avmBrowseBean + * + * @return avmBrowseBean + */ + public AVMBrowseBean getAvmBrowseBean() + { + return avmBrowseBean; + } + + /** + * Setter for avmBrowseBean + * + * @param avmBrowseBean avm browse bean + */ + public void setAvmBrowseBean(AVMBrowseBean avmBrowseBean) + { + this.avmBrowseBean = avmBrowseBean; + } + + /** + * Getter for avmService service + * + * @return avmService + */ + public AVMService getAvmService() + { + if (avmService == null) + { + avmService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getAVMService(); + } + + return avmService; + } + + /** + * Getter for avmSyncService service + * + * @return avmSyncService + */ + public AVMSyncService getAvmSyncService() + { + if (avmSyncService == null) + { + avmSyncService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getAVMSyncService(); + } + return avmSyncService; + } + + /** + * Returns description message id for AVMCompare dialog + * + * @return description message id for dialog + */ + protected abstract String getDescription(); + + /** + * Returns sandbox name + * + * @return sandbox name + */ + public String getSandbox() + { + return sandbox; + } +} diff --git a/source/java/org/alfresco/web/bean/wcm/CompareToAnySnapshotDialog.java b/source/java/org/alfresco/web/bean/wcm/CompareToAnySnapshotDialog.java new file mode 100755 index 0000000000..7469fd3d02 --- /dev/null +++ b/source/java/org/alfresco/web/bean/wcm/CompareToAnySnapshotDialog.java @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2005-2008 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.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import javax.faces.context.FacesContext; +import javax.faces.event.ActionEvent; +import javax.faces.model.SelectItem; + +import org.alfresco.web.app.Application; +import org.alfresco.web.ui.common.Utils; + +/** + * Class for compareToAnySnapshot dialog + * + * @author Dmitry Velichkevich + * @author Dmitry Lazurkin + */ +public class CompareToAnySnapshotDialog extends CompareSnapshotDialog +{ + private static final long serialVersionUID = 5483432383286687197L; + + private static final String COMPARE_TO_ANY_SNAPSHOT_DESCRIPTION_MESSAGE_TEXT_ID = "snapshot_compare_to_any_description"; + + public static final String MSG_ERROR_VERSION_NOT_VALID = "error_version_validate"; + + private int userSpecifiedVersion; + + private boolean storeChanged; + private String userSpecifiedStore; + + private String userSpecifiedRoot; + + private List availableVersionNumbers; + private int curAvailableVersionNumber; + + private boolean compare; + + /** + * Builds list of available version numbers + */ + private void buildAvailibleVersionNumbers() + { + this.curAvailableVersionNumber = -1; + this.availableVersionNumbers = AVMCompareUtils.getAllVersionID(getAvmService(), userSpecifiedStore); + } + + @Override + public void init(Map parameters) + { + super.init(parameters); + userSpecifiedStore = sandbox; + userSpecifiedRoot = storeRoot; + userSpecifiedVersion = -1; + buildAvailibleVersionNumbers(); + this.compare = true; + this.storeChanged = false; + } + + /** + * @return true if snapshot's version is correct + */ + private boolean isCorrectVersion(int userSpecVersion) + { + return userSpecVersion == -1 || availableVersionNumbers.contains(userSpecVersion); + } + + @Override + public List> getComparedNodes() + { + if (compare) + { + this.compare = false; + + List> nodes = null; + + if (isCorrectVersion(userSpecifiedVersion)) + { + nodes = AVMCompareUtils.getComparedNodes(getAvmSyncService(), version, storeRoot, userSpecifiedVersion, userSpecifiedRoot, null); + } + + return nodes; + } + else + { + return Collections.emptyList(); + } + } + + /** + * @return list of stores select items + */ + public List getStoresList() + { + List stores = AVMCompareUtils.receiveStoresList(getAvmService()); + + List result = new ArrayList(); + + for (String itemValue : stores) + { + result.add(new SelectItem(itemValue, itemValue, itemValue, false)); + } + + return result; + } + + /** + * Action listener method that sets flag for starting compare + * + * @param event action event + */ + public void refreshComparePanel(ActionEvent event) + { + this.compare = true; + } + + /** + * Getter for user specified version + * + * @return userSpecifiedVersion + */ + public int getUserSpecifiedVersion() + { + return userSpecifiedVersion; + } + + /** + * Setter for user specified version + * + * @param userSpecifiedVersion user specified version + */ + public void setUserSpecifiedVersion(int userSpecifiedVersion) + { + if (this.storeChanged == false) + { + if (this.userSpecifiedVersion != userSpecifiedVersion) + { + if (userSpecifiedVersion != -1) + { + int index = availableVersionNumbers.indexOf(userSpecifiedVersion); + if (index != -1) + { + this.curAvailableVersionNumber = index; + this.userSpecifiedVersion = userSpecifiedVersion; + } + else + { + Utils.addErrorMessage(Application.getMessage(FacesContext.getCurrentInstance(), MSG_ERROR_VERSION_NOT_VALID)); + FacesContext.getCurrentInstance().renderResponse(); + } + } + else + { + this.curAvailableVersionNumber = -1; + this.userSpecifiedVersion = -1; + } + } + } + else + { + this.storeChanged = false; + } + } + + /** + * Getter for user specified Store + * + * @return userSpecifiedStore user specified store + */ + public String getUserSpecifiedSnapshot() + { + return userSpecifiedStore; + } + + /** + * Setter for user specified snapshot + * + * @param setUserSpecifiedSnapshot user specified snapshot + */ + public void setUserSpecifiedSnapshot(String userSpecifiedSnapshot) + { + if (userSpecifiedSnapshot.equals(userSpecifiedStore) == false) + { + this.storeChanged = true; + this.userSpecifiedStore = userSpecifiedSnapshot; + this.userSpecifiedRoot = AVMUtil.buildSandboxRootPath(this.userSpecifiedStore); + this.userSpecifiedVersion = -1; + buildAvailibleVersionNumbers(); + } + } + + @Override + public String getSandbox() + { + return this.userSpecifiedStore; + } + + @Override + protected String getDescription() + { + return COMPARE_TO_ANY_SNAPSHOT_DESCRIPTION_MESSAGE_TEXT_ID; + } + + /** + * @return true if increment button for version is disabled + */ + public boolean isIncrementVersionButtonDisabled() + { + return (this.curAvailableVersionNumber + 1) == this.availableVersionNumbers.size(); + } + + /** + * @return true if decrement button for version is disabled + */ + public boolean isDecrementVersionButtonDisabled() + { + return this.curAvailableVersionNumber == -1; + } + + /** + * Increments version number + * + * @param event action event + */ + public void incrementVersion(ActionEvent event) + { + this.curAvailableVersionNumber++; + this.userSpecifiedVersion = this.availableVersionNumbers.get(this.curAvailableVersionNumber); + } + + /** + * Decrements version number + * + * @param event action event + */ + public void decrementVersion(ActionEvent event) + { + this.curAvailableVersionNumber--; + this.userSpecifiedVersion = (this.curAvailableVersionNumber != -1) ? (this.availableVersionNumbers.get(this.curAvailableVersionNumber)) : (-1); + } + +} \ No newline at end of file diff --git a/source/java/org/alfresco/web/bean/wcm/CompareToCurrentSnapshotDialog.java b/source/java/org/alfresco/web/bean/wcm/CompareToCurrentSnapshotDialog.java new file mode 100755 index 0000000000..de5f786cf0 --- /dev/null +++ b/source/java/org/alfresco/web/bean/wcm/CompareToCurrentSnapshotDialog.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2005-2008 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.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Class for compareToCurrentSnapshot dialog + * @author ValerySh + * + */ +public class CompareToCurrentSnapshotDialog extends CompareSnapshotDialog +{ + + private static final long serialVersionUID = 5483551383286687197L; + /** description for dialog */ + private static final String MSG_COMPARE_TO_CURRENT_DESCRIPTION = "snapshot_compare_to_current_description"; + + @SuppressWarnings("unused") + private static final Log logger = LogFactory.getLog(CompareToPreviousSnapshotDialog.class); + + /* + * (non-Javadoc) + * + * @see org.alfresco.web.bean.wcm.CompareSnapshot#getComparedNodes() + */ + public List> getComparedNodes() + { + if (finished) + { + finished = false; + return null; + } + finished = true; + return AVMCompareUtils.getComparedNodes(getAvmSyncService(), version, storeRoot, -1, storeRoot, null); + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.web.bean.wcm.CompareSnapshot#getDescription() + */ + protected String getDescription() + { + return MSG_COMPARE_TO_CURRENT_DESCRIPTION; + } + +} diff --git a/source/java/org/alfresco/web/bean/wcm/CompareToPreviousSnapshotDialog.java b/source/java/org/alfresco/web/bean/wcm/CompareToPreviousSnapshotDialog.java new file mode 100755 index 0000000000..bbbd8f3afa --- /dev/null +++ b/source/java/org/alfresco/web/bean/wcm/CompareToPreviousSnapshotDialog.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2005-2008 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.List; +import java.util.Map; + +/** + * Class for compareToPreviousSnapshot dialog + * + * @author ValerySh + * + */ +public class CompareToPreviousSnapshotDialog extends CompareSnapshotDialog +{ + private static final long serialVersionUID = 5483551384486687197L; + + /** description for dialog */ + private static final String MSG_COMPARE_TO_PREVIOUS_DESCRIPTION = "snapshot_compare_to_previous_description"; + + public List> getComparedNodes() + { + int prevVersion = AVMCompareUtils.getPrevVersionID(getAvmService(), sandbox, version); + return AVMCompareUtils.getComparedNodes(getAvmSyncService(), version, storeRoot, prevVersion, storeRoot, null); + } + + protected String getDescription() + { + return MSG_COMPARE_TO_PREVIOUS_DESCRIPTION; + } + +} diff --git a/source/java/org/alfresco/web/ui/wcm/component/UISandboxSnapshots.java b/source/java/org/alfresco/web/ui/wcm/component/UISandboxSnapshots.java index 5318589db4..11b35eed3a 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UISandboxSnapshots.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UISandboxSnapshots.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2008 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 @@ -15,11 +15,11 @@ * 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: + * 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.ui.wcm.component; @@ -51,6 +51,7 @@ import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.web.app.Application; import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.bean.wcm.AVMCompareUtils; import org.alfresco.web.bean.wcm.AVMUtil; import org.alfresco.web.bean.wcm.DeploymentUtil; import org.alfresco.web.ui.common.ComponentConstants; @@ -68,560 +69,611 @@ import org.springframework.web.jsf.FacesContextUtils; */ public class UISandboxSnapshots extends SelfRenderingComponent { - private static final String ACT_SNAPSHOT_PREVIEW = "snapshot_preview"; - private static final String ACT_SNAPSHOT_REVERT = "snapshot_revert"; - private static final String ACT_SNAPSHOT_DEPLOY = "snapshot_deploy"; - - private static final String REQUEST_SNAPVERSION = "_snapVer"; + private static final String ACT_SNAPSHOT_PREVIEW = "snapshot_preview"; + private static final String ACT_SNAPSHOT_REVERT = "snapshot_revert"; + private static final String ACT_SNAPSHOT_COMPARE_TO_CURRENT = "snapshot_compare_to_current"; + private static final String ACT_SNAPSHOT_COMPARE_TO_PREVIOUS = "snapshot_compare_to_previous"; + private static final String ACT_SNAPSHOT_COMPARE_TO_ANY = "snapshot_compare_to_any"; + private static final String ACT_SNAPSHOT_DEPLOY = "snapshot_deploy"; - private static Log logger = LogFactory.getLog(UISandboxSnapshots.class); - - // snapshot date filters - public static final String FILTER_DATE_ALL = "all"; - public static final String FILTER_DATE_TODAY = "today"; - public static final String FILTER_DATE_WEEK = "week"; - public static final String FILTER_DATE_MONTH = "month"; - - private static final String MSG_LABEL = "name"; - private static final String MSG_DESCRIPTION = "description"; - private static final String MSG_DATE = "date"; - private static final String MSG_USERNAME = "snapshot_submitted_by"; - private static final String MSG_VERSION = "version"; - private static final String MSG_STATUS = "status"; - private static final String MSG_ACTIONS = "actions"; - private static final String MSG_LIVE = "live"; - - /** sandbox to show snapshots for */ - private String value; - - /** date filter to use when listing snapshots */ - private String dateFilter; - - /** The snapshot version deployed and the state of that deployment */ - private int deployAttemptVersion = -1; - private String deployStatus; - - // ------------------------------------------------------------------------------ - // Component implementation - - /** - * @see javax.faces.component.UIComponent#getFamily() - */ - public String getFamily() - { - return "org.alfresco.faces.SandboxSnapshots"; - } - - public void restoreState(FacesContext context, Object state) - { - Object values[] = (Object[])state; - // standard component attributes are restored by the super class - super.restoreState(context, values[0]); - this.value = (String)values[1]; - } - - public Object saveState(FacesContext context) - { - Object values[] = new Object[2]; - // standard component attributes are saved by the super class - values[0] = super.saveState(context); - values[1] = this.value; - return values; - } - - /** - * @see javax.faces.component.UIComponentBase#getRendersChildren() - */ - public boolean getRendersChildren() - { - return true; - } - - /** - * @see javax.faces.component.UIComponentBase#encodeChildren(javax.faces.context.FacesContext) - */ - public void encodeChildren(FacesContext context) throws IOException - { - // the child components are rendered explicitly during the encodeBegin() - } - - /** - * @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext) - */ - @SuppressWarnings("unchecked") - public void encodeBegin(FacesContext context) throws IOException - { - if (isRendered() == false) - { - return; - } - - ResponseWriter out = context.getResponseWriter(); - - ResourceBundle bundle = Application.getBundle(context); - DateFormat df = Utils.getDateTimeFormat(context); - AVMService avmService = getAVMService(context); - UserTransaction tx = null; - try - { - tx = Repository.getUserTransaction(FacesContext.getCurrentInstance(), true); - tx.begin(); - - String sandbox = getValue(); - if (sandbox == null) - { - throw new IllegalArgumentException("Sandbox must be specified."); - } - - // TODO: apply tag style - removed hardcoded - out.write(""); - // header row - out.write(""); - - // get the list of snapshots we can potentially display - List versions; - String dateFilter = getDateFilter(); - if (dateFilter == null || dateFilter.equals(FILTER_DATE_ALL)) - { - versions = avmService.getStoreVersions(sandbox); - } - else - { - Date toDate = new Date(); - Date fromDate; - if (FILTER_DATE_TODAY.equals(dateFilter)) + private static final String REQUEST_SNAPVERSION = "_snapVer"; + + private static Log logger = LogFactory.getLog(UISandboxSnapshots.class); + + // snapshot date filters + public static final String FILTER_DATE_ALL = "all"; + public static final String FILTER_DATE_TODAY = "today"; + public static final String FILTER_DATE_WEEK = "week"; + public static final String FILTER_DATE_MONTH = "month"; + + private static final String MSG_LABEL = "name"; + private static final String MSG_DESCRIPTION = "description"; + private static final String MSG_DATE = "date"; + private static final String MSG_USERNAME = "snapshot_submitted_by"; + private static final String MSG_VERSION = "version"; + private static final String MSG_STATUS = "status"; + private static final String MSG_ACTIONS = "actions"; + private static final String MSG_LIVE = "live"; + + /** sandbox to show snapshots for */ + private String value; + + /** date filter to use when listing snapshots */ + private String dateFilter; + + /** The snapshot version deployed and the state of that deployment */ + private int deployAttemptVersion = -1; + private String deployStatus; + + // ------------------------------------------------------------------------------ + // Component implementation + + /** + * @see javax.faces.component.UIComponent#getFamily() + */ + public String getFamily() + { + return "org.alfresco.faces.SandboxSnapshots"; + } + + public void restoreState(FacesContext context, Object state) + { + Object values[] = (Object[]) state; + // standard component attributes are restored by the super class + super.restoreState(context, values[0]); + this.value = (String) values[1]; + } + + public Object saveState(FacesContext context) + { + Object values[] = new Object[2]; + // standard component attributes are saved by the super class + values[0] = super.saveState(context); + values[1] = this.value; + return values; + } + + /** + * @see javax.faces.component.UIComponentBase#getRendersChildren() + */ + public boolean getRendersChildren() + { + return true; + } + + /** + * @see javax.faces.component.UIComponentBase#encodeChildren(javax.faces.context.FacesContext) + */ + public void encodeChildren(FacesContext context) throws IOException + { + // the child components are rendered explicitly during the encodeBegin() + } + + /** + * @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext) + */ + @SuppressWarnings("unchecked") + public void encodeBegin(FacesContext context) throws IOException + { + if (isRendered() == false) + { + return; + } + + ResponseWriter out = context.getResponseWriter(); + + ResourceBundle bundle = Application.getBundle(context); + DateFormat df = Utils.getDateTimeFormat(context); + AVMService avmService = getAVMService(context); + UserTransaction tx = null; + try + { + tx = Repository.getUserTransaction(FacesContext.getCurrentInstance(), true); + tx.begin(); + + String sandbox = getValue(); + if (sandbox == null) { - final Calendar c = Calendar.getInstance(); - c.setTime(toDate); - c.set(Calendar.HOUR_OF_DAY, 0); - c.set(Calendar.MINUTE, 0); - c.set(Calendar.SECOND, 0); - fromDate = c.getTime(); + throw new IllegalArgumentException("Sandbox must be specified."); } - else if (FILTER_DATE_WEEK.equals(dateFilter)) + + // TODO: apply tag style - removed hardcoded + out.write("
"); - out.write(bundle.getString(MSG_LABEL)); - out.write(""); - out.write(bundle.getString(MSG_DESCRIPTION)); - out.write(""); - out.write(bundle.getString(MSG_DATE)); - out.write(""); - out.write(bundle.getString(MSG_USERNAME)); - out.write(""); - out.write(bundle.getString(MSG_VERSION)); - out.write(""); - out.write(bundle.getString(MSG_STATUS)); - out.write(""); - out.write(bundle.getString(MSG_ACTIONS)); - out.write("
"); + // header row + out.write(""); + + // get the list of snapshots we can potentially display + List versions; + String dateFilter = getDateFilter(); + if (dateFilter == null || dateFilter.equals(FILTER_DATE_ALL)) { - fromDate = new Date(toDate.getTime() - (1000L*60L*60L*24L*7L)); - } - else if (FILTER_DATE_MONTH.equals(dateFilter)) - { - fromDate = new Date(toDate.getTime() - (1000L*60L*60L*24L*30L)); + versions = avmService.getStoreVersions(sandbox); } else { - throw new IllegalArgumentException("Unknown date filter mode: " + dateFilter); + Date toDate = new Date(); + Date fromDate; + if (FILTER_DATE_TODAY.equals(dateFilter)) + { + final Calendar c = Calendar.getInstance(); + c.setTime(toDate); + c.set(Calendar.HOUR_OF_DAY, 0); + c.set(Calendar.MINUTE, 0); + c.set(Calendar.SECOND, 0); + fromDate = c.getTime(); + } + else if (FILTER_DATE_WEEK.equals(dateFilter)) + { + fromDate = new Date(toDate.getTime() - (1000L * 60L * 60L * 24L * 7L)); + } + else if (FILTER_DATE_MONTH.equals(dateFilter)) + { + fromDate = new Date(toDate.getTime() - (1000L * 60L * 60L * 24L * 30L)); + } + else + { + throw new IllegalArgumentException("Unknown date filter mode: " + dateFilter); + } + versions = avmService.getStoreVersions(sandbox, fromDate, toDate); } - versions = avmService.getStoreVersions(sandbox, fromDate, toDate); - } - - // determine whether the deploy action should be shown - boolean showDeployAction = false; - NodeRef webProjectRef = AVMUtil.getWebProjectNodeFromStore(sandbox); - List deployToServers = DeploymentUtil.findLiveServers(webProjectRef); - if (deployToServers != null && deployToServers.size() > 0) - { - showDeployAction = true; - } - - // determine the deployment status for the website - NodeService nodeService = Repository.getServiceRegistry(context).getNodeService(); - determineDeploymentStatus(context, webProjectRef, sandbox, nodeService, avmService); - - Map requestMap = context.getExternalContext().getRequestMap(); - for (int i=versions.size() - 1; i >= 0; i--) // reverse order - { - VersionDescriptor item = versions.get(i); - - // only display snapshots with a valid tag - others are system generated snapshots - if (item.getTag() != null && item.getVersionID() != 0) + + // determine whether the deploy action should be shown + boolean showDeployAction = false; + NodeRef webProjectRef = AVMUtil.getWebProjectNodeFromStore(sandbox); + List deployToServers = DeploymentUtil.findLiveServers(webProjectRef); + if (deployToServers != null && deployToServers.size() > 0) { - int version = item.getVersionID(); - - out.write(""); + showDeployAction = true; } - } - - // end table - out.write("
"); + out.write(bundle.getString(MSG_LABEL)); + out.write(""); + out.write(bundle.getString(MSG_DESCRIPTION)); + out.write(""); + out.write(bundle.getString(MSG_DATE)); + out.write(""); + out.write(bundle.getString(MSG_USERNAME)); + out.write(""); + out.write(bundle.getString(MSG_VERSION)); + out.write(""); + out.write(bundle.getString(MSG_STATUS)); + out.write(""); + out.write(bundle.getString(MSG_ACTIONS)); + out.write("
"); - out.write(item.getTag()); - out.write(""); - out.write(item.getDescription() != null ? item.getDescription() : ""); - out.write(""); - out.write(df.format(new Date(item.getCreateDate()))); - out.write(""); - out.write(item.getCreator()); - out.write(""); - out.write(Integer.toString(version)); - out.write(""); - if (version == this.deployAttemptVersion && this.deployStatus != null) - { - out.write(this.deployStatus); - } - else - { - out.write(" "); - } - out.write(""); - - // create actions for the item - - // revert action - UIActionLink action = findAction(ACT_SNAPSHOT_REVERT, sandbox); - if (action == null) - { - Map params = new HashMap(2, 1.0f); - params.put("sandbox", sandbox); - params.put("version", "#{" + REQUEST_SNAPVERSION + "}"); - action = createAction(context, sandbox, ACT_SNAPSHOT_REVERT, "/images/icons/revert.gif", - "#{AVMBrowseBean.revertSnapshot}", null, null, params); - - } - requestMap.put(REQUEST_SNAPVERSION, Integer.toString(item.getVersionID())); - Utils.encodeRecursive(context, action); - - // deploy action (if there are deployto servers specified) - if (showDeployAction) - { - out.write("  "); - action = findAction(ACT_SNAPSHOT_DEPLOY, sandbox); - if (action == null) - { - Map params = new HashMap(2, 1.0f); - params.put("version", "#{" + REQUEST_SNAPVERSION + "}"); - params.put("store", sandbox); - action = createAction(context, sandbox, ACT_SNAPSHOT_DEPLOY, "/images/icons/deploy.gif", - "#{DialogManager.setupParameters}", "dialog:deployWebsite", null, params); - } - - Utils.encodeRecursive(context, action); - } - - // TODO: restore once preview of a store by version is implemented in vserver - //out.write("  "); - /*Utils.encodeRecursive(context, aquireAction( - context, sandbox, ACT_SNAPSHOT_PREVIEW, null, - null, null)); - out.write(" ");*/ - - requestMap.remove(REQUEST_SNAPVERSION); - - out.write("
"); - - tx.commit(); - } - catch (Throwable err) - { - try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} - throw new RuntimeException(err); - } - } - - /** - * Aquire a UIActionLink component for the specified action - * - * @param fc FacesContext - * @param sandbox Root sandbox name - * @param name Action name - will be used for I18N message lookup - * @param icon Icon to display for the action - * @param actionListener Actionlistener for the action - * @param outcome Navigation outcome for the action - * - * @return UIActionLink component - */ - private UIActionLink aquireAction(FacesContext fc, String sandbox, String name, String icon, - String actionListener, String outcome) - { - return aquireAction(fc, sandbox, name, icon, actionListener, outcome, null, null); - } - - /** - * Aquire a UIActionLink component for the specified action - * - * @param fc FacesContext - * @param sandbox Root sandbox name - * @param name Action name - will be used for I18N message lookup - * @param icon Icon to display for the action - * @param actionListener Actionlistener for the action - * @param outcome Navigation outcome for the action - * @param url HREF URL for the action - * @param params Parameters name/values for the action listener args - * - * @return UIActionLink component - */ - private UIActionLink aquireAction(FacesContext fc, String sandbox, String name, String icon, - String actionListener, String outcome, String url, Map params) - { - UIActionLink action = findAction(name, sandbox); - if (action == null) - { - action = createAction(fc, sandbox, name, icon, actionListener, outcome, url, params); - } - return action; - } - - /** - * Locate a child UIActionLink component by name. - * - * @param name Of the action component to find - * @param sandbox Sandbox the action component is tied to - * - * @return UIActionLink component if found, else null if not created yet - */ - @SuppressWarnings("unchecked") - private UIActionLink findAction(String name, String sandbox) - { - UIActionLink action = null; - String actionId = name + '_' + sandbox; - if (logger.isDebugEnabled()) - logger.debug("Finding action Id: " + actionId); - for (UIComponent component : (List)getChildren()) - { - if (actionId.equals(component.getId())) - { - action = (UIActionLink)component; - if (logger.isDebugEnabled()) - logger.debug("...found action Id: " + actionId); - break; - } - } - return action; - } - - /** - * Create a UIActionLink child component. - * - * @param fc FacesContext - * @param sandbox Root sandbox name - * @param name Action name - will be used for I18N message lookup - * @param icon Icon to display for the actio n - * @param actionListener Actionlistener for the action - * @param outcome Navigation outcome for the action - * @param url HREF URL for the action - * @param params Parameters name/values for the action listener args - * - * @return UIActionLink child component - */ - @SuppressWarnings("unchecked") - private UIActionLink createAction(FacesContext fc, String sandbox, String name, String icon, - String actionListener, String outcome, String url, Map params) - { - javax.faces.application.Application facesApp = fc.getApplication(); - UIActionLink control = (UIActionLink)facesApp.createComponent(UIActions.COMPONENT_ACTIONLINK); - - String id = name + '_' + sandbox; - if (logger.isDebugEnabled()) - logger.debug("...creating action Id: " + id); - control.setRendererType(UIActions.RENDERER_ACTIONLINK); - control.setId(id); - control.setValue(Application.getMessage(fc, name)); - control.setShowLink(icon != null ? false : true); - control.setImage(icon); - - if (actionListener != null) - { - control.setActionListener(facesApp.createMethodBinding( - actionListener, UIActions.ACTION_CLASS_ARGS)); - - // add sandbox as the default action listener parameter - if (params == null) - { - UIParameter param = (UIParameter)facesApp.createComponent(ComponentConstants.JAVAX_FACES_PARAMETER); - param.setId(id + "_1"); - param.setName("sandbox"); - param.setValue(sandbox); - control.getChildren().add(param); - } - else - { - // if a specific set of parameters are supplied, then add them instead - int idIndex = 1; - for (String key : params.keySet()) + + // determine the deployment status for the website + NodeService nodeService = Repository.getServiceRegistry(context).getNodeService(); + determineDeploymentStatus(context, webProjectRef, sandbox, nodeService, avmService); + + Map requestMap = context.getExternalContext().getRequestMap(); + for (int i = versions.size() - 1; i >= 0; i--) // reverse order { - UIParameter param = (UIParameter)facesApp.createComponent(ComponentConstants.JAVAX_FACES_PARAMETER); - param.setId(id + '_' + Integer.toString(idIndex++)); - param.setName(key); - String value = params.get(key); - if (value.startsWith("#{") == true) - { - ValueBinding vb = facesApp.createValueBinding(value); - param.setValueBinding("value", vb); - } - else - { - param.setValue(params.get(key)); - } - control.getChildren().add(param); - } - } - } - if (outcome != null) - { - control.setAction(new ConstantMethodBinding(outcome)); - } - if (url != null) - { - control.setHref(url); - control.setTarget("new"); - } - - this.getChildren().add(control); - - return control; - } - - @SuppressWarnings("unchecked") - private void determineDeploymentStatus(FacesContext context, NodeRef webProjectRef, - String sandbox, NodeService nodeService, AVMService avmService) - { - // if the store property holding the last deployment id is non null a - // deployment has been attempted - PropertyValue val = avmService.getStoreProperty(sandbox, SandboxConstants.PROP_LAST_DEPLOYMENT_ID); - String attemptId = null; - - if (val != null) - { - attemptId = val.getStringValue(); - - // get the latest deployment attempt - NodeRef attempt = DeploymentUtil.findDeploymentAttempt(attemptId); - if (attempt != null) - { - // retrieve the snapshot deployed - Integer ver = (Integer)nodeService.getProperty(attempt, - WCMAppModel.PROP_DEPLOYATTEMPTVERSION); - if (ver != null) - { - this.deployAttemptVersion = ver.intValue(); - } - - // determine if all required reports are present - List selectedServers = (List)nodeService.getProperty( - attempt, WCMAppModel.PROP_DEPLOYATTEMPTSERVERS); - int numServersSelected = 0; - if (selectedServers != null) - { - numServersSelected = selectedServers.size(); - - List deployReportRefs = nodeService.getChildAssocs( - attempt, WCMAppModel.ASSOC_DEPLOYMENTREPORTS, RegexQNamePattern.MATCH_ALL); - - if (deployReportRefs.size() >= numServersSelected) - { - // the number of expected reports are present, determine the status - boolean oneOrMoreFailed = false; - boolean allFailed = true; - for (ChildAssociationRef ref : deployReportRefs) - { - NodeRef report = ref.getChildRef(); - - // get the deploy outcome - Boolean successful = (Boolean)nodeService.getProperty(report, - WCMAppModel.PROP_DEPLOYSUCCESSFUL); - - if (successful != null) - { - if (successful.booleanValue()) + VersionDescriptor item = versions.get(i); + + // only display snapshots with a valid tag - others are system generated snapshots + if (item.getTag() != null && item.getVersionID() != 0) + { + int version = item.getVersionID(); + + out.write(""); + out.write(item.getTag()); + out.write(""); + out.write(item.getDescription() != null ? item.getDescription() : ""); + out.write(""); + out.write(df.format(new Date(item.getCreateDate()))); + out.write(""); + out.write(item.getCreator()); + out.write(""); + out.write(Integer.toString(version)); + out.write(""); + if (version == this.deployAttemptVersion && this.deployStatus != null) + { + out.write(this.deployStatus); + } + else + { + out.write(" "); + } + out.write(""); + + // create actions for the item + + // revert action + UIActionLink action = findAction(ACT_SNAPSHOT_REVERT, sandbox); + if (action == null) + { + Map params = new HashMap(2, 1.0f); + params.put("sandbox", sandbox); + params.put("version", "#{" + REQUEST_SNAPVERSION + "}"); + action = createAction(context, sandbox, ACT_SNAPSHOT_REVERT, "/images/icons/revert.gif", "#{AVMBrowseBean.revertSnapshot}", null, null, params); + + } + + requestMap.put(REQUEST_SNAPVERSION, Integer.toString(item.getVersionID())); + Utils.encodeRecursive(context, action); + + // deploy action (if there are deployto servers specified) + if (showDeployAction) + { + out.write("  "); + action = findAction(ACT_SNAPSHOT_DEPLOY, sandbox); + if (action == null) { - allFailed = false; + Map params = new HashMap(2, 1.0f); + params.put("version", "#{" + REQUEST_SNAPVERSION + "}"); + params.put("store", sandbox); + action = createAction(context, sandbox, ACT_SNAPSHOT_DEPLOY, "/images/icons/deploy.gif", "#{DialogManager.setupParameters}", "dialog:deployWebsite", + null, params); + } + + Utils.encodeRecursive(context, action); + } + + // TODO: restore once preview of a store by version is implemented in vserver + // out.write("  "); + /* + * Utils.encodeRecursive(context, aquireAction( context, sandbox, ACT_SNAPSHOT_PREVIEW, null, null, null)); out.write(" "); + */ + + boolean isLatestVersion = AVMCompareUtils.isLatestVersion(avmService, sandbox, version); + // ///////////////////////////////////////////////////////////////////////// + if (!isLatestVersion) + { + + out.write("  "); + + // Compare To Current Snapshot + + action = findAction(ACT_SNAPSHOT_COMPARE_TO_CURRENT, sandbox); + if (action == null) + { + Map params = new HashMap(2, 1.0f); + params.put("sandbox", sandbox); + params.put("store", sandbox); + params.put("version", "#{" + REQUEST_SNAPVERSION + "}"); + action = createAction(context, sandbox, ACT_SNAPSHOT_COMPARE_TO_CURRENT, "/images/icons/comparetocurrent.png", "#{DialogManager.setupParameters}", + "dialog:compareToCurrentSnapshot", null, params); + + } + Utils.encodeRecursive(context, action); + } + + boolean isFirstVersion = AVMCompareUtils.isFirstVersion(avmService, sandbox, version); + if (!isFirstVersion) + { + out.write("  "); + + // Compare To previous Snapshot + action = findAction(ACT_SNAPSHOT_COMPARE_TO_PREVIOUS, sandbox); + if (action == null) + { + Map params = new HashMap(2, 1.0f); + params.put("sandbox", sandbox); + params.put("version", "#{" + REQUEST_SNAPVERSION + "}"); + action = createAction(context, sandbox, ACT_SNAPSHOT_COMPARE_TO_PREVIOUS, "/images/icons/comparetoprevious.png", "#{DialogManager.setupParameters}", + "dialog:compareToPreviousSnapshot", null, params); + + } + Utils.encodeRecursive(context, action); + } + out.write("  "); + // //Compare To Any Snapshot + action = findAction(ACT_SNAPSHOT_COMPARE_TO_ANY, sandbox); + if (action == null) + { + Map params = new HashMap(2, 1.0f); + params.put("sandbox", sandbox); + params.put("version", "#{" + REQUEST_SNAPVERSION + "}"); + action = createAction(context, sandbox, ACT_SNAPSHOT_COMPARE_TO_ANY, "/images/icons/comparetoany.png", "#{DialogManager.setupParameters}", + "dialog:compareToAnySnapshot", null, params); + + } + Utils.encodeRecursive(context, action); + requestMap.remove(REQUEST_SNAPVERSION); + + out.write(""); + } + } + + // end table + out.write(""); + + tx.commit(); + } + catch (Throwable err) + { + try + { + if (tx != null) + { + tx.rollback(); + } + } + catch (Exception tex) + { + } + throw new RuntimeException(err); + } + } + + /** + * Aquire a UIActionLink component for the specified action + * + * @param fc FacesContext + * @param sandbox Root sandbox name + * @param name Action name - will be used for I18N message lookup + * @param icon Icon to display for the action + * @param actionListener Actionlistener for the action + * @param outcome Navigation outcome for the action + * @return UIActionLink component + */ + private UIActionLink aquireAction(FacesContext fc, String sandbox, String name, String icon, String actionListener, String outcome) + { + return aquireAction(fc, sandbox, name, icon, actionListener, outcome, null, null); + } + + /** + * Aquire a UIActionLink component for the specified action + * + * @param fc FacesContext + * @param sandbox Root sandbox name + * @param name Action name - will be used for I18N message lookup + * @param icon Icon to display for the action + * @param actionListener Actionlistener for the action + * @param outcome Navigation outcome for the action + * @param url HREF URL for the action + * @param params Parameters name/values for the action listener args + * @return UIActionLink component + */ + private UIActionLink aquireAction(FacesContext fc, String sandbox, String name, String icon, String actionListener, String outcome, String url, Map params) + { + UIActionLink action = findAction(name, sandbox); + if (action == null) + { + action = createAction(fc, sandbox, name, icon, actionListener, outcome, url, params); + } + return action; + } + + /** + * Locate a child UIActionLink component by name. + * + * @param name Of the action component to find + * @param sandbox Sandbox the action component is tied to + * @return UIActionLink component if found, else null if not created yet + */ + @SuppressWarnings("unchecked") + private UIActionLink findAction(String name, String sandbox) + { + UIActionLink action = null; + String actionId = name + '_' + sandbox; + if (logger.isDebugEnabled()) + logger.debug("Finding action Id: " + actionId); + for (UIComponent component : (List) getChildren()) + { + if (actionId.equals(component.getId())) + { + action = (UIActionLink) component; + if (logger.isDebugEnabled()) + logger.debug("...found action Id: " + actionId); + break; + } + } + return action; + } + + /** + * Create a UIActionLink child component. + * + * @param fc FacesContext + * @param sandbox Root sandbox name + * @param name Action name - will be used for I18N message lookup + * @param icon Icon to display for the actio n + * @param actionListener Actionlistener for the action + * @param outcome Navigation outcome for the action + * @param url HREF URL for the action + * @param params Parameters name/values for the action listener args + * @return UIActionLink child component + */ + @SuppressWarnings("unchecked") + private UIActionLink createAction(FacesContext fc, String sandbox, String name, String icon, String actionListener, String outcome, String url, Map params) + { + javax.faces.application.Application facesApp = fc.getApplication(); + UIActionLink control = (UIActionLink) facesApp.createComponent(UIActions.COMPONENT_ACTIONLINK); + + String id = name + '_' + sandbox; + if (logger.isDebugEnabled()) + logger.debug("...creating action Id: " + id); + control.setRendererType(UIActions.RENDERER_ACTIONLINK); + control.setId(id); + control.setValue(Application.getMessage(fc, name)); + control.setShowLink(icon != null ? false : true); + control.setImage(icon); + + if (actionListener != null) + { + control.setActionListener(facesApp.createMethodBinding(actionListener, UIActions.ACTION_CLASS_ARGS)); + + // add sandbox as the default action listener parameter + if (params == null) + { + UIParameter param = (UIParameter) facesApp.createComponent(ComponentConstants.JAVAX_FACES_PARAMETER); + param.setId(id + "_1"); + param.setName("sandbox"); + param.setValue(sandbox); + control.getChildren().add(param); + } + else + { + // if a specific set of parameters are supplied, then add them instead + int idIndex = 1; + for (String key : params.keySet()) + { + UIParameter param = (UIParameter) facesApp.createComponent(ComponentConstants.JAVAX_FACES_PARAMETER); + param.setId(id + '_' + Integer.toString(idIndex++)); + param.setName(key); + String value = params.get(key); + if (value.startsWith("#{") == true) + { + ValueBinding vb = facesApp.createValueBinding(value); + param.setValueBinding("value", vb); + } + else + { + param.setValue(params.get(key)); + } + control.getChildren().add(param); + } + } + } + if (outcome != null) + { + control.setAction(new ConstantMethodBinding(outcome)); + } + if (url != null) + { + control.setHref(url); + control.setTarget("new"); + } + + this.getChildren().add(control); + + return control; + } + + @SuppressWarnings("unchecked") + private void determineDeploymentStatus(FacesContext context, NodeRef webProjectRef, String sandbox, NodeService nodeService, AVMService avmService) + { + // if the store property holding the last deployment id is non null a + // deployment has been attempted + PropertyValue val = avmService.getStoreProperty(sandbox, SandboxConstants.PROP_LAST_DEPLOYMENT_ID); + String attemptId = null; + + if (val != null) + { + attemptId = val.getStringValue(); + + // get the latest deployment attempt + NodeRef attempt = DeploymentUtil.findDeploymentAttempt(attemptId); + if (attempt != null) + { + // retrieve the snapshot deployed + Integer ver = (Integer) nodeService.getProperty(attempt, WCMAppModel.PROP_DEPLOYATTEMPTVERSION); + if (ver != null) + { + this.deployAttemptVersion = ver.intValue(); + } + + // determine if all required reports are present + List selectedServers = (List) nodeService.getProperty(attempt, WCMAppModel.PROP_DEPLOYATTEMPTSERVERS); + int numServersSelected = 0; + if (selectedServers != null) + { + numServersSelected = selectedServers.size(); + + List deployReportRefs = nodeService.getChildAssocs(attempt, WCMAppModel.ASSOC_DEPLOYMENTREPORTS, RegexQNamePattern.MATCH_ALL); + + if (deployReportRefs.size() >= numServersSelected) + { + // the number of expected reports are present, determine the status + boolean oneOrMoreFailed = false; + boolean allFailed = true; + for (ChildAssociationRef ref : deployReportRefs) + { + NodeRef report = ref.getChildRef(); + + // get the deploy outcome + Boolean successful = (Boolean) nodeService.getProperty(report, WCMAppModel.PROP_DEPLOYSUCCESSFUL); + + if (successful != null) + { + if (successful.booleanValue()) + { + allFailed = false; + } + else + { + oneOrMoreFailed = true; + } + } + } + + // get the right status string + if (allFailed) + { + this.deployStatus = Application.getMessage(context, "deploy_status_failed"); + } + else if (oneOrMoreFailed) + { + this.deployStatus = Application.getMessage(context, "deploy_status_partial"); } else { - oneOrMoreFailed = true; + this.deployStatus = Application.getMessage(context, "deploy_status_live"); } - } - } - - // get the right status string - if (allFailed) - { - this.deployStatus = Application.getMessage(context, "deploy_status_failed"); - } - else if (oneOrMoreFailed) - { - this.deployStatus = Application.getMessage(context, "deploy_status_partial"); - } - else - { - this.deployStatus = Application.getMessage(context, "deploy_status_live"); - } - } - else - { - // not all expected reports are present yet, still in progress - this.deployStatus = Application.getMessage(context, "deploy_status_in_progress"); - } + } + else + { + // not all expected reports are present yet, still in progress + this.deployStatus = Application.getMessage(context, "deploy_status_in_progress"); + } + } } - } - } - } - - private AVMService getAVMService(FacesContext fc) - { - return (AVMService)FacesContextUtils.getRequiredWebApplicationContext(fc).getBean("AVMLockingAwareService"); - } - - - // ------------------------------------------------------------------------------ - // Strongly typed component property accessors + } + } - /** - * Returns the Sandbox to show the snapshots for - * - * @return The Sandbox name - */ - public String getValue() - { - ValueBinding vb = getValueBinding("value"); - if (vb != null) - { - this.value = (String)vb.getValue(getFacesContext()); - } - - return this.value; - } - - /** - * Sets the Sandbox to show the snapshots for - * - * @param value The Sandbox name - */ - public void setValue(String value) - { - this.value = value; - } + private AVMService getAVMService(FacesContext fc) + { + return (AVMService) FacesContextUtils.getRequiredWebApplicationContext(fc).getBean("AVMLockingAwareService"); + } - /** - * @return Returns the date filter. - */ - public String getDateFilter() - { - ValueBinding vb = getValueBinding("dateFilter"); - if (vb != null) - { - this.dateFilter = (String)vb.getValue(getFacesContext()); - } - - return this.dateFilter; - } + // ------------------------------------------------------------------------------ + // Strongly typed component property accessors - /** - * @param dateFilter The date filter to set. - */ - public void setDateFilter(String dateFilter) - { - this.dateFilter = dateFilter; - } + /** + * Returns the Sandbox to show the snapshots for + * + * @return The Sandbox name + */ + public String getValue() + { + ValueBinding vb = getValueBinding("value"); + if (vb != null) + { + this.value = (String) vb.getValue(getFacesContext()); + } + + return this.value; + } + + /** + * Sets the Sandbox to show the snapshots for + * + * @param value The Sandbox name + */ + public void setValue(String value) + { + this.value = value; + } + + /** + * @return Returns the date filter. + */ + public String getDateFilter() + { + ValueBinding vb = getValueBinding("dateFilter"); + if (vb != null) + { + this.dateFilter = (String) vb.getValue(getFacesContext()); + } + + return this.dateFilter; + } + + /** + * @param dateFilter The date filter to set. + */ + public void setDateFilter(String dateFilter) + { + this.dateFilter = dateFilter; + } } diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml index ea695d53a0..720a663cae 100644 --- a/source/web/WEB-INF/faces-config-beans.xml +++ b/source/web/WEB-INF/faces-config-beans.xml @@ -4188,6 +4188,48 @@ + + + + The bean that AVM Compure to current snapshot + + CompareToCurrentSnapshot + org.alfresco.web.bean.wcm.CompareToCurrentSnapshotDialog + session + + avmBrowseBean + #{AVMBrowseBean} + + + + + + + + The bean that AVM Compure to prev snapshot + + CompareToPreviousSnapshot + org.alfresco.web.bean.wcm.CompareToPreviousSnapshotDialog + session + + avmBrowseBean + #{AVMBrowseBean} + + + + + + + CompareToAnySnapshot + org.alfresco.web.bean.wcm.CompareToAnySnapshotDialog + session + + avmBrowseBean + #{AVMBrowseBean} + + + + The bean that backs up the Change Expiration Date Dialog diff --git a/source/web/images/icons/arrow_down_disabled.gif b/source/web/images/icons/arrow_down_disabled.gif new file mode 100755 index 0000000000000000000000000000000000000000..b10f8db0b0f3e2437e7a0d268a535e72beb1c101 GIT binary patch literal 1071 zcmV+~1kn3ONk%v~VGsZi0QUd@000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c z3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~EC2ui01yBW000R80QdFtw=WtgPM<(^5*3Z#zkd1t>1&5cRl9ll^3ijr z3R63M|K!oLM6I5@cJJI>yf>{9J$e5eRny0gUKlT3!qodn&Cx$+tM0+0rw+`qV_(wI zgNJWbvrskP$@90x*|RPE;=!xOF4U%b?v}#yV$7HqcthXa+w_UvJb3opeNl$&%R77U zM1snMts1p2I4fcL(xuBaY1%ANk~WQ7mrIl|UCIOrj5cc2ByGYb%^9{Um?Tx2#KoFt zYn`BJ(q^si8A_GVT(h)T&9NCXA89d60Br!`94OH)z(h@p@!W ppFe){CV9FB4VyM+-8f+sg89$kzJJm@K~h{PQ#F71{^1J<06Wx77P|ld literal 0 HcmV?d00001 diff --git a/source/web/images/icons/arrow_up_disabled.gif b/source/web/images/icons/arrow_up_disabled.gif new file mode 100755 index 0000000000000000000000000000000000000000..fe371475f9c2cb4280d74147a8c66be2f2b6098b GIT binary patch literal 1071 zcmV+~1kn3ONk%v~VGsZi0QUd@000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c z3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~EC2ui01yBW000R80Pp?N*H2m~OQc9y0ws;#zJCJq#iQhkoj!Q+^s#eA z30^*k^(I+sH*cOhck|@6t2U{gKuOc=&9lgbi^h5Orb+rYO;x>l_u_3ic5Dm0d-Ck5 zn&t^#yL#`sBwMyDS(kV9+Trtr>771$TB03m*6dg`E%fxg!(@t{J9%AdCR0|ki#&Jq zOl^9Wjas#9UMOkOVlA7qYtuMYLR{?`wJ(?=fw30t8#QQb&6+hWmNIRjCav1E zZI`x5s#Xn~H8Yebk*Q{F+O0 +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> +<%@ 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"%> + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/web/jsp/wcm/compare-to-current-snapshot.jsp b/source/web/jsp/wcm/compare-to-current-snapshot.jsp new file mode 100755 index 0000000000..72c858952e --- /dev/null +++ b/source/web/jsp/wcm/compare-to-current-snapshot.jsp @@ -0,0 +1,55 @@ +<%-- + * Copyright (C) 2005-2008 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="http://java.sun.com/jsp/jstl/core" prefix="c"%> +<%@ 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"%> + + + + + + + + + + + + + + + + + + + + + + +