001/*
002 * (C) Copyright 2006-2007 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 */
017
018package org.nuxeo.ecm.platform.preview.helper;
019
020import java.io.Serializable;
021import java.util.Map;
022import java.util.concurrent.ConcurrentHashMap;
023
024import org.apache.commons.lang.StringUtils;
025import org.nuxeo.common.utils.URIUtils;
026import org.nuxeo.ecm.core.api.Blob;
027import org.nuxeo.ecm.core.api.DocumentModel;
028import org.nuxeo.ecm.core.api.DocumentRef;
029import org.nuxeo.ecm.core.api.IdRef;
030import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
031import org.nuxeo.ecm.core.api.blobholder.DocumentBlobHolder;
032import org.nuxeo.ecm.core.io.download.DownloadService;
033import org.nuxeo.ecm.platform.preview.api.HtmlPreviewAdapter;
034import org.nuxeo.ecm.platform.preview.api.PreviewException;
035
036public class PreviewHelper {
037
038    public static final String PREVIEWURL_PREFIX = "restAPI/preview/";
039
040    public static final String PREVIEWURL_DEFAULTXPATH = "default";
041
042    protected static final String PDF_MIMETYPE = "application/pdf";
043
044    protected static final String PDF_EXTENSION = ".pdf";
045
046    protected static final Map<String, Boolean> hasPreviewByType = new ConcurrentHashMap<String, Boolean>();
047
048    private PreviewHelper() {
049    }
050
051    public static String getPreviewURL(DocumentModel doc) {
052        return getPreviewURL(doc, PREVIEWURL_DEFAULTXPATH);
053    }
054
055    public static String getPreviewURL(DocumentModel doc, String xpath) {
056        if (xpath == null) {
057            xpath = PREVIEWURL_DEFAULTXPATH;
058        }
059
060        StringBuilder sb = new StringBuilder();
061
062        sb.append(PREVIEWURL_PREFIX);
063        sb.append(doc.getRepositoryName());
064        sb.append("/");
065        sb.append(doc.getId());
066        sb.append("/");
067        sb.append(xpath);
068        sb.append("/");
069
070        return sb.toString();
071    }
072
073    public static DocumentRef getDocumentRefFromPreviewURL(String url) {
074        if (url == null) {
075            return null;
076        }
077
078        String[] urlParts = url.split(PREVIEWURL_PREFIX);
079        String[] parts = urlParts[1].split("/");
080        String strRef = parts[1];
081        return new IdRef(strRef);
082    }
083
084    public static boolean typeSupportsPreview(DocumentModel doc) {
085        String docType = doc.getType();
086        if (hasPreviewByType.containsKey(docType)) {
087            return hasPreviewByType.get(docType);
088        } else {
089            HtmlPreviewAdapter adapter = doc.getAdapter(HtmlPreviewAdapter.class);
090            if (adapter == null) {
091                synchronized (hasPreviewByType) {
092                    hasPreviewByType.put(docType, false);
093                    return false;
094                }
095            } else {
096                synchronized (hasPreviewByType) {
097                    hasPreviewByType.put(docType, true);
098                    return true;
099                }
100            }
101        }
102    }
103
104    /**
105     * @param document
106     * @throws PreviewException
107     * @since 5.7.3
108     */
109    public static boolean docHasBlobToPreview(DocumentModel document) throws PreviewException {
110        HtmlPreviewAdapter adapter = document.getAdapter(HtmlPreviewAdapter.class);
111        return adapter == null ? false : adapter.hasBlobToPreview();
112    }
113
114    /**
115     * @since 7.3
116     */
117    public static String getViewerURL(DocumentModel doc, String xpath, Blob blob, String baseURL) {
118        baseURL = baseURL.endsWith("/") ? baseURL.substring(0, baseURL.length() - 1) : baseURL;
119        String fileURL = String.format("%s/api/v1/id/%s/@blob/%s", baseURL, doc.getId(),
120            isBlobHolder(doc, xpath) ? DownloadService.BLOBHOLDER_0 : xpath);
121        StringBuilder sb = new StringBuilder();
122        sb.append("viewer/web/viewer.html?file=");
123        sb.append(fileURL);
124        if (!isPDF(blob)) {
125            sb.append("/@convert?");
126            sb.append(URIUtils.quoteURIPathToken("format=pdf"));
127        }
128
129        return sb.toString();
130    }
131
132    /**
133     * @since 7.3
134     */
135    public static boolean isPDF(Blob blob) {
136        String mimeType = blob.getMimeType();
137        if (StringUtils.isNotBlank(mimeType) && PDF_MIMETYPE.equals(mimeType)) {
138            return true;
139        } else {
140            String filename = blob.getFilename();
141            if (StringUtils.isNotBlank(filename) && filename.endsWith(PDF_EXTENSION)) {
142                // assume it's a pdf file
143                return true;
144            }
145        }
146        return false;
147    }
148
149    private static boolean isBlobHolder(DocumentModel doc, String xpath) {
150        DocumentBlobHolder bh = (DocumentBlobHolder) doc.getAdapter(BlobHolder.class);
151        return bh != null && bh.getXpath().equals(xpath);
152    }
153}