/* * (C) Copyright 2016 Nuxeo SA (http://nuxeo.com/) and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Contributors: * * Nelson Silva <nsilva@nuxeo.com> */ package org.nuxeo.ecm.restapi.server.jaxrs.adapters; import org.nuxeo.ecm.core.api.Blob; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.blobholder.BlobHolder; import org.nuxeo.ecm.core.api.blobholder.DocumentBlobHolder; import org.nuxeo.ecm.core.blob.BlobManager; import org.nuxeo.ecm.core.io.download.DownloadService; import org.nuxeo.ecm.platform.preview.api.HtmlPreviewAdapter; import org.nuxeo.ecm.platform.preview.helper.PreviewHelper; import org.nuxeo.ecm.restapi.server.jaxrs.blob.BlobObject; import org.nuxeo.ecm.webengine.WebException; import org.nuxeo.ecm.webengine.model.WebAdapter; import org.nuxeo.ecm.webengine.model.exceptions.WebResourceNotFoundException; import org.nuxeo.ecm.webengine.model.impl.DefaultAdapter; import org.nuxeo.runtime.api.Framework; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.IOException; import java.io.Serializable; import java.io.UncheckedIOException; import java.net.URI; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; /** * @since 8.2 */ @WebAdapter(name = PreviewAdapter.NAME, type = "previewAdapter") @Produces({ MediaType.APPLICATION_JSON }) public class PreviewAdapter extends DefaultAdapter { public static final String NAME = "preview"; @GET public Object preview(@QueryParam("blobPostProcessing") boolean postProcessing, @Context HttpServletRequest request, @Context HttpServletResponse response) { DocumentBlobHolder bh = getBlobHolderToPreview(); // if it's a managed blob try to use the embed uri for preview BlobManager blobManager = Framework.getService(BlobManager.class); try { URI uri = blobManager.getURI(bh.getBlob(), BlobManager.UsageHint.EMBED, null); if (uri != null) { return Response.seeOther(uri).build(); } } catch (IOException e) { throw WebException.wrap(e); } List<Blob> previewBlobs = getPreviewBlobs(bh, postProcessing); if (previewBlobs == null || previewBlobs.isEmpty()) { throw new WebResourceNotFoundException("Preview not available"); } try { Blob blob = previewBlobs.get(0); DownloadService downloadService = Framework.getService(DownloadService.class); downloadService.downloadBlob(request, response, bh.getDocument(), bh.getXpath(), blob, blob.getFilename(), "preview", null, true); } catch (IOException e) { throw WebException.wrap(e); } return Response.ok().build(); } @GET @Path("{subPath}") public Object subPath(@PathParam("subPath") String subPath, @QueryParam("blobPostProcessing") boolean postProcessing, @Context HttpServletRequest request, @Context HttpServletResponse response) { DocumentBlobHolder bh = getBlobHolderToPreview(); List<Blob> previewBlobs = getPreviewBlobs(bh, postProcessing); if (previewBlobs == null || previewBlobs.isEmpty()) { throw new WebResourceNotFoundException("Preview not available"); } // find blob Optional<Blob> subBlob = previewBlobs.stream() .filter(b -> subPath.equals(b.getFilename())) .findFirst(); if (!subBlob.isPresent()) { throw new WebResourceNotFoundException(String.format("Preview blob %s not found", subPath)); } try { Blob blob = subBlob.get(); DownloadService downloadService = Framework.getService(DownloadService.class); Map<String, Serializable> extendedInfos = Collections.singletonMap("subPath", subPath); downloadService.downloadBlob(request, response, bh.getDocument(), bh.getXpath(), blob, blob.getFilename(), "preview", extendedInfos, true); } catch (IOException e) { throw WebException.wrap(e); } return Response.ok().build(); } private List<Blob> getPreviewBlobs(DocumentBlobHolder bh, boolean blobPostProcessing) { DocumentModel doc = bh.getDocument(); String xpath = bh.getXpath(); HtmlPreviewAdapter preview; if (isBlobTarget() && !isBlobHolder(doc, xpath)) { preview = PreviewHelper.getBlobPreviewAdapter(doc); return preview.getFilePreviewBlobs(xpath, blobPostProcessing); } preview = doc.getAdapter(HtmlPreviewAdapter.class); if (preview == null) { return null; } return preview.getFilePreviewBlobs(blobPostProcessing); } private DocumentBlobHolder getBlobHolderToPreview() { DocumentModel doc; if (isBlobTarget()) { BlobObject target = (BlobObject) getTarget(); doc = target.getDocument(); if (!isBlobHolder(doc, target.getXpath())) { return new DocumentBlobHolder(doc, target.getXpath()); } } else { doc = getTarget().getAdapter(DocumentModel.class); } return (DocumentBlobHolder) doc.getAdapter(BlobHolder.class); } private boolean isBlobTarget() { return getTarget().isInstanceOf("blob"); } private boolean isBlobHolder(DocumentModel doc, String xpath) { DocumentBlobHolder bh = (DocumentBlobHolder) doc.getAdapter(BlobHolder.class); return bh != null && bh.getXpath().equals(xpath); } }