Search in sources :

Example 1 with DisplayMode

use of org.apache.nifi.web.ViewableContent.DisplayMode in project nifi by apache.

the class ContentViewerController method doGet.

/**
 * Gets the content and defers to registered viewers to generate the markup.
 *
 * @param request servlet request
 * @param response servlet response
 * @throws ServletException if a servlet-specific error occurs
 * @throws IOException if an I/O error occurs
 */
@Override
protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
    // specify the charset in a response header
    response.addHeader("Content-Type", "text/html; charset=UTF-8");
    // get the content
    final ServletContext servletContext = request.getServletContext();
    final ContentAccess contentAccess = (ContentAccess) servletContext.getAttribute("nifi-content-access");
    final ContentRequestContext contentRequest;
    try {
        contentRequest = getContentRequest(request);
    } catch (final Exception e) {
        request.setAttribute("title", "Error");
        request.setAttribute("messages", "Unable to interpret content request.");
        // forward to the error page
        final ServletContext viewerContext = servletContext.getContext("/nifi");
        viewerContext.getRequestDispatcher("/message").forward(request, response);
        return;
    }
    if (contentRequest.getDataUri() == null) {
        request.setAttribute("title", "Error");
        request.setAttribute("messages", "The data reference must be specified.");
        // forward to the error page
        final ServletContext viewerContext = servletContext.getContext("/nifi");
        viewerContext.getRequestDispatcher("/message").forward(request, response);
        return;
    }
    // get the content
    final DownloadableContent downloadableContent;
    try {
        downloadableContent = contentAccess.getContent(contentRequest);
    } catch (final ResourceNotFoundException rnfe) {
        request.setAttribute("title", "Error");
        request.setAttribute("messages", "Unable to find the specified content");
        // forward to the error page
        final ServletContext viewerContext = servletContext.getContext("/nifi");
        viewerContext.getRequestDispatcher("/message").forward(request, response);
        return;
    } catch (final AccessDeniedException ade) {
        request.setAttribute("title", "Access Denied");
        request.setAttribute("messages", "Unable to approve access to the specified content: " + ade.getMessage());
        // forward to the error page
        final ServletContext viewerContext = servletContext.getContext("/nifi");
        viewerContext.getRequestDispatcher("/message").forward(request, response);
        return;
    } catch (final Exception e) {
        request.setAttribute("title", "Error");
        request.setAttribute("messages", "An unexpected error has occurred: " + e.getMessage());
        // forward to the error page
        final ServletContext viewerContext = servletContext.getContext("/nifi");
        viewerContext.getRequestDispatcher("/message").forward(request, response);
        return;
    }
    // determine how we want to view the data
    String mode = request.getParameter("mode");
    // if the name isn't set, use original
    if (mode == null) {
        mode = DisplayMode.Original.name();
    }
    // determine the display mode
    final DisplayMode displayMode;
    try {
        displayMode = DisplayMode.valueOf(mode);
    } catch (final IllegalArgumentException iae) {
        request.setAttribute("title", "Error");
        request.setAttribute("messages", "Invalid display mode: " + mode);
        // forward to the error page
        final ServletContext viewerContext = servletContext.getContext("/nifi");
        viewerContext.getRequestDispatcher("/message").forward(request, response);
        return;
    }
    // buffer the content to support resetting in case we need to detect the content type or char encoding
    try (final BufferedInputStream bis = new BufferedInputStream(downloadableContent.getContent())) {
        final String mimeType;
        final String normalizedMimeType;
        // when clustered and we don't know the type set to octet stream since the content was retrieved from the node's rest endpoint
        if (downloadableContent.getType() == null || StringUtils.startsWithIgnoreCase(downloadableContent.getType(), MediaType.OCTET_STREAM.toString())) {
            // attempt to detect the content stream if we don't know what it is ()
            final DefaultDetector detector = new DefaultDetector();
            // create the stream for tika to process, buffered to support reseting
            final TikaInputStream tikaStream = TikaInputStream.get(bis);
            // provide a hint based on the filename
            final Metadata metadata = new Metadata();
            metadata.set(Metadata.RESOURCE_NAME_KEY, downloadableContent.getFilename());
            // Get mime type
            final MediaType mediatype = detector.detect(tikaStream, metadata);
            mimeType = mediatype.toString();
        } else {
            mimeType = downloadableContent.getType();
        }
        // Extract only mime type and subtype from content type (anything after the first ; are parameters)
        // Lowercase so subsequent code does not need to implement case insensitivity
        normalizedMimeType = mimeType.split(";", 2)[0].toLowerCase();
        // add attributes needed for the header
        request.setAttribute("filename", downloadableContent.getFilename());
        request.setAttribute("contentType", mimeType);
        // generate the header
        request.getRequestDispatcher("/WEB-INF/jsp/header.jsp").include(request, response);
        // remove the attributes needed for the header
        request.removeAttribute("filename");
        request.removeAttribute("contentType");
        // generate the markup for the content based on the display mode
        if (DisplayMode.Hex.equals(displayMode)) {
            final byte[] buffer = new byte[BUFFER_LENGTH];
            final int read = StreamUtils.fillBuffer(bis, buffer, false);
            // trim the byte array if necessary
            byte[] bytes = buffer;
            if (read != buffer.length) {
                bytes = new byte[read];
                System.arraycopy(buffer, 0, bytes, 0, read);
            }
            // convert bytes into the base 64 bytes
            final String base64 = Base64.encodeBase64String(bytes);
            // defer to the jsp
            request.setAttribute("content", base64);
            request.getRequestDispatcher("/WEB-INF/jsp/hexview.jsp").include(request, response);
        } else {
            // lookup a viewer for the content
            final String contentViewerUri = servletContext.getInitParameter(normalizedMimeType);
            // handle no viewer for content type
            if (contentViewerUri == null) {
                request.getRequestDispatcher("/WEB-INF/jsp/no-viewer.jsp").include(request, response);
            } else {
                // create a request attribute for accessing the content
                request.setAttribute(ViewableContent.CONTENT_REQUEST_ATTRIBUTE, new ViewableContent() {

                    @Override
                    public InputStream getContentStream() {
                        return bis;
                    }

                    @Override
                    public String getContent() throws IOException {
                        // detect the charset
                        final CharsetDetector detector = new CharsetDetector();
                        detector.setText(bis);
                        detector.enableInputFilter(true);
                        final CharsetMatch match = detector.detect();
                        // ensure we were able to detect the charset
                        if (match == null) {
                            throw new IOException("Unable to detect character encoding.");
                        }
                        // convert the stream using the detected charset
                        return IOUtils.toString(bis, match.getName());
                    }

                    @Override
                    public ViewableContent.DisplayMode getDisplayMode() {
                        return displayMode;
                    }

                    @Override
                    public String getFileName() {
                        return downloadableContent.getFilename();
                    }

                    @Override
                    public String getContentType() {
                        return normalizedMimeType;
                    }

                    @Override
                    public String getRawContentType() {
                        return mimeType;
                    }
                });
                try {
                    // generate the content
                    final ServletContext viewerContext = servletContext.getContext(contentViewerUri);
                    viewerContext.getRequestDispatcher("/view-content").include(request, response);
                } catch (final Exception e) {
                    String message = e.getMessage() != null ? e.getMessage() : e.toString();
                    message = "Unable to generate view of data: " + message;
                    // log the error
                    logger.error(message);
                    if (logger.isDebugEnabled()) {
                        logger.error(StringUtils.EMPTY, e);
                    }
                    // populate the request attributes
                    request.setAttribute("title", "Error");
                    request.setAttribute("messages", message);
                    // forward to the error page
                    final ServletContext viewerContext = servletContext.getContext("/nifi");
                    viewerContext.getRequestDispatcher("/message").forward(request, response);
                    return;
                }
                // remove the request attribute
                request.removeAttribute(ViewableContent.CONTENT_REQUEST_ATTRIBUTE);
            }
        }
        // generate footer
        request.getRequestDispatcher("/WEB-INF/jsp/footer.jsp").include(request, response);
    }
}
Also used : DefaultDetector(org.apache.tika.detect.DefaultDetector) AccessDeniedException(org.apache.nifi.authorization.AccessDeniedException) BufferedInputStream(java.io.BufferedInputStream) TikaInputStream(org.apache.tika.io.TikaInputStream) InputStream(java.io.InputStream) CharsetDetector(com.ibm.icu.text.CharsetDetector) Metadata(org.apache.tika.metadata.Metadata) TikaInputStream(org.apache.tika.io.TikaInputStream) IOException(java.io.IOException) ServletException(javax.servlet.ServletException) AccessDeniedException(org.apache.nifi.authorization.AccessDeniedException) IOException(java.io.IOException) DisplayMode(org.apache.nifi.web.ViewableContent.DisplayMode) CharsetMatch(com.ibm.icu.text.CharsetMatch) BufferedInputStream(java.io.BufferedInputStream) ServletContext(javax.servlet.ServletContext) MediaType(org.apache.tika.mime.MediaType)

Aggregations

CharsetDetector (com.ibm.icu.text.CharsetDetector)1 CharsetMatch (com.ibm.icu.text.CharsetMatch)1 BufferedInputStream (java.io.BufferedInputStream)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 ServletContext (javax.servlet.ServletContext)1 ServletException (javax.servlet.ServletException)1 AccessDeniedException (org.apache.nifi.authorization.AccessDeniedException)1 DisplayMode (org.apache.nifi.web.ViewableContent.DisplayMode)1 DefaultDetector (org.apache.tika.detect.DefaultDetector)1 TikaInputStream (org.apache.tika.io.TikaInputStream)1 Metadata (org.apache.tika.metadata.Metadata)1 MediaType (org.apache.tika.mime.MediaType)1