001/*
002 * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 */
015
016package org.nuxeo.ecm.platform.preview.helper;
017
018import java.io.Serializable;
019import java.util.Map;
020import java.util.concurrent.ConcurrentHashMap;
021
022import org.apache.commons.lang.StringUtils;
023import org.nuxeo.common.utils.URIUtils;
024import org.nuxeo.ecm.core.api.Blob;
025import org.nuxeo.ecm.core.api.DocumentModel;
026import org.nuxeo.ecm.core.api.DocumentRef;
027import org.nuxeo.ecm.core.api.IdRef;
028import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
029import org.nuxeo.ecm.core.api.blobholder.DocumentBlobHolder;
030import org.nuxeo.ecm.core.io.download.DownloadService;
031import org.nuxeo.ecm.platform.preview.api.HtmlPreviewAdapter;
032import org.nuxeo.ecm.platform.preview.api.PreviewException;
033
034public class PreviewHelper {
035
036    public static final String PREVIEWURL_PREFIX = "restAPI/preview/";
037
038    public static final String PREVIEWURL_DEFAULTXPATH = "default";
039
040    protected static final String PDF_MIMETYPE = "application/pdf";
041
042    protected static final String PDF_EXTENSION = ".pdf";
043
044    protected static final Map<String, Boolean> hasPreviewByType = new ConcurrentHashMap<String, Boolean>();
045
046    private PreviewHelper() {
047    }
048
049    public static String getPreviewURL(DocumentModel doc) {
050        return getPreviewURL(doc, PREVIEWURL_DEFAULTXPATH);
051    }
052
053    public static String getPreviewURL(DocumentModel doc, String xpath) {
054        if (xpath == null) {
055            xpath = PREVIEWURL_DEFAULTXPATH;
056        }
057
058        StringBuilder sb = new StringBuilder();
059
060        sb.append(PREVIEWURL_PREFIX);
061        sb.append(doc.getRepositoryName());
062        sb.append("/");
063        sb.append(doc.getId());
064        sb.append("/");
065        sb.append(xpath);
066        sb.append("/");
067
068        return sb.toString();
069    }
070
071    public static DocumentRef getDocumentRefFromPreviewURL(String url) {
072        if (url == null) {
073            return null;
074        }
075
076        String[] urlParts = url.split(PREVIEWURL_PREFIX);
077        String[] parts = urlParts[1].split("/");
078        String strRef = parts[1];
079        return new IdRef(strRef);
080    }
081
082    public static boolean typeSupportsPreview(DocumentModel doc) {
083        String docType = doc.getType();
084        if (hasPreviewByType.containsKey(docType)) {
085            return hasPreviewByType.get(docType);
086        } else {
087            HtmlPreviewAdapter adapter = doc.getAdapter(HtmlPreviewAdapter.class);
088            if (adapter == null) {
089                synchronized (hasPreviewByType) {
090                    hasPreviewByType.put(docType, false);
091                    return false;
092                }
093            } else {
094                synchronized (hasPreviewByType) {
095                    hasPreviewByType.put(docType, true);
096                    return true;
097                }
098            }
099        }
100    }
101
102    /**
103     * @param document
104     * @throws PreviewException
105     * @since 5.7.3
106     */
107    public static boolean docHasBlobToPreview(DocumentModel document) throws PreviewException {
108        HtmlPreviewAdapter adapter = document.getAdapter(HtmlPreviewAdapter.class);
109        return adapter == null ? false : adapter.hasBlobToPreview();
110    }
111
112    /**
113     * @since 7.3
114     */
115    public static String getViewerURL(DocumentModel doc, String xpath, Blob blob, String baseURL) {
116        baseURL = baseURL.endsWith("/") ? baseURL.substring(0, baseURL.length() - 1) : baseURL;
117        String fileURL = String.format("%s/api/v1/id/%s/@blob/%s", baseURL, doc.getId(),
118            isBlobHolder(doc, xpath) ? DownloadService.BLOBHOLDER_0 : xpath);
119        StringBuilder sb = new StringBuilder();
120        sb.append("viewer/web/viewer.html?file=");
121        sb.append(fileURL);
122        if (!isPDF(blob)) {
123            sb.append("/@convert?");
124            sb.append(URIUtils.quoteURIPathToken("format=pdf"));
125        }
126
127        return sb.toString();
128    }
129
130    /**
131     * @since 7.3
132     */
133    public static boolean isPDF(Blob blob) {
134        String mimeType = blob.getMimeType();
135        if (StringUtils.isNotBlank(mimeType) && PDF_MIMETYPE.equals(mimeType)) {
136            return true;
137        } else {
138            String filename = blob.getFilename();
139            if (StringUtils.isNotBlank(filename) && filename.endsWith(PDF_EXTENSION)) {
140                // assume it's a pdf file
141                return true;
142            }
143        }
144        return false;
145    }
146
147    private static boolean isBlobHolder(DocumentModel doc, String xpath) {
148        DocumentBlobHolder bh = (DocumentBlobHolder) doc.getAdapter(BlobHolder.class);
149        return bh != null && bh.getXpath().equals(xpath);
150    }
151}