All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencms.workplace.comparison.CmsResourceComparisonDialog Maven / Gradle / Ivy

Go to download

OpenCms is an enterprise-ready, easy to use website content management system based on Java and XML technology. Offering a complete set of features, OpenCms helps content managers worldwide to create and maintain beautiful websites fast and efficiently.

There is a newer version: 18.0
Show newest version
/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software GmbH & Co. KG, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.workplace.comparison;

import org.opencms.file.CmsFile;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsProject;
import org.opencms.file.CmsResource;
import org.opencms.file.CmsResourceFilter;
import org.opencms.file.history.CmsHistoryFile;
import org.opencms.file.history.CmsHistoryResourceHandler;
import org.opencms.file.types.CmsResourceTypeImage;
import org.opencms.file.types.CmsResourceTypeJsp;
import org.opencms.file.types.CmsResourceTypePlain;
import org.opencms.file.types.CmsResourceTypePointer;
import org.opencms.file.types.CmsResourceTypeXmlContent;
import org.opencms.file.types.CmsResourceTypeXmlPage;
import org.opencms.file.types.I_CmsResourceType;
import org.opencms.i18n.CmsLocaleManager;
import org.opencms.jsp.CmsJspActionElement;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.search.extractors.CmsExtractorMsOfficeOLE2;
import org.opencms.search.extractors.CmsExtractorPdf;
import org.opencms.search.extractors.CmsExtractorRtf;
import org.opencms.search.extractors.I_CmsTextExtractor;
import org.opencms.util.CmsStringUtil;
import org.opencms.util.CmsUUID;
import org.opencms.widgets.I_CmsWidget;
import org.opencms.widgets.I_CmsWidgetParameter;
import org.opencms.workplace.CmsDialog;
import org.opencms.workplace.CmsWorkplaceSettings;
import org.opencms.workplace.commons.CmsResourceInfoDialog;
import org.opencms.workplace.list.A_CmsListDialog;
import org.opencms.workplace.list.CmsMultiListDialog;
import org.opencms.xml.CmsXmlException;
import org.opencms.xml.I_CmsXmlDocument;
import org.opencms.xml.content.CmsXmlContent;
import org.opencms.xml.content.CmsXmlContentFactory;
import org.opencms.xml.content.I_CmsXmlContentValueVisitor;
import org.opencms.xml.page.CmsXmlPage;
import org.opencms.xml.page.CmsXmlPageFactory;
import org.opencms.xml.types.I_CmsXmlContentValue;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;

import org.apache.commons.logging.Log;

