001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.workplace.comparison; 029 030import org.opencms.db.CmsDbEntryNotFoundException; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsProject; 033import org.opencms.file.CmsProperty; 034import org.opencms.file.CmsResource; 035import org.opencms.file.history.I_CmsHistoryResource; 036import org.opencms.loader.CmsLoaderException; 037import org.opencms.main.CmsException; 038import org.opencms.main.CmsLog; 039import org.opencms.main.OpenCms; 040import org.opencms.security.CmsPrincipal; 041import org.opencms.util.CmsDateUtil; 042import org.opencms.workplace.commons.Messages; 043 044import java.text.DateFormat; 045import java.util.ArrayList; 046import java.util.Date; 047import java.util.Iterator; 048import java.util.List; 049 050import org.apache.commons.logging.Log; 051 052/** 053 * Comparison of two OpenCms resources.<p> 054 */ 055public class CmsResourceComparison { 056 057 /** Constant indicating that an item (e.g. element or property) has been added.<p> */ 058 public static final String TYPE_ADDED = "added"; 059 060 /** Constant indicating that an item has been changed.<p> */ 061 public static final String TYPE_CHANGED = "changed"; 062 063 /** Constant indicating that an item has been removed.<p> */ 064 public static final String TYPE_REMOVED = "removed"; 065 066 /** Constant indicating that an item has not been changed.<p> */ 067 public static final String TYPE_UNCHANGED = "unchanged"; 068 069 /** The log object for this class. */ 070 private static final Log LOG = CmsLog.getLog(CmsResourceComparison.class); 071 072 /** 073 * Constructs a new resource comparison object.<p> 074 * 075 */ 076 protected CmsResourceComparison() { 077 078 super(); 079 } 080 081 /** 082 * Helper method that collects all meta attributes of the two file versions and 083 * finds out, which of the attributes were added, removed, modified or remain unchanged.<p> 084 * 085 * @param cms the CmsObject to use 086 * @param resource1 the first resource to read the properties from 087 * @param resource2 the second resource to read the properties from 088 * 089 * @return a list of the compared attributes 090 */ 091 public static List<CmsAttributeComparison> compareAttributes( 092 CmsObject cms, 093 CmsResource resource1, 094 CmsResource resource2) { 095 096 List<CmsAttributeComparison> comparedAttributes = new ArrayList<CmsAttributeComparison>(); 097 comparedAttributes.add( 098 new CmsAttributeComparison( 099 Messages.GUI_HISTORY_COLS_SIZE_0, 100 String.valueOf(resource1.getLength()), 101 String.valueOf(resource2.getLength()))); 102 String release1; 103 if (CmsResource.DATE_RELEASED_DEFAULT == resource1.getDateReleased()) { 104 release1 = "-"; 105 } else { 106 release1 = CmsDateUtil.getDateTime( 107 new Date(resource1.getDateReleased()), 108 DateFormat.SHORT, 109 cms.getRequestContext().getLocale()); 110 } 111 String release2; 112 if (CmsResource.DATE_RELEASED_DEFAULT == resource2.getDateReleased()) { 113 release2 = "-"; 114 } else { 115 release2 = CmsDateUtil.getDateTime( 116 new Date(resource2.getDateReleased()), 117 DateFormat.SHORT, 118 cms.getRequestContext().getLocale()); 119 } 120 comparedAttributes.add(new CmsAttributeComparison(Messages.GUI_LABEL_DATE_RELEASED_0, release1, release2)); 121 String expire1; 122 if (CmsResource.DATE_EXPIRED_DEFAULT == resource1.getDateExpired()) { 123 expire1 = "-"; 124 } else { 125 expire1 = CmsDateUtil.getDateTime( 126 new Date(resource1.getDateExpired()), 127 DateFormat.SHORT, 128 cms.getRequestContext().getLocale()); 129 } 130 String expire2; 131 if (CmsResource.DATE_EXPIRED_DEFAULT == resource2.getDateExpired()) { 132 expire2 = "-"; 133 } else { 134 expire2 = CmsDateUtil.getDateTime( 135 new Date(resource2.getDateExpired()), 136 DateFormat.SHORT, 137 cms.getRequestContext().getLocale()); 138 } 139 comparedAttributes.add(new CmsAttributeComparison(Messages.GUI_LABEL_DATE_EXPIRED_0, expire1, expire2)); 140 comparedAttributes.add( 141 new CmsAttributeComparison( 142 Messages.GUI_PERMISSION_INTERNAL_0, 143 String.valueOf(resource1.isInternal()), 144 String.valueOf(resource2.isInternal()))); 145 String dateLastModified1 = CmsDateUtil.getDateTime( 146 new Date(resource1.getDateLastModified()), 147 DateFormat.SHORT, 148 cms.getRequestContext().getLocale()); 149 String dateLastModified2 = CmsDateUtil.getDateTime( 150 new Date(resource2.getDateLastModified()), 151 DateFormat.SHORT, 152 cms.getRequestContext().getLocale()); 153 comparedAttributes.add( 154 new CmsAttributeComparison(Messages.GUI_LABEL_DATE_LAST_MODIFIED_0, dateLastModified1, dateLastModified2)); 155 try { 156 String type1 = OpenCms.getResourceManager().getResourceType(resource1.getTypeId()).getTypeName(); 157 String type2 = OpenCms.getResourceManager().getResourceType(resource2.getTypeId()).getTypeName(); 158 comparedAttributes.add(new CmsAttributeComparison(Messages.GUI_HISTORY_COLS_FILE_TYPE_0, type1, type2)); 159 } catch (CmsLoaderException e) { 160 LOG.debug(e.getMessage(), e); 161 } 162 String dateCreated1 = CmsDateUtil.getDateTime( 163 new Date(resource1.getDateCreated()), 164 DateFormat.SHORT, 165 cms.getRequestContext().getLocale()); 166 String dateCreated2 = CmsDateUtil.getDateTime( 167 new Date(resource2.getDateCreated()), 168 DateFormat.SHORT, 169 cms.getRequestContext().getLocale()); 170 comparedAttributes.add( 171 new CmsAttributeComparison(Messages.GUI_HISTORY_COLS_DATE_PUBLISHED_0, dateCreated1, dateCreated2)); 172 try { 173 String userLastModified1 = resource1.getUserLastModified().toString(); 174 try { 175 userLastModified1 = CmsPrincipal.readPrincipalIncludingHistory( 176 cms, 177 resource1.getUserLastModified()).getName(); 178 } catch (CmsDbEntryNotFoundException e) { 179 // ignore 180 } 181 String userLastModified2 = resource2.getUserLastModified().toString(); 182 try { 183 userLastModified2 = CmsPrincipal.readPrincipalIncludingHistory( 184 cms, 185 resource2.getUserLastModified()).getName(); 186 } catch (CmsDbEntryNotFoundException e) { 187 // ignore 188 } 189 comparedAttributes.add( 190 new CmsAttributeComparison( 191 Messages.GUI_LABEL_USER_LAST_MODIFIED_0, 192 userLastModified1, 193 userLastModified2)); 194 } catch (CmsException e) { 195 LOG.error(e.getMessage(), e); 196 } 197 String path1 = cms.getRequestContext().removeSiteRoot(resource1.getRootPath()); 198 String path2 = cms.getRequestContext().removeSiteRoot(resource2.getRootPath()); 199 comparedAttributes.add(new CmsAttributeComparison(Messages.GUI_HISTORY_COLS_RESOURCE_PATH_0, path1, path2)); 200 return comparedAttributes; 201 } 202 203 /** 204 * Helper method that finds out, which of the properties were added, removed, modified or remain unchanged.<p> 205 * 206 * @param cms the CmsObject to use 207 * @param resource1 the first resource to read the properties from 208 * @param version1 the version of the first resource 209 * @param resource2 the second resource to read the properties from 210 * @param version2 the version of the second resource 211 * 212 * @return a list of the compared attributes 213 * 214 * @throws CmsException if something goes wrong 215 */ 216 public static List<CmsAttributeComparison> compareProperties( 217 CmsObject cms, 218 CmsResource resource1, 219 String version1, 220 CmsResource resource2, 221 String version2) throws CmsException { 222 223 List<CmsProperty> properties1; 224 if (resource1 instanceof I_CmsHistoryResource) { 225 properties1 = cms.readHistoryPropertyObjects((I_CmsHistoryResource)resource1); 226 } else { 227 if (Integer.parseInt(version1) < 0) { 228 // switch to the online project 229 CmsProject prj = cms.getRequestContext().getCurrentProject(); 230 try { 231 cms.getRequestContext().setCurrentProject(cms.readProject(CmsProject.ONLINE_PROJECT_ID)); 232 properties1 = cms.readPropertyObjects(resource1, false); 233 } finally { 234 cms.getRequestContext().setCurrentProject(prj); 235 } 236 } else { 237 properties1 = cms.readPropertyObjects(resource1, false); 238 } 239 } 240 List<CmsProperty> properties2; 241 if (resource2 instanceof I_CmsHistoryResource) { 242 properties2 = cms.readHistoryPropertyObjects((I_CmsHistoryResource)resource2); 243 } else { 244 if (Integer.parseInt(version2) < 0) { 245 // switch to the online project 246 CmsProject prj = cms.getRequestContext().getCurrentProject(); 247 try { 248 cms.getRequestContext().setCurrentProject(cms.readProject(CmsProject.ONLINE_PROJECT_ID)); 249 properties2 = cms.readPropertyObjects(resource2, false); 250 } finally { 251 cms.getRequestContext().setCurrentProject(prj); 252 } 253 } else { 254 properties2 = cms.readPropertyObjects(resource2, false); 255 } 256 } 257 List<CmsAttributeComparison> comparedProperties = new ArrayList<CmsAttributeComparison>(); 258 List<CmsProperty> removedProperties = new ArrayList<CmsProperty>(properties1); 259 removedProperties.removeAll(properties2); 260 List<CmsProperty> addedProperties = new ArrayList<CmsProperty>(properties2); 261 addedProperties.removeAll(properties1); 262 List<CmsProperty> retainedProperties = new ArrayList<CmsProperty>(properties2); 263 retainedProperties.retainAll(properties1); 264 CmsProperty prop; 265 Iterator<CmsProperty> i = addedProperties.iterator(); 266 while (i.hasNext()) { 267 prop = i.next(); 268 comparedProperties.add( 269 new CmsAttributeComparison(prop.getName(), "", prop.getValue(), CmsResourceComparison.TYPE_ADDED)); 270 } 271 i = removedProperties.iterator(); 272 while (i.hasNext()) { 273 prop = i.next(); 274 comparedProperties.add( 275 new CmsAttributeComparison(prop.getName(), prop.getValue(), "", CmsResourceComparison.TYPE_REMOVED)); 276 } 277 i = retainedProperties.iterator(); 278 while (i.hasNext()) { 279 prop = i.next(); 280 String value1 = properties1.get(properties1.indexOf(prop)).getValue(); 281 String value2 = properties2.get(properties2.indexOf(prop)).getValue(); 282 if (value1.equals(value2)) { 283 comparedProperties.add( 284 new CmsAttributeComparison(prop.getName(), value1, value2, CmsResourceComparison.TYPE_UNCHANGED)); 285 } else { 286 comparedProperties.add( 287 new CmsAttributeComparison(prop.getName(), value1, value2, CmsResourceComparison.TYPE_CHANGED)); 288 } 289 } 290 return comparedProperties; 291 } 292}