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 com.alkacon.diff.Diff; 031 032import org.opencms.jsp.CmsJspActionElement; 033import org.opencms.util.CmsStringUtil; 034import org.opencms.workplace.CmsDialog; 035import org.opencms.workplace.CmsWorkplace; 036import org.opencms.workplace.CmsWorkplaceSettings; 037import org.opencms.workplace.list.A_CmsListDialog; 038import org.opencms.workplace.tools.A_CmsHtmlIconButton; 039import org.opencms.workplace.tools.CmsHtmlIconButtonStyleEnum; 040 041import java.io.BufferedReader; 042import java.io.IOException; 043import java.io.StringReader; 044 045import javax.servlet.http.HttpServletRequest; 046import javax.servlet.jsp.JspException; 047import javax.servlet.jsp.JspWriter; 048 049/** 050 * Provides a GUI for the configuration file comparison dialog.<p> 051 * 052 * @since 6.0.0 053 */ 054public abstract class A_CmsDiffViewDialog extends CmsDialog { 055 056 /** Diff mode. */ 057 private CmsDiffViewMode m_mode; 058 059 /** 060 * Default constructor.<p> 061 * 062 * @param jsp an initialized JSP action element 063 */ 064 protected A_CmsDiffViewDialog(CmsJspActionElement jsp) { 065 066 super(jsp); 067 setParamStyle(STYLE_NEW); 068 } 069 070 /** 071 * Performs the dialog actions depending on the initialized action and displays the dialog form.<p> 072 * 073 * @throws Exception if writing to the JSP out fails 074 */ 075 public void displayDialog() throws Exception { 076 077 if (getAction() == ACTION_CANCEL) { 078 actionCloseDialog(); 079 } 080 JspWriter out = getJsp().getJspContext().getOut(); 081 out.print("<link rel='stylesheet' type='text/css' href='"); 082 out.print(getStyleUri(getJsp())); 083 out.println("diff.css'>"); 084 out.println(dialogContentStart(getParamTitle())); 085 out.print("<form name='diff-form' method='post' action='"); 086 out.print(getDialogUri()); 087 out.println("'>"); 088 out.println(allParamsAsHidden()); 089 out.println("</form>"); 090 // icon is displayed on the right in order that the user needs not scroll to the icon for long lines 091 out.println("<p>"); 092 out.println(getDiffOnlyButtonsHtml()); 093 out.println("</p>"); 094 out.println(dialogBlockStart(null)); 095 out.println("<table cellspacing='0' cellpadding='0' class='xmlTable'>\n<tr><td><pre style='overflow:auto'>"); 096 try { 097 CmsHtmlDifferenceConfiguration conf = new CmsHtmlDifferenceConfiguration( 098 getMode() == CmsDiffViewMode.ALL ? -1 : getLinesBeforeSkip(), 099 getLocale()); 100 String diff = Diff.diffAsHtml(getOriginalSource(), getCopySource(), conf); 101 if (CmsStringUtil.isNotEmpty(diff)) { 102 out.println(diff); 103 } else { 104 // print original source, if there are no differences 105 out.println( 106 wrapLinesWithUnchangedStyle( 107 CmsStringUtil.substitute(CmsStringUtil.escapeHtml(getOriginalSource()), "<br/>", ""))); 108 } 109 } catch (Exception e) { 110 out.print(e); 111 } 112 out.println("</pre></td></tr>\n</table>"); 113 out.println(dialogBlockEnd()); 114 out.println(dialogContentEnd()); 115 out.println(dialogEnd()); 116 out.println(bodyEnd()); 117 out.println(htmlEnd()); 118 } 119 120 /** 121 * Returns the html code for the buttons 'show only differences' and 'show everything'.<p> 122 * 123 * @return the html code for the buttons 'show only differences' and 'show everything' 124 */ 125 String getDiffOnlyButtonsHtml() { 126 127 StringBuffer result = new StringBuffer(); 128 if (!getOriginalSource().equals(getCopySource())) { 129 String onClick1 = "javascript:document.forms['diff-form'].mode.value = '"; 130 String onClick2 = "javascript:document.forms['diff-form'].mode.value = '"; 131 onClick1 += CmsDiffViewMode.ALL; 132 onClick2 += CmsDiffViewMode.DIFF_ONLY; 133 onClick1 += "'; document.forms['diff-form'].submit();"; 134 onClick2 += "'; document.forms['diff-form'].submit();"; 135 result.append( 136 getTwoButtonsHtml( 137 CmsDiffViewMode.DIFF_ONLY.getName().key(getLocale()), 138 CmsDiffViewMode.ALL.getName().key(getLocale()), 139 onClick1, 140 onClick2, 141 getMode() == CmsDiffViewMode.DIFF_ONLY)); 142 } else { 143 // display all text, if there are no differences 144 setMode(CmsDiffViewMode.ALL); 145 } 146 return result.toString(); 147 } 148 149 /** 150 * Returns the html for two buttons, whereby the third parameter determines which one is active.<p> 151 * 152 * @param label1 the label for the first button 153 * @param label2 the label for the second button 154 * @param firstActive a flag indicating wheter the first or second button is active 155 * @param onClick1 the action to be performed if the first button is clicked 156 * @param onClick2 the action to be performed if the second button is clicked 157 * 158 * @return the html for two buttons, whereby the third parameter determines which one is active 159 */ 160 public String getTwoButtonsHtml( 161 String label1, 162 String label2, 163 String onClick1, 164 String onClick2, 165 boolean firstActive) { 166 167 StringBuffer result = new StringBuffer(); 168 if (firstActive) { 169 result.append( 170 A_CmsHtmlIconButton.defaultButtonHtml( 171 CmsHtmlIconButtonStyleEnum.SMALL_ICON_TEXT, 172 "id", 173 label1, 174 null, 175 true, 176 A_CmsListDialog.ICON_DETAILS_SHOW, 177 null, 178 onClick1)); 179 result.append(" "); 180 result.append(deactivatedEmphasizedButtonHtml(label2, A_CmsListDialog.ICON_DETAILS_HIDE)); 181 } else { 182 183 result.append(deactivatedEmphasizedButtonHtml(label1, A_CmsListDialog.ICON_DETAILS_HIDE)); 184 result.append(" "); 185 result.append( 186 A_CmsHtmlIconButton.defaultButtonHtml( 187 CmsHtmlIconButtonStyleEnum.SMALL_ICON_TEXT, 188 "id", 189 label2, 190 null, 191 true, 192 A_CmsListDialog.ICON_DETAILS_SHOW, 193 null, 194 onClick2)); 195 } 196 result.append(" "); 197 return result.toString(); 198 } 199 200 /** 201 * Returns the html code for a deactivated empfasized button.<p> 202 * 203 * @param name the label of the button 204 * @param iconPath the path to the icon 205 * 206 * @return the html code for a deactivated empfasized button 207 */ 208 public String deactivatedEmphasizedButtonHtml(String name, String iconPath) { 209 210 StringBuffer result = new StringBuffer(); 211 result.append( 212 "<span style='vertical-align:middle;'><img style='width:20px;height:20px;display:inline;vertical-align:middle;text-decoration:none;' src=\'"); 213 result.append(CmsWorkplace.getSkinUri()); 214 result.append(iconPath); 215 result.append("\' alt=\'"); 216 result.append(name); 217 result.append("\' title=\'"); 218 result.append(name); 219 result.append("\'> <b>"); 220 result.append(name); 221 result.append("</b></span>"); 222 return result.toString(); 223 } 224 225 /** 226 * Returns the mode.<p> 227 * 228 * @return the mode 229 */ 230 public CmsDiffViewMode getMode() { 231 232 return m_mode; 233 } 234 235 /** 236 * Returns the parameter value for the Mode.<p> 237 * 238 * @return the parameter value for the Mode 239 */ 240 public String getParamMode() { 241 242 if (m_mode == null) { 243 return null; 244 } 245 return m_mode.getMode(); 246 } 247 248 /** 249 * Sets the mode.<p> 250 * 251 * @param mode the mode to set 252 */ 253 public void setMode(CmsDiffViewMode mode) { 254 255 m_mode = mode; 256 } 257 258 /** 259 * Sets the parameter value for the Mode.<p> 260 * 261 * @param mode the parameter value for the Mode to set 262 */ 263 public void setParamMode(String mode) { 264 265 m_mode = CmsDiffViewMode.valueOf(mode); 266 } 267 268 /** 269 * Returns the text to compare as copy.<p> 270 * 271 * @return the text to compare as copy 272 */ 273 protected abstract String getCopySource(); 274 275 /** 276 * Returns the number of lines to show before they are skipped.<p> 277 * 278 * @return the number of lines to show before they are skipped 279 */ 280 protected abstract int getLinesBeforeSkip(); 281 282 /** 283 * Returns the text to compare as original.<p> 284 * 285 * @return the text to compare as original 286 */ 287 protected abstract String getOriginalSource(); 288 289 /** 290 * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest) 291 */ 292 @Override 293 protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { 294 295 super.initWorkplaceRequestValues(settings, request); 296 if (CmsStringUtil.isEmptyOrWhitespaceOnly(getParamMode())) { 297 // ensure a valid mode is set 298 m_mode = CmsDiffViewMode.DIFF_ONLY; 299 } 300 // test the needed parameters 301 try { 302 validateParamaters(); 303 } catch (Exception e) { 304 // close if parameters not available 305 setAction(ACTION_CANCEL); 306 try { 307 actionCloseDialog(); 308 } catch (JspException e1) { 309 // noop 310 } 311 return; 312 } 313 } 314 315 /** 316 * Validates the parameters.<p> 317 * 318 * @throws Exception if something goes wrong 319 */ 320 protected abstract void validateParamaters() throws Exception; 321 322 /** 323 * 324 * Returns a diff text wrapped with formatting style.<p> 325 * 326 * @param diff the text to wrap with CSS formatting 327 * @return the text with formatting styles wrapped 328 * @throws IOException if something goes wrong 329 */ 330 protected String wrapLinesWithUnchangedStyle(String diff) throws IOException { 331 332 String line; 333 StringBuffer result = new StringBuffer(); 334 BufferedReader br = new BufferedReader(new StringReader(diff)); 335 while ((line = br.readLine()) != null) { 336 if ("".equals(line.trim())) { 337 line = " "; 338 } 339 result.append("<div class=\"df-unc\"><span class=\"df-unc\">").append(line).append("</span></div>\n"); 340 } 341 return result.toString(); 342 } 343 344}