/**
 * Helper class for managing three lists on the same dialog.

* * @since 6.0.0 */ public class CmsResourceComparisonDialog extends CmsDialog { /** * Visitor that collects the xpath expressions of xml contents.

*/ class CmsXmlContentTextExtractor implements I_CmsXmlContentValueVisitor { /** The StringBuffer to write the extracted text to. */ private StringBuffer m_buffer; /** The locales of the xml content. */ private List m_locales; /** * Creates a new CmsXmlContentTextExtractor.

* * @param stringBuffer the StringBuffer to append the element text to */ CmsXmlContentTextExtractor(StringBuffer stringBuffer) { m_buffer = stringBuffer; m_locales = new ArrayList(); } /** * * @see org.opencms.xml.content.I_CmsXmlContentValueVisitor#visit(org.opencms.xml.types.I_CmsXmlContentValue) */ public void visit(I_CmsXmlContentValue value) { // only add simple types if (value.isSimpleType()) { String locale = value.getLocale().toString(); if (!m_locales.contains(locale)) { m_buffer.append("\n\n[").append(locale).append(']'); m_locales.add(locale); } m_buffer.append("\n\n[").append(value.getPath()).append("]\n\n"); try { I_CmsWidget widget = value.getDocument().getContentDefinition().getContentHandler().getWidget( value); m_buffer.append( widget.getWidgetStringValue( getCms(), new CmsResourceInfoDialog(getJsp()), (I_CmsWidgetParameter)value)); } catch (CmsXmlException e) { LOG.error(e.getMessage(), e); } } } } /** Constant indicating that all elements are compared.

*/ public static final String COMPARE_ALL_ELEMENTS = "allelements"; /** Constant indicating that the attributes are compared.

*/ public static final String COMPARE_ATTRIBUTES = "attributes"; /** Constant indicating that the properties are compared.

*/ public static final String COMPARE_PROPERTIES = "properties"; /** The log object for this class. */ static final Log LOG = CmsLog.getLog(CmsResourceComparisonDialog.class); /** The difference dialog. */ private CmsDifferenceDialog m_differenceDialog; /** Parameter value indicating whether to compare properties, attributes or elements. */ private String m_paramCompare; /** Parameter value for the element name. */ private String m_paramElement; /** Parameter value for the structure id of the first file. */ private String m_paramId1; /** Parameter value for the structure id of the second file. */ private String m_paramId2; /** Parameter value for the locale. */ private String m_paramLocale; /** Parameter value for the text mode. */ private String m_paramTextmode; /** Parameter value for the version of the first file. */ private String m_paramVersion1; /** Parameter value for the version of the second file. */ private String m_paramVersion2; /** * Public constructor with JSP action element.

* * @param jsp an initialized JSP action element */ public CmsResourceComparisonDialog(CmsJspActionElement jsp) { super(jsp); } /** * Public constructor with JSP variables.

* * @param context the JSP page context * @param req the JSP request * @param res the JSP response */ public CmsResourceComparisonDialog(PageContext context, HttpServletRequest req, HttpServletResponse res) { this(new CmsJspActionElement(context, req, res)); } /** * Returns either the historical file or the offline file, depending on the version number.

* * @param cms the CmsObject to use * @param structureId the structure id of the file * @param version the historical version number * * @return either the historical file or the offline file, depending on the version number * * @throws CmsException if something goes wrong */ public static CmsFile readFile(CmsObject cms, CmsUUID structureId, String version) throws CmsException { if (Integer.parseInt(version) == CmsHistoryResourceHandler.PROJECT_OFFLINE_VERSION) { // offline CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); return cms.readFile(resource); } else { int ver = Integer.parseInt(version); if (ver < 0) { // online CmsProject project = cms.getRequestContext().getCurrentProject(); try { cms.getRequestContext().setCurrentProject(cms.readProject(CmsProject.ONLINE_PROJECT_ID)); CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); return cms.readFile(resource); } finally { cms.getRequestContext().setCurrentProject(project); } } // backup return cms.readFile((CmsHistoryFile)cms.readResource(structureId, ver)); } } /** * Returns either the historical resource or the offline resource, depending on the version number.

* * @param cms the CmsObject to use * @param id the structure id of the resource * @param version the historical version number * * @return either the historical resource or the offline resource, depending on the version number * * @throws CmsException if something goes wrong */ protected static CmsResource readResource(CmsObject cms, CmsUUID id, String version) throws CmsException { if (Integer.parseInt(version) == CmsHistoryResourceHandler.PROJECT_OFFLINE_VERSION) { return cms.readResource(id, CmsResourceFilter.IGNORE_EXPIRATION); } else { int ver = Integer.parseInt(version); if (ver < 0) { CmsProject project = cms.getRequestContext().getCurrentProject(); try { cms.getRequestContext().setCurrentProject(cms.readProject(CmsProject.ONLINE_PROJECT_ID)); return cms.readResource(id, CmsResourceFilter.IGNORE_EXPIRATION); } finally { cms.getRequestContext().setCurrentProject(project); } } return (CmsResource)cms.readResource(id, ver); } } /** * Display method for two list dialogs.

* * @throws Exception if something goes wrong */ public void displayDialog() throws Exception { CmsResourceInfoDialog fileInfo = new CmsResourceInfoDialog(getJsp()) { @Override protected String defaultActionHtmlEnd() { return ""; } }; fileInfo.displayDialog(true); if (fileInfo.isForwarded()) { return; } CmsPropertyComparisonList propertyDiff = new CmsPropertyComparisonList(getJsp()); CmsAttributeComparisonList attributeDiff = new CmsAttributeComparisonList(getJsp()); List lists = new ArrayList(); lists.add(attributeDiff); I_CmsResourceType resourceType = OpenCms.getResourceManager().getResourceType(propertyDiff.getResourceType()); if ((resourceType instanceof CmsResourceTypeXmlContent) || (resourceType instanceof CmsResourceTypeXmlPage)) { // display attributes, properties and compared elements CmsElementComparisonList contentDiff = new CmsElementComparisonList(getJsp()); // get the content of the resource1 and resource2 byte[] content1 = readFile( getCms(), propertyDiff.getResource1().getStructureId(), getParamVersion1()).getContents(); byte[] content2 = readFile( getCms(), propertyDiff.getResource2().getStructureId(), getParamVersion2()).getContents(); // display the content comparison only if both files has contents if ((content1.length > 0) && (content2.length > 0)) { lists.add(contentDiff); } lists.add(propertyDiff); CmsMultiListDialog threeLists = new CmsMultiListDialog(lists); // perform the active list actions threeLists.displayDialog(true); // write the dialog just if no list has been forwarded if (threeLists.isForwarded()) { return; } fileInfo.writeDialog(); threeLists.writeDialog(); } else if (resourceType instanceof CmsResourceTypeImage) { // display attributes, properties and images lists.add(propertyDiff); CmsMultiListDialog twoLists = new CmsMultiListDialog(lists) { /** * @see org.opencms.workplace.list.CmsMultiListDialog#defaultActionHtmlEnd() */ @Override public String defaultActionHtmlEnd() { return ""; } }; twoLists.displayDialog(true); if (twoLists.isForwarded()) { return; } CmsImageComparisonDialog images = new CmsImageComparisonDialog(getJsp()); fileInfo.writeDialog(); twoLists.writeDialog(); // this is very dangerous // it is possible that here a forward is tried, what should not be sence we already wrote to the output stream. // CmsImageComparisonDialog should implement isForwarded, writeDialog and displayDialog(boolean) methods images.displayDialog(); } else if (resourceType instanceof CmsResourceTypePointer) { lists.add(propertyDiff); CmsMultiListDialog twoLists = new CmsMultiListDialog(lists) { /** * @see org.opencms.workplace.list.CmsMultiListDialog#defaultActionHtmlEnd() */ @Override public String defaultActionHtmlEnd() { return ""; } }; twoLists.displayDialog(true); if (twoLists.isForwarded()) { return; } CmsPointerComparisonDialog pointers = new CmsPointerComparisonDialog(getJsp()); fileInfo.writeDialog(); twoLists.writeDialog(); // same as for CmsImageComparisonDialog pointers.displayDialog(); } else if (propertyDiff.getResource1().isFile()) { // display attributes and properties lists.add(propertyDiff); CmsMultiListDialog twoLists = new CmsMultiListDialog(lists); twoLists.displayDialog(true); if (twoLists.isForwarded()) { return; } CmsResource resource1 = propertyDiff.getResource1(); CmsResource resource2 = propertyDiff.getResource2(); String path1 = resource1.getRootPath(); String path2 = resource2.getRootPath(); byte[] content1 = readFile(getCms(), resource1.getStructureId(), getParamVersion1()).getContents(); byte[] content2 = readFile(getCms(), resource2.getStructureId(), getParamVersion2()).getContents(); String originalSource = null; String copySource = null; I_CmsTextExtractor textExtractor = null; // only if both files have contents if ((content1.length > 0) && (content2.length > 0)) { if (path1.endsWith(".pdf") && path2.endsWith(".pdf")) { textExtractor = CmsExtractorPdf.getExtractor(); } else if (path1.endsWith(".doc") && path2.endsWith(".doc")) { textExtractor = CmsExtractorMsOfficeOLE2.getExtractor(); } else if (path1.endsWith(".xls") && path2.endsWith(".xls")) { textExtractor = CmsExtractorMsOfficeOLE2.getExtractor(); } else if (path1.endsWith(".rtf") && path2.endsWith(".rtf")) { textExtractor = CmsExtractorRtf.getExtractor(); } else if (path1.endsWith(".ppt") && path2.endsWith(".ppt")) { textExtractor = CmsExtractorMsOfficeOLE2.getExtractor(); } } if (textExtractor != null) { try { // extract the content originalSource = textExtractor.extractText(content1).getContent(); copySource = textExtractor.extractText(content2).getContent(); } catch (Exception e) { // something goes wrong on extracting content // set the content to null, so the content dialog will not be shown originalSource = null; copySource = null; LOG.error(e.getMessage(), e); } } else if ((resourceType instanceof CmsResourceTypePlain) || (resourceType instanceof CmsResourceTypeJsp)) { originalSource = new String(content1); copySource = new String(content2); } fileInfo.writeDialog(); twoLists.writeDialog(); if (CmsStringUtil.isNotEmpty(originalSource) && CmsStringUtil.isNotEmpty(copySource)) { m_differenceDialog.setCopySource(copySource); m_differenceDialog.setOriginalSource(originalSource); // same as for CmsImageComparisonDialog m_differenceDialog.displayDialog(); } } else { // display attributes and properties lists.add(propertyDiff); CmsMultiListDialog twoLists = new CmsMultiListDialog(lists); twoLists.displayDialog(true); if (twoLists.isForwarded()) { return; } fileInfo.writeDialog(); twoLists.writeDialog(); } } /** * Displays the difference dialog.

* @throws Exception if something goes wrong */ public void displayDifferenceDialog() throws Exception { m_differenceDialog.displayDialog(); } /** * Converts an attribute list to a string.

* * @param attributes a list of compared attributes to be converted to a string * @return a string respresentation of the attribute list */ public String[] getAttributesAsString(List attributes) { Iterator i = attributes.iterator(); StringBuffer res1 = new StringBuffer(512); StringBuffer res2 = new StringBuffer(512); while (i.hasNext()) { CmsAttributeComparison compare = (CmsAttributeComparison)i.next(); res1.append(key(compare.getName())).append(": ").append(compare.getVersion1()).append("\n"); res2.append(key(compare.getName())).append(": ").append(compare.getVersion2()).append("\n"); } return new String[] {res1.toString(), res2.toString()}; } /** * Returns the paramCompare.

* * @return the paramCompare */ public String getParamCompare() { return m_paramCompare; } /** * Returns the paramElement.

* * @return the paramElement */ public String getParamElement() { return m_paramElement; } /** * Returns the paramId1.

* * @return the paramId1 */ public String getParamId1() { return m_paramId1; } /** * Returns the paramId2.

* * @return the paramId2 */ public String getParamId2() { return m_paramId2; } /** * Returns the paramLocale.

* * @return the paramLocale */ public String getParamLocale() { return m_paramLocale; } /** * Returns the paramTextmode.

* * @return the paramTextmode */ public String getParamTextmode() { return m_paramTextmode; } /** * Returns the paramVersion1.

* * @return the paramVersion1 */ public String getParamVersion1() { return m_paramVersion1; } /** * Returns the paramVersion2.

* * @return the paramVersion2 */ public String getParamVersion2() { return m_paramVersion2; } /** * Converts an attribute list to a string.

* * @param properties a list of compared properties to be converted to a string * @return a string respresentation of the attribute list */ public String[] getPropertiesAsString(List properties) { Iterator i = properties.iterator(); StringBuffer res1 = new StringBuffer(512); StringBuffer res2 = new StringBuffer(512); while (i.hasNext()) { CmsAttributeComparison compare = (CmsAttributeComparison)i.next(); res1.append(compare.getName()).append(": ").append(compare.getVersion1()).append("\n"); res2.append(compare.getName()).append(": ").append(compare.getVersion2()).append("\n"); } return new String[] {res1.toString(), res2.toString()}; } /** * Sets the paramCompare.

* * @param paramCompare the paramCompare to set */ public void setParamCompare(String paramCompare) { m_paramCompare = paramCompare; } /** * Sets the paramElement.

* * @param paramElement the paramElement to set */ public void setParamElement(String paramElement) { m_paramElement = paramElement; } /** * Sets the paramId1.

* * @param paramId1 the paramId1 to set */ public void setParamId1(String paramId1) { m_paramId1 = paramId1; } /** * Sets the paramId2.

* * @param paramId2 the paramId2 to set */ public void setParamId2(String paramId2) { m_paramId2 = paramId2; } /** * Sets the paramLocale.

* * @param paramLocale the paramLocale to set */ public void setParamLocale(String paramLocale) { m_paramLocale = paramLocale; } /** * Sets the paramTextmode.

* * @param paramTextmode the paramTextmode to set */ public void setParamTextmode(String paramTextmode) { m_paramTextmode = paramTextmode; } /** * Sets the paramVersion1.

* * @param paramVersion1 the paramVersion1 to set */ public void setParamVersion1(String paramVersion1) { m_paramVersion1 = paramVersion1; } /** * Sets the paramVersion2.

* * @param paramVersion2 the paramVersion2 to set */ public void setParamVersion2(String paramVersion2) { m_paramVersion2 = paramVersion2; } /** * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest) */ @Override protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { super.initWorkplaceRequestValues(settings, request); try { CmsResource resource1 = CmsResourceComparisonDialog.readResource( getCms(), new CmsUUID(getParamId1()), getParamVersion1()); CmsResource resource2 = CmsResourceComparisonDialog.readResource( getCms(), new CmsUUID(getParamId2()), getParamVersion2()); // if certain element is compared, use html difference dialog if (CmsStringUtil.isNotEmpty(getParamElement())) { m_differenceDialog = new CmsHtmlDifferenceDialog(getJsp()); } else { m_differenceDialog = new CmsDifferenceDialog(getJsp()); } if (CmsResourceComparisonDialog.COMPARE_ATTRIBUTES.equals(getParamCompare())) { List comparedAttributes = CmsResourceComparison.compareAttributes(getCms(), resource1, resource2); String[] attributeStrings = getAttributesAsString(comparedAttributes); m_differenceDialog.setOriginalSource(attributeStrings[0]); m_differenceDialog.setCopySource(attributeStrings[1]); } else if (CmsResourceComparisonDialog.COMPARE_PROPERTIES.equals(getParamCompare())) { List comparedProperties = CmsResourceComparison.compareProperties( getCms(), resource1, getParamVersion1(), resource2, getParamVersion2()); String[] propertyStrings = getPropertiesAsString(comparedProperties); m_differenceDialog.setOriginalSource(propertyStrings[0]); m_differenceDialog.setCopySource(propertyStrings[1]); } else if (resource1.isFile()) { CmsFile file1 = readFile(getCms(), new CmsUUID(getParamId1()), getParamVersion1()); CmsFile file2 = readFile(getCms(), new CmsUUID(getParamId2()), getParamVersion2()); setContentAsSource(file1, file2); } } catch (CmsException e) { LOG.error(e.getMessage(), e); } catch (UnsupportedEncodingException e) { LOG.error(e.getMessage(), e); } } /** * Returns the content of all elements of an xml document appended.

* * @param xmlDoc the xml document to extract the elements from * @return the content of all elements of an xml document appended */ private String extractElements(I_CmsXmlDocument xmlDoc) { StringBuffer result = new StringBuffer(); if (xmlDoc instanceof CmsXmlPage) { List locales = xmlDoc.getLocales(); Iterator i = locales.iterator(); boolean firstIter = true; while (i.hasNext()) { if (!firstIter) { result.append("\n\n-----"); } Locale locale = (Locale)i.next(); result.append("\n\n[").append(locale.toString()).append(']'); List elements = xmlDoc.getValues(locale); Iterator j = elements.iterator(); while (j.hasNext()) { I_CmsXmlContentValue value = (I_CmsXmlContentValue)j.next(); result.append("\n\n["); // output value of name attribute result.append(value.getElement().attribute(0).getValue()); result.append("]\n\n"); try { I_CmsWidget widget = value.getDocument().getHandler().getWidget(value); result.append( widget.getWidgetStringValue( getCms(), new CmsResourceInfoDialog(getJsp()), (I_CmsWidgetParameter)value)); } catch (CmsXmlException e) { LOG.error(e.getMessage(), e); } } firstIter = false; } } else if (xmlDoc instanceof CmsXmlContent) { CmsXmlContentTextExtractor visitor = new CmsXmlContentTextExtractor(result); ((CmsXmlContent)xmlDoc).visitAllValuesWith(visitor); } return result.toString(); } /** * Extracts the content from the files according to the file type.

* * @param file1 the first file to compare * @param file2 the second file to compare * * @throws CmsException if something goes wrong * @throws UnsupportedEncodingException if the encoding of one file is not supported */ private void setContentAsSource(CmsFile file1, CmsFile file2) throws CmsException, UnsupportedEncodingException { CmsObject cms = getCms(); if (CmsStringUtil.isNotEmpty(getParamElement())) { I_CmsXmlDocument resource1; I_CmsXmlDocument resource2; if (CmsResourceTypeXmlPage.isXmlPage(file1)) { resource1 = CmsXmlPageFactory.unmarshal(cms, file1); } else { resource1 = CmsXmlContentFactory.unmarshal(cms, file1); } if (CmsResourceTypeXmlPage.isXmlPage(file2)) { resource2 = CmsXmlPageFactory.unmarshal(cms, file2); } else { resource2 = CmsXmlContentFactory.unmarshal(cms, file2); } I_CmsXmlContentValue value1 = resource1.getValue( getParamElement(), CmsLocaleManager.getLocale(getParamLocale())); I_CmsXmlContentValue value2 = resource2.getValue( getParamElement(), CmsLocaleManager.getLocale(getParamLocale())); if (value1 == null) { m_differenceDialog.setOriginalSource(""); } else { m_differenceDialog.setOriginalSource(value1.getStringValue(cms)); } if (value2 == null) { m_differenceDialog.setCopySource(""); } else { m_differenceDialog.setCopySource(value2.getStringValue(cms)); } } else if (CmsResourceComparisonDialog.COMPARE_ALL_ELEMENTS.equals(getParamCompare())) { I_CmsXmlDocument resource1; I_CmsXmlDocument resource2; if (CmsResourceTypeXmlPage.isXmlPage(file1)) { resource1 = CmsXmlPageFactory.unmarshal(cms, file1); } else { resource1 = CmsXmlContentFactory.unmarshal(cms, file1); } if (CmsResourceTypeXmlPage.isXmlPage(file2)) { resource2 = CmsXmlPageFactory.unmarshal(cms, file2); } else { resource2 = CmsXmlContentFactory.unmarshal(cms, file2); } m_differenceDialog.setOriginalSource(extractElements(resource1)); m_differenceDialog.setCopySource(extractElements(resource2)); } else { // compare whole plain text file m_differenceDialog.setOriginalSource( new String(file1.getContents(), cms.getRequestContext().getEncoding())); m_differenceDialog.setCopySource(new String(file2.getContents(), cms.getRequestContext().getEncoding())); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy