001/*
002 * (C) Copyright 2006-2009 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 * Contributors:
017 *     Nuxeo - initial API and implementation
018 *
019 * $Id$
020 */
021
022package org.nuxeo.ecm.platform.preview.converters;
023
024import java.io.IOException;
025import java.io.Serializable;
026import java.util.ArrayList;
027import java.util.List;
028import java.util.Map;
029
030import org.nuxeo.ecm.core.api.Blob;
031import org.nuxeo.ecm.core.api.Blobs;
032import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
033import org.nuxeo.ecm.core.convert.api.ConversionException;
034import org.nuxeo.ecm.core.convert.api.ConversionService;
035import org.nuxeo.ecm.core.convert.api.ConverterCheckResult;
036import org.nuxeo.ecm.core.convert.extension.ConverterDescriptor;
037import org.nuxeo.ecm.core.convert.extension.ExternalConverter;
038import org.nuxeo.ecm.platform.htmlsanitizer.HtmlSanitizerService;
039import org.nuxeo.ecm.platform.preview.helper.PreviewHelper;
040import org.nuxeo.runtime.api.Framework;
041
042public class HtmlPreviewConverter implements ExternalConverter {
043
044    /**
045     * @deprecated since 11.1. Use {@link Framework#getService(Class)} with {@link ConversionService} instead.
046     */
047    @Deprecated
048    protected static ConversionService cs;
049
050    protected static Boolean canUsePDF2Html;
051
052    protected static Boolean canUseOOo2Html;
053
054    /**
055     * @deprecated since 11.1. Use {@link Framework#getService(Class)} with {@link ConversionService} instead.
056     */
057    @Deprecated
058    protected static ConversionService getConversionService() {
059        if (cs == null) {
060            cs = Framework.getService(ConversionService.class);
061        }
062        return cs;
063    }
064
065    protected static boolean getCanUsePDF2Html() {
066        if (canUsePDF2Html == null) {
067            try {
068                canUsePDF2Html = Framework.getService(ConversionService.class)
069                                          .isConverterAvailable("pdf2html")
070                                          .isAvailable();
071            } catch (ConversionException e) {
072                return false;
073            }
074        }
075        return canUsePDF2Html;
076    }
077
078    protected static boolean getCanUseOOo2Html() {
079        if (canUseOOo2Html == null) {
080            try {
081                canUseOOo2Html = Framework.getService(ConversionService.class)
082                                          .isConverterAvailable("office2html")
083                                          .isAvailable();
084            } catch (ConversionException e) {
085                return false;
086            }
087        }
088        return canUseOOo2Html;
089    }
090
091    protected List<String> getConverterChain(String srcMT) {
092        List<String> subConverters = new ArrayList<>();
093
094        if (srcMT == null) {
095            return null;
096        }
097
098        if (srcMT.equals("text/html") || srcMT.equals("text/xml") || srcMT.equals("text/xhtml")) {
099            return subConverters;
100        }
101
102        if (getCanUsePDF2Html()) {
103            if (srcMT.equals("application/pdf")) {
104                subConverters.add("pdf2html");
105            } else {
106                subConverters.add("any2pdf");
107                subConverters.add("pdf2html");
108            }
109        } else {
110            if (getCanUseOOo2Html()) {
111                subConverters.add("office2html");
112            } else {
113                return null;
114            }
115        }
116
117        return subConverters;
118    }
119
120    @Override
121    public BlobHolder convert(BlobHolder blobHolder, Map<String, Serializable> parameters) throws ConversionException {
122
123        Blob sourceBlob = blobHolder.getBlob();
124
125        List<String> subConverters = getConverterChain(sourceBlob.getMimeType());
126
127        if (subConverters == null) {
128            throw new ConversionException("Can not find suitable underlying converters to handle html preview",
129                    blobHolder);
130        }
131
132        BlobHolder result = blobHolder;
133
134        for (String converterName : subConverters) {
135            result = Framework.getService(ConversionService.class).convert(converterName, result, parameters);
136        }
137
138        Blob blob = result.getBlob();
139
140        // sanitize result
141        HtmlSanitizerService sanitizer = Framework.getService(HtmlSanitizerService.class);
142        if (sanitizer == null) {
143            throw new RuntimeException("Cannot find HtmlSanitizerService");
144        }
145        String body;
146        try {
147            body = sanitizer.sanitizeString(blob.getString(), null);
148        } catch (IOException e) {
149            throw new ConversionException(e);
150        }
151        String html = PreviewHelper.makeHtmlPage(body);
152        blob = Blobs.createBlob(html, "text/html", null, blob.getFilename());
153        result.setBlob(blob);
154
155        return result;
156    }
157
158    @Override
159    public void init(ConverterDescriptor descriptor) {
160        // TODO Auto-generated method stub
161    }
162
163    @Override
164    public ConverterCheckResult isConverterAvailable() {
165        ConverterCheckResult result = new ConverterCheckResult();
166        result.setAvailable(getCanUseOOo2Html() || getCanUsePDF2Html());
167        return result;
168    }
169
170}