001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.documentlibrary.action;
016    
017    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
018    import com.liferay.portal.kernel.servlet.SessionErrors;
019    import com.liferay.portal.kernel.util.DiffResult;
020    import com.liferay.portal.kernel.util.DiffUtil;
021    import com.liferay.portal.kernel.util.FileUtil;
022    import com.liferay.portal.kernel.util.HtmlUtil;
023    import com.liferay.portal.kernel.util.ParamUtil;
024    import com.liferay.portal.kernel.util.PropsKeys;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.util.StringUtil;
027    import com.liferay.portal.security.auth.PrincipalException;
028    import com.liferay.portal.security.permission.ActionKeys;
029    import com.liferay.portal.struts.PortletAction;
030    import com.liferay.portal.theme.ThemeDisplay;
031    import com.liferay.portal.util.PrefsPropsUtil;
032    import com.liferay.portal.util.PropsValues;
033    import com.liferay.portal.util.WebKeys;
034    import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
035    import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
036    import com.liferay.portlet.documentlibrary.service.permission.DLFileEntryPermission;
037    import com.liferay.portlet.documentlibrary.util.DocumentConversionUtil;
038    
039    import java.io.InputStream;
040    import java.io.InputStreamReader;
041    
042    import java.util.List;
043    
044    import javax.portlet.PortletConfig;
045    import javax.portlet.RenderRequest;
046    import javax.portlet.RenderResponse;
047    
048    import org.apache.struts.action.ActionForm;
049    import org.apache.struts.action.ActionForward;
050    import org.apache.struts.action.ActionMapping;
051    
052    /**
053     * @author Bruno Farache
054     */
055    public class CompareVersionsAction extends PortletAction {
056    
057            public ActionForward render(
058                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
059                            RenderRequest renderRequest, RenderResponse renderResponse)
060                    throws Exception {
061    
062                    try {
063                            compareVersions(renderRequest);
064                    }
065                    catch (Exception e) {
066                            if (e instanceof NoSuchFileEntryException ||
067                                    e instanceof PrincipalException) {
068    
069                                    SessionErrors.add(renderRequest, e.getClass().getName());
070    
071                                    setForward(renderRequest, "portlet.document_library.error");
072                            }
073                            else {
074                                    throw e;
075                            }
076                    }
077    
078                    return mapping.findForward("portlet.document_library.compare_versions");
079            }
080    
081            protected void compareVersions(RenderRequest renderRequest)
082                    throws Exception {
083    
084                    ThemeDisplay themeDisplay = (ThemeDisplay)renderRequest.getAttribute(
085                            WebKeys.THEME_DISPLAY);
086    
087                    long companyId = themeDisplay.getCompanyId();
088                    long userId = themeDisplay.getUserId();
089    
090                    long fileEntryId = ParamUtil.getLong(renderRequest, "fileEntryId");
091    
092                    long groupId = themeDisplay.getScopeGroupId();
093                    long folderId = ParamUtil.getLong(renderRequest, "folderId");
094                    String name = ParamUtil.getString(renderRequest, "name");
095    
096                    DLFileEntryPermission.check(
097                            themeDisplay.getPermissionChecker(), groupId, folderId, name,
098                            ActionKeys.VIEW);
099    
100                    String extension = FileUtil.getExtension(name);
101    
102                    String titleWithExtension = ParamUtil.getString(
103                            renderRequest, "titleWithExtension");
104    
105                    String sourceVersion = ParamUtil.getString(
106                            renderRequest, "sourceVersion");
107                    String targetVersion = ParamUtil.getString(
108                            renderRequest, "targetVersion");
109    
110                    InputStream sourceIs = DLFileEntryLocalServiceUtil.getFileAsStream(
111                            companyId, userId, groupId, folderId, name, sourceVersion);
112                    InputStream targetIs = DLFileEntryLocalServiceUtil.getFileAsStream(
113                            companyId, userId, groupId, folderId, name, targetVersion);
114    
115                    if (extension.equals("htm") || extension.equals("html") ||
116                            extension.equals("xml")) {
117    
118                            String escapedSource = HtmlUtil.escape(StringUtil.read(sourceIs));
119                            String escapedTarget = HtmlUtil.escape(StringUtil.read(targetIs));
120    
121                            sourceIs = new UnsyncByteArrayInputStream(
122                                    escapedSource.getBytes(StringPool.UTF8));
123                            targetIs = new UnsyncByteArrayInputStream(
124                                    escapedTarget.getBytes(StringPool.UTF8));
125                    }
126    
127                    if (PrefsPropsUtil.getBoolean(
128                                    PropsKeys.OPENOFFICE_SERVER_ENABLED,
129                                    PropsValues.OPENOFFICE_SERVER_ENABLED) &&
130                            isConvertBeforeCompare(extension)) {
131    
132                            String sourceTempFileId = DocumentConversionUtil.getTempFileId(
133                                    fileEntryId, sourceVersion);
134                            String targetTempFileId = DocumentConversionUtil.getTempFileId(
135                                    fileEntryId, targetVersion);
136    
137                            sourceIs = DocumentConversionUtil.convert(
138                                    sourceTempFileId, sourceIs, extension, "txt");
139                            targetIs = DocumentConversionUtil.convert(
140                                    targetTempFileId, targetIs, extension, "txt");
141                    }
142    
143                    List<DiffResult>[] diffResults = DiffUtil.diff(
144                            new InputStreamReader(sourceIs), new InputStreamReader(targetIs));
145    
146                    renderRequest.setAttribute(
147                            WebKeys.SOURCE_NAME,
148                            titleWithExtension + StringPool.SPACE + sourceVersion);
149                    renderRequest.setAttribute(
150                            WebKeys.TARGET_NAME,
151                            titleWithExtension + StringPool.SPACE + targetVersion);
152                    renderRequest.setAttribute(WebKeys.DIFF_RESULTS, diffResults);
153            }
154    
155            protected boolean isConvertBeforeCompare(String extension) {
156                    if (extension.equals("txt")) {
157                            return false;
158                    }
159    
160                    String[] conversions = DocumentConversionUtil.getConversions(extension);
161    
162                    for (int i = 0; i < conversions.length; i++) {
163                            if (conversions[i].equals("txt")) {
164                                    return true;
165                            }
166                    }
167    
168                    return false;
169            }
170    
171    }