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 GmbH & Co. KG, 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.file.CmsFile; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsProject; 033import org.opencms.file.CmsResource; 034import org.opencms.file.CmsResourceFilter; 035import org.opencms.file.history.CmsHistoryFile; 036import org.opencms.file.history.CmsHistoryResourceHandler; 037import org.opencms.file.types.CmsResourceTypePlain; 038import org.opencms.jsp.CmsJspActionElement; 039import org.opencms.loader.CmsLoaderException; 040import org.opencms.main.CmsException; 041import org.opencms.main.OpenCms; 042import org.opencms.util.CmsStringUtil; 043import org.opencms.util.CmsUUID; 044import org.opencms.workplace.CmsWorkplace; 045import org.opencms.workplace.commons.CmsHistoryList; 046import org.opencms.workplace.list.CmsListIndependentAction; 047import org.opencms.workplace.list.CmsListItem; 048import org.opencms.workplace.list.CmsListItemDetails; 049import org.opencms.workplace.list.CmsListMetadata; 050import org.opencms.workplace.list.CmsListOrderEnum; 051 052import java.io.IOException; 053import java.util.ArrayList; 054import java.util.HashMap; 055import java.util.Iterator; 056import java.util.List; 057import java.util.Map; 058 059import javax.servlet.ServletException; 060import javax.servlet.http.HttpServletRequest; 061import javax.servlet.http.HttpServletResponse; 062import javax.servlet.jsp.PageContext; 063 064/** 065 * List for property comparison including columns for property name and the values. <p> 066 * 067 * @since 6.0.0 068 */ 069public class CmsAttributeComparisonList extends CmsPropertyComparisonList { 070 071 /** List id constant. */ 072 public static final String AC_LIST_ID = "hiacl"; 073 074 /** 075 * Public constructor.<p> 076 * 077 * @param jsp an initialized JSP action element 078 */ 079 public CmsAttributeComparisonList(CmsJspActionElement jsp) { 080 081 this(AC_LIST_ID, jsp); 082 } 083 084 /** 085 * Public constructor with JSP variables.<p> 086 * 087 * @param context the JSP page context 088 * @param req the JSP request 089 * @param res the JSP response 090 */ 091 public CmsAttributeComparisonList(PageContext context, HttpServletRequest req, HttpServletResponse res) { 092 093 this(new CmsJspActionElement(context, req, res)); 094 } 095 096 /** 097 * Protected constructor.<p> 098 * 099 * @param listId the id of the specialized list 100 * @param jsp an initialized JSP action element 101 */ 102 protected CmsAttributeComparisonList(String listId, CmsJspActionElement jsp) { 103 104 super( 105 jsp, 106 listId, 107 Messages.get().container(Messages.GUI_COMPARE_ATTRIBUTES_0), 108 LIST_COLUMN_PROPERTY_NAME, 109 CmsListOrderEnum.ORDER_ASCENDING, 110 null); 111 } 112 113 /** 114 * Returns either the historical file or the offline file, depending on the version number.<p> 115 * 116 * @param cms the CmsObject to use 117 * @param structureId the structure id of the file 118 * @param version the historical version number 119 * 120 * @return either the historical file or the offline file, depending on the version number 121 * 122 * @throws CmsException if something goes wrong 123 */ 124 protected static CmsFile readFile(CmsObject cms, CmsUUID structureId, String version) throws CmsException { 125 126 if (Integer.parseInt(version) == CmsHistoryResourceHandler.PROJECT_OFFLINE_VERSION) { 127 // offline 128 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 129 return cms.readFile(resource); 130 } else { 131 int ver = Integer.parseInt(version); 132 if (ver < 0) { 133 // online 134 CmsProject project = cms.getRequestContext().getCurrentProject(); 135 try { 136 cms.getRequestContext().setCurrentProject(cms.readProject(CmsProject.ONLINE_PROJECT_ID)); 137 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 138 return cms.readFile(resource); 139 } finally { 140 cms.getRequestContext().setCurrentProject(project); 141 } 142 } 143 // backup 144 return cms.readFile((CmsHistoryFile)cms.readResource(structureId, ver)); 145 } 146 } 147 148 /** 149 * @see org.opencms.workplace.list.A_CmsListDialog#executeListSingleActions() 150 */ 151 @Override 152 public void executeListSingleActions() throws IOException, ServletException { 153 154 // forward to the edit module screen 155 Map<String, String[]> params = new HashMap<String, String[]>(); 156 params.put(CmsHistoryList.PARAM_VERSION_1, new String[] {getParamVersion1()}); 157 params.put(CmsHistoryList.PARAM_VERSION_2, new String[] {getParamVersion2()}); 158 params.put(CmsHistoryList.PARAM_ID_1, new String[] {getParamId1()}); 159 params.put(CmsHistoryList.PARAM_ID_2, new String[] {getParamId2()}); 160 params.put(PARAM_COMPARE, new String[] {CmsResourceComparisonDialog.COMPARE_ATTRIBUTES}); 161 params.put(PARAM_RESOURCE, new String[] {getParamResource()}); 162 // forward to the difference screen 163 getToolManager().jspForwardTool(this, "/history/comparison/difference", params); 164 } 165 166 /** 167 * @see org.opencms.workplace.list.A_CmsListDialog#getListItems() 168 */ 169 @Override 170 protected List<CmsListItem> getListItems() { 171 172 List<CmsListItem> ret = new ArrayList<CmsListItem>(); 173 Iterator<?> diffs = CmsResourceComparison.compareAttributes( 174 getCms(), 175 getResource1(), 176 getResource2()).iterator(); 177 while (diffs.hasNext()) { 178 CmsAttributeComparison comparison = (CmsAttributeComparison)diffs.next(); 179 CmsListItem item = getList().newItem(comparison.getName()); 180 item.set(LIST_COLUMN_PROPERTY_NAME, key(comparison.getName())); 181 item.set(LIST_COLUMN_VERSION_1, CmsStringUtil.trimToSize(comparison.getVersion1(), TRIM_AT_LENGTH)); 182 item.set(LIST_COLUMN_VERSION_2, CmsStringUtil.trimToSize(comparison.getVersion2(), TRIM_AT_LENGTH)); 183 if (CmsResourceComparison.TYPE_ADDED.equals(comparison.getStatus())) { 184 item.set(LIST_COLUMN_TYPE, key(Messages.GUI_COMPARE_ADDED_0)); 185 } else if (CmsResourceComparison.TYPE_REMOVED.equals(comparison.getStatus())) { 186 item.set(LIST_COLUMN_TYPE, key(Messages.GUI_COMPARE_REMOVED_0)); 187 } else if (CmsResourceComparison.TYPE_CHANGED.equals(comparison.getStatus())) { 188 item.set(LIST_COLUMN_TYPE, key(Messages.GUI_COMPARE_CHANGED_0)); 189 } else { 190 if (!getList().getMetadata().getItemDetailDefinition(LIST_IACTION_SHOW).isVisible()) { 191 // do not display entry 192 continue; 193 } else { 194 item.set(LIST_COLUMN_TYPE, key(Messages.GUI_COMPARE_UNCHANGED_0)); 195 } 196 } 197 ret.add(item); 198 199 if (!diffs.hasNext()) { 200 getList().getMetadata().getIndependentAction(LIST_ACTION_VIEW1).setEnabled(getResource1().isFile()); 201 getList().getMetadata().getIndependentAction(LIST_ACTION_VIEW2).setEnabled(getResource2().isFile()); 202 } 203 } 204 getList().getMetadata().getColumnDefinition(LIST_COLUMN_VERSION_1).setName( 205 Messages.get().container( 206 Messages.GUI_COMPARE_VERSION_1, 207 CmsHistoryListUtil.getDisplayVersion(getParamVersion1(), getLocale()))); 208 getList().getMetadata().getColumnDefinition(LIST_COLUMN_VERSION_2).setName(Messages.get().container( 209 Messages.GUI_COMPARE_VERSION_1, 210 CmsHistoryListUtil.getDisplayVersion(getParamVersion2(), getLocale()))); 211 212 return ret; 213 } 214 215 /** 216 * Returns the html code to display a file version.<p> 217 * 218 * @param structureId the structure id of the file to be displayed 219 * @param version the version of the file to be displayed 220 * 221 * @return the html code to display a file version 222 */ 223 protected String getViewVersionButtonHtml(CmsUUID structureId, String version) { 224 225 // set flag to activate the preview button of the comparison dialog 226 boolean active = true; 227 try { 228 // only show preview, if the resource is a file 229 // or the version has content 230 if (OpenCms.getResourceManager().getResourceType(getResource1().getTypeId()).isFolder()) { 231 active = false; 232 } else { 233 byte[] content = readFile(getCms(), structureId, version).getContents(); 234 if (content.length < 1) { 235 active = false; 236 } 237 } 238 } catch (CmsLoaderException e) { 239 // ignore, buttons will be shown 240 241 } catch (CmsException e) { 242 // do not show the preview button 243 active = false; 244 } 245 246 // return button only if file resource 247 if (active) { 248 String label = Messages.get().container( 249 Messages.GUI_COMPARE_VIEW_VERSION_1, 250 CmsHistoryListUtil.getDisplayVersion(version, getLocale())).key(getLocale()); 251 String iconPath = null; 252 try { 253 String typeName = OpenCms.getResourceManager().getResourceType( 254 getResource1().getTypeId()).getTypeName(); 255 iconPath = CmsWorkplace.RES_PATH_FILETYPES 256 + OpenCms.getWorkplaceManager().getExplorerTypeSetting(typeName).getIcon(); 257 } catch (CmsException e) { 258 iconPath = CmsWorkplace.RES_PATH_FILETYPES 259 + OpenCms.getWorkplaceManager().getExplorerTypeSetting( 260 CmsResourceTypePlain.getStaticTypeName()).getIcon(); 261 } 262 StringBuffer result = new StringBuffer(1024); 263 result.append("<span class='link' onClick=\""); 264 result.append("window.open('"); 265 result.append(getJsp().link(CmsHistoryListUtil.getHistoryLink(getCms(), structureId, version))); 266 result.append("','version','scrollbars=yes', 'resizable=yes', 'width=800', 'height=600')\">"); 267 result.append("<img style='width: 16px; height: 16px;' src='"); 268 result.append(CmsWorkplace.getSkinUri()); 269 result.append(iconPath); 270 result.append("' alt='"); 271 result.append(label); 272 result.append("' title='"); 273 result.append(label); 274 result.append("'> <a href='#'>"); 275 result.append(label); 276 result.append("</a></span>"); 277 278 return result.toString(); 279 } 280 return ""; 281 } 282 283 /** 284 * @see org.opencms.workplace.list.A_CmsListDialog#setIndependentActions(org.opencms.workplace.list.CmsListMetadata) 285 */ 286 @Override 287 protected void setIndependentActions(CmsListMetadata metadata) { 288 289 // add the view version action 290 CmsListIndependentAction viewVersion1 = new CmsListIndependentAction(LIST_ACTION_VIEW1) { 291 292 /** 293 * @see org.opencms.workplace.tools.I_CmsHtmlIconButton#buttonHtml(org.opencms.workplace.CmsWorkplace) 294 */ 295 @Override 296 public String buttonHtml(CmsWorkplace wp) { 297 298 return ((CmsAttributeComparisonList)wp).getViewVersionButtonHtml( 299 new CmsUUID(((CmsAttributeComparisonList)wp).getParamId1()), 300 ((CmsAttributeComparisonList)wp).getParamVersion1()); 301 } 302 }; 303 metadata.addIndependentAction(viewVersion1); 304 // add the view version action 305 CmsListIndependentAction viewVersion2 = new CmsListIndependentAction(LIST_ACTION_VIEW2) { 306 307 /** 308 * @see org.opencms.workplace.tools.I_CmsHtmlIconButton#buttonHtml(org.opencms.workplace.CmsWorkplace) 309 */ 310 @Override 311 public String buttonHtml(CmsWorkplace wp) { 312 313 return ((CmsAttributeComparisonList)wp).getViewVersionButtonHtml( 314 new CmsUUID(((CmsAttributeComparisonList)wp).getParamId2()), 315 ((CmsAttributeComparisonList)wp).getParamVersion2()); 316 } 317 }; 318 metadata.addIndependentAction(viewVersion2); 319 320 // add event details 321 CmsListItemDetails eventDetails = new CmsListItemDetails(LIST_IACTION_SHOW); 322 eventDetails.setVisible(false); 323 eventDetails.setShowActionName(Messages.get().container(Messages.GUI_COMPARE_SHOW_ALL_ATTRIBUTES_0)); 324 eventDetails.setHideActionName(Messages.get().container(Messages.GUI_COMPARE_HIDE_IDENTICAL_ATTRIBUTES_0)); 325 metadata.addItemDetails(eventDetails); 326 } 327}