You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2015/02/26 04:51:07 UTC

incubator-nifi git commit: NIFI-353: - Starting to moving the hex viewer into the main content viewer web application that comes bundled in framework. Previously it was only in the standard content viewer extension but we want to be able to render the co

Repository: incubator-nifi
Updated Branches:
  refs/heads/NIFI-353 60c411de0 -> cc0b6fe2f


NIFI-353:
- Starting to moving the hex viewer into the main content viewer web application that comes bundled in framework. Previously it was only in the standard content viewer extension but we want to be able to render the content in hex for all types of data.

Project: http://git-wip-us.apache.org/repos/asf/incubator-nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-nifi/commit/cc0b6fe2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-nifi/tree/cc0b6fe2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-nifi/diff/cc0b6fe2

Branch: refs/heads/NIFI-353
Commit: cc0b6fe2f2b852457824357ff493b5c4e9d44ccd
Parents: 60c411d
Author: Matt Gilman <ma...@gmail.com>
Authored: Wed Feb 25 22:50:23 2015 -0500
Committer: Matt Gilman <ma...@gmail.com>
Committed: Wed Feb 25 22:50:23 2015 -0500

----------------------------------------------------------------------
 .../org/apache/nifi/web/ViewableContent.java    |  15 ++
 .../nifi/web/ContentViewerController.java       | 157 ++++++++++-------
 .../src/main/webapp/WEB-INF/jsp/header.jsp      |   4 +
 .../src/main/webapp/WEB-INF/jsp/hexview.jsp     |  34 ++++
 .../src/main/webapp/js/hexview/LICENSE          |  32 ++++
 .../main/webapp/js/hexview/hexview.default.css  |  10 ++
 .../src/main/webapp/js/hexview/hexview.js       | 175 +++++++++++++++++++
 .../web/StandardContentViewerController.java    |  57 +++---
 .../main/webapp/META-INF/nifi-content-viewer    |   3 +-
 .../src/main/webapp/WEB-INF/jsp/hexview.jsp     |  35 ----
 .../src/main/webapp/js/hexview/LICENSE          |  32 ----
 .../main/webapp/js/hexview/hexview.default.css  |  10 --
 .../src/main/webapp/js/hexview/hexview.js       | 175 -------------------
 13 files changed, 396 insertions(+), 343 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/cc0b6fe2/nifi/nifi-api/src/main/java/org/apache/nifi/web/ViewableContent.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-api/src/main/java/org/apache/nifi/web/ViewableContent.java b/nifi/nifi-api/src/main/java/org/apache/nifi/web/ViewableContent.java
index 25eee9a..cece3c5 100644
--- a/nifi/nifi-api/src/main/java/org/apache/nifi/web/ViewableContent.java
+++ b/nifi/nifi-api/src/main/java/org/apache/nifi/web/ViewableContent.java
@@ -26,6 +26,12 @@ public interface ViewableContent {
 
     public static final String CONTENT_REQUEST_ATTRIBUTE = "org.apache.nifi.web.content";
     
+    public enum DisplayMode {
+        Original,
+        Formatted,
+        Hex;
+    }
+    
     /**
      * The stream to the viewable content.
      * 
@@ -42,6 +48,15 @@ public interface ViewableContent {
     String getContent() throws IOException;
     
     /**
+     * Returns the desired play mode. If the mode is Hex the
+     * framework will handle generating the mark up. The only
+     * values that an extension will see is Original or Formatted.
+     * 
+     * @return 
+     */
+    DisplayMode getDisplayMode();
+    
+    /**
      * The contents file name.
      *  
      * @return 

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/cc0b6fe2/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/java/org/apache/nifi/web/ContentViewerController.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/java/org/apache/nifi/web/ContentViewerController.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/java/org/apache/nifi/web/ContentViewerController.java
index b538631..cad4819 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/java/org/apache/nifi/web/ContentViewerController.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/java/org/apache/nifi/web/ContentViewerController.java
@@ -20,7 +20,6 @@ import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintWriter;
-import java.nio.charset.Charset;
 import javax.servlet.RequestDispatcher;
 
 import javax.servlet.ServletContext;
@@ -29,7 +28,9 @@ import javax.servlet.annotation.WebServlet;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.io.IOUtils;
+import org.apache.nifi.web.ViewableContent.DisplayMode;
 import org.apache.tika.detect.DefaultDetector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
@@ -46,7 +47,7 @@ import org.slf4j.LoggerFactory;
 public class ContentViewerController extends HttpServlet {
 
     private static final Logger logger = LoggerFactory.getLogger(ContentViewerController.class);
-
+    
     /**
      *
      * @param request servlet request
@@ -67,81 +68,115 @@ public class ContentViewerController extends HttpServlet {
             return;
         }
 
-        // detect the content type
-        final DefaultDetector detector = new DefaultDetector();
-
-        // create the stream for tika to process, buffer to support reseting
-        final BufferedInputStream bis = new BufferedInputStream(downloadableContent.getContent());
-        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());
+        // determine how we want to view the data
+        String mode = request.getParameter("mode");
         
-        // Get mime type
-        final MediaType mediatype = detector.detect(tikaStream, metadata);
-        final String mimeType = mediatype.toString();
+        // if the name isn't set, use original
+        if (mode == null) {
+            mode = DisplayMode.Original.name();
+        }
         
-        // lookup a viewer for the content
-        final String contentViewerUri = servletContext.getInitParameter(mimeType);
-
-        // handle no viewer for content type
-        if (contentViewerUri == null) {
+        final DisplayMode displayMode;
+        try {
+            displayMode = DisplayMode.valueOf(mode);
+        } catch (final IllegalArgumentException iae) {
             final PrintWriter out = response.getWriter();
-            out.println("No viewer...");
-            out.println("identified mime type: " + mimeType);
-            out.println("filename: " + downloadableContent.getFilename());
-            out.println("type: " + downloadableContent.getType());
+            out.println("Invalid display mode: " + mode);
             
             return;
         }
-
+        
         // generate the header
         final RequestDispatcher header = request.getRequestDispatcher("/WEB-INF/jsp/header.jsp");
         header.include(request, response);
-
-        // create a request attribute for accessing the content
-        request.setAttribute(ViewableContent.CONTENT_REQUEST_ATTRIBUTE, new ViewableContent() {
-            @Override
-            public InputStream getContentStream() {
-                return bis;
+        
+        // generate the markup for the content based on the display mode
+        if (DisplayMode.Hex.equals(displayMode)) {
+            // convert stream into the base 64 bytes
+            final byte[] bytes = IOUtils.toByteArray(downloadableContent.getContent());
+            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 {
+            // detect the content type
+            final DefaultDetector detector = new DefaultDetector();
+
+            // create the stream for tika to process, buffer to support reseting
+            final BufferedInputStream bis = new BufferedInputStream(downloadableContent.getContent());
+            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);
+            final String mimeType = mediatype.toString();
+
+            // lookup a viewer for the content
+            final String contentViewerUri = servletContext.getInitParameter(mimeType);
+
+            // handle no viewer for content type
+            if (contentViewerUri == null) {
+                final PrintWriter out = response.getWriter();
+                out.println("No viewer...");
+                out.println("identified mime type: " + mimeType);
+                out.println("filename: " + downloadableContent.getFilename());
+                out.println("type: " + downloadableContent.getType());
+
+                return;
             }
 
-            @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.");
+            // create a request attribute for accessing the content
+            request.setAttribute(ViewableContent.CONTENT_REQUEST_ATTRIBUTE, new ViewableContent() {
+                @Override
+                public InputStream getContentStream() {
+                    return bis;
                 }
-                
-                // convert the stream using the detected charset
-                return IOUtils.toString(bis, match.getName());
-            }
 
-            @Override
-            public String getFileName() {
-                return downloadableContent.getFilename();
-            }
+                @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 String getContentType() {
-                return mimeType;
-            }
-        });
+                @Override
+                public ViewableContent.DisplayMode getDisplayMode() {
+                    return displayMode;
+                }
+
+                @Override
+                public String getFileName() {
+                    return downloadableContent.getFilename();
+                }
 
-        // generate the content
-        final ServletContext viewerContext = servletContext.getContext(contentViewerUri);
-        final RequestDispatcher content = viewerContext.getRequestDispatcher("/view-content");
-        content.include(request, response);
+                @Override
+                public String getContentType() {
+                    return mimeType;
+                }
+            });
+
+            // generate the content
+            final ServletContext viewerContext = servletContext.getContext(contentViewerUri);
+            final RequestDispatcher content = viewerContext.getRequestDispatcher("/view-content");
+            content.include(request, response);
 
-        // remove the request attribute
-        request.removeAttribute(ViewableContent.CONTENT_REQUEST_ATTRIBUTE);
+            // remove the request attribute
+            request.removeAttribute(ViewableContent.CONTENT_REQUEST_ATTRIBUTE);
+        }
 
         // generate footer
         final RequestDispatcher footer = request.getRequestDispatcher("/WEB-INF/jsp/footer.jsp");

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/cc0b6fe2/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/WEB-INF/jsp/header.jsp
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/WEB-INF/jsp/header.jsp b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/WEB-INF/jsp/header.jsp
index b15b615..0a17604 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/WEB-INF/jsp/header.jsp
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/WEB-INF/jsp/header.jsp
@@ -24,6 +24,10 @@
         <link href="css/main.css" rel="stylesheet" type="text/css" />
         <link href="../nifi/css/message-pane.css" rel="stylesheet" type="text/css" />
         <link href="../nifi/css/message-page.css" rel="stylesheet" type="text/css" />
+        <link rel="stylesheet" href="../nifi/js/jquery/combo/jquery.combo.css" type="text/css" />
+        <script type="text/javascript" src="../nifi/js/jquery/jquery-2.1.1.min.js"></script>
+        <script type="text/javascript" src="../nifi/js/jquery/combo/jquery.combo.js"></script>
+        <script type="text/javascript" src="js/application.js"></script>
     </head>
 
     <body class="message-pane">

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/cc0b6fe2/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/WEB-INF/jsp/hexview.jsp
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/WEB-INF/jsp/hexview.jsp b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/WEB-INF/jsp/hexview.jsp
new file mode 100644
index 0000000..f2270d7
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/WEB-INF/jsp/hexview.jsp
@@ -0,0 +1,34 @@
+<%--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+--%>
+<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
+<link rel="stylesheet" href="js/hexview/hexview.default.css" type="text/css" />
+<script type="text/javascript" src="js/hexview/hexview.js"></script>
+
+<div id="hexview-content" class="hexviewerwindow">
+    ${content}
+    <form id="hexviewwindow_params">
+        <input type="hidden" name="highlights" value="" />
+        <input type="hidden" name="row_width" value="16" />
+        <input type="hidden" name="word_size" value="1" />
+        <input type="hidden" name="caption" value="" />
+    </form>
+</div>
+
+<script type="text/javascript">
+    $(document).ready(function () {
+    });
+</script>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/cc0b6fe2/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/js/hexview/LICENSE
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/js/hexview/LICENSE b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/js/hexview/LICENSE
new file mode 100644
index 0000000..95e1332
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/js/hexview/LICENSE
@@ -0,0 +1,32 @@
+
+HexViewJS License
+-----------------
+
+HexViewJS is written by Nick McVeity <nm...@gmail.com> and is 
+licensed under the terms of the MIT license reproduced below.
+
+========================================================================
+
+Copyright (c) 2010 Nick McVeity <nm...@gmail.com>
+
+Permission is hereby granted, free of charge, to any person 
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be 
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+========================================================================
+

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/cc0b6fe2/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/js/hexview/hexview.default.css
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/js/hexview/hexview.default.css b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/js/hexview/hexview.default.css
new file mode 100644
index 0000000..581161e
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/js/hexview/hexview.default.css
@@ -0,0 +1,10 @@
+.hexviewerwindow { font-family: monospace; background-color: #F2F2F2;}
+div.hexviewerwindow { padding: 20px; }
+.hexviewerwindow_table { border-collapse:collapse; border: 5px solid grey; margin-left: 16px; caption-side:bottom; }
+.hexviewerwindow_offset {background: #A9D0F5; padding-right: 8px; }
+.hexviewerwindow_visual {background: #A9F5F2; padding-left: 8px; }
+.hexviewerwindow_code {}
+.hexviewerwindow_code_hi {background: #F4FA58; }
+.hexviewerwindow_border_start {border-left: solid #E0E0E0 1px; }
+.hexviewerwindow_border_middle {border-bottom: solid #E0E0E0 1px; border-top: solid #E0E0E0 1px;}
+.hexviewerwindow_border_end {border-right: solid #E0E0E0 1px; border-top: solid #E0E0E0 1px; }

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/cc0b6fe2/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/js/hexview/hexview.js
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/js/hexview/hexview.js b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/js/hexview/hexview.js
new file mode 100644
index 0000000..c5b4401
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/js/hexview/hexview.js
@@ -0,0 +1,175 @@
+		var HEX = '0123456789ABCDEF'
+
+		function dec2_to_hex(dec)
+		{
+			if (dec < 0)
+				dec = 0
+			
+			if (dec > 255)
+				dec = 255
+			
+			return HEX.charAt(Math.floor(dec / 16)) + HEX.charAt(dec % 16)
+		}
+		
+		function dec_to_hex8(dec)
+		{
+			var str = ""
+			
+			for (var i = 3; i >= 0; i--)
+			{
+				str += dec2_to_hex((dec >> (i*8)) & 255)
+			}
+			
+			return str;
+		}
+
+		function remove_whitespace(str)
+		{
+			return str.replace(/\n/g, "")
+					  .replace(/\t/g, "")
+					  .replace(/ /g, "")
+					  .replace(/\r/g, "")
+		}
+		
+		var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
+		
+		function base64_decode(encoded)
+		{
+			var decoded = ""
+			
+			for (var i = 0; i < encoded.length; i += 4)
+			{
+				var ch0 = encoded.charAt(i+0)
+				var ch1 = encoded.charAt(i+1)
+				var ch2 = encoded.charAt(i+2)
+				var ch3 = encoded.charAt(i+3)
+				
+				var index0 = BASE64_CHARS.indexOf(ch0);
+				var index1 = BASE64_CHARS.indexOf(ch1);
+				var index2 = BASE64_CHARS.indexOf(ch2);
+				var index3 = BASE64_CHARS.indexOf(ch3);
+				
+				decoded += String.fromCharCode((index0 << 2) | (index1 >> 4))
+				decoded += String.fromCharCode(((index1 & 15) << 4) | (index2 >> 2))
+				decoded += String.fromCharCode(((index2 & 3) << 6) | index3)
+			}
+			
+			return decoded
+		}
+		
+		function markup_hexviewwindow(div, index)
+		{
+			var bin_data = base64_decode(remove_whitespace(div.text()))
+			var line_data
+			var title = div.attr("title")
+			
+			var highlights_str = $("form#hexviewwindow_params input[name='highlights']", div).attr("value").split(',')
+			var highlights = []
+			
+			for (var i = 0; i < highlights_str.length; i++)
+			{
+				highlights.push(highlights_str[i].split(":"))
+			}
+			 
+			var params = title.split(':')
+			var step = parseInt($("form#hexviewwindow_params input[name='row_width']", div).attr("value"))
+			var word_size = parseInt($("form#hexviewwindow_params input[name='word_size']", div).attr("value"))
+			var hide_0x = parseInt($("form#hexviewwindow_params input[name='hide_0x']", div).attr("value"))
+			var decimal_offset = parseInt($("form#hexviewwindow_params input[name='decimal_offset']", div).attr("value"))
+			var start_byte_1 = parseInt($("form#hexviewwindow_params input[name='start_byte_1']", div).attr("value"))
+			var caption = $("form#hexviewwindow_params input[name='caption']", div).attr("value")
+			
+			div.text("")
+			div.append("<table></table>")
+			
+			var offset = (start_byte_1 ? 1 : 0)
+
+			function apply_highlights(index)
+			{
+				for (var j = 0; j < highlights.length; j++)
+				{
+					if ((index >= highlights[j][0]) && (index <= highlights[j][1]))
+					{
+						if (index == highlights[j][0])
+						{
+							$("table tr td:last", div).addClass("hexviewerwindow_border_start")
+						}
+						
+						if (index == highlights[j][1])
+						{
+							$("table tr td:last", div).addClass("hexviewerwindow_border_end")
+						}
+						
+						$("table tr td:last", div).addClass("hexviewerwindow_code_hi hexviewerwindow_border_middle")
+						$("table tr td:last", div).attr("style", "background-color: " + highlights[j][2] + ";")
+						$("table tr td:last", div).attr("title", highlights[j][3])
+						
+						runlen += 1
+					}
+					else
+					{
+						$("table tr td:last", div).addClass("hexviewerwindow_code")
+					}
+				}
+			}
+
+			if (caption)
+				$("table", div).append("<caption>" + caption + "</caption>")
+				
+			while (bin_data.length > 0)
+			{
+				line_data = bin_data.slice(0, step)
+				bin_data = bin_data.slice(step)
+			
+				$("table", div).addClass("hexviewerwindow_table")
+				$("table", div).append("<tr></tr>").addClass("hexviewerwindow")
+				$("table tr:last", div).append("<td>" + (decimal_offset ? ("00000000"+offset).slice(-8) : "0x" + dec_to_hex8(offset)) + "</td>")
+				$("table tr td:last", div).addClass("hexviewerwindow_offset")
+				
+				var runlen = 0
+				
+				for (var i = 0; i < line_data.length; i += word_size)
+				{
+					var num = ""
+					
+					for (var j = 0; j < word_size; j++)
+					{
+						num += dec2_to_hex(line_data.charCodeAt(i+j))
+					}
+					
+					$("table tr:last", div).append("<td>" + (hide_0x ? "" : "0x") + num + "</td>")
+
+					apply_highlights(offset+i)
+				}
+				
+				var text = ""
+				
+				for (var i = 0; i < line_data.length; i++)
+				{
+					var cc = line_data.charCodeAt(i)
+					
+					if ((cc >= 32) && (cc <= 126))
+					{
+						text = text + line_data.charAt(i)
+					}
+					else
+					{
+						text = text + "."
+					}
+				}
+				
+				if (line_data.length < step)
+					$("table tr td:last", div).attr("colspan", Math.floor((step - line_data.length) / word_size) + 1)
+
+				offset += step
+				
+				$("table tr:last", div).append("<td>" + text + "</td>")
+				$("table tr td:last", div).addClass("hexviewerwindow_visual")
+			}
+		}
+		
+		$(document).ready(function () {
+			$("div.hexviewwindow").each(function (index) {
+				markup_hexviewwindow($(this), index)
+			})
+		})
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/cc0b6fe2/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/java/org/apache/nifi/web/StandardContentViewerController.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/java/org/apache/nifi/web/StandardContentViewerController.java b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/java/org/apache/nifi/web/StandardContentViewerController.java
index 3a361b4..36113ef 100644
--- a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/java/org/apache/nifi/web/StandardContentViewerController.java
+++ b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/java/org/apache/nifi/web/StandardContentViewerController.java
@@ -16,8 +16,8 @@
  */
 package org.apache.nifi.web;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.io.PrintWriter;
 import java.io.StringWriter;
 
 import javax.servlet.ServletException;
@@ -34,6 +34,7 @@ import javax.xml.transform.stream.StreamResult;
 import javax.xml.transform.stream.StreamSource;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.io.IOUtils;
+import org.apache.nifi.web.ViewableContent.DisplayMode;
 import org.codehaus.jackson.map.ObjectMapper;
 
 /**
@@ -57,43 +58,43 @@ public class StandardContentViewerController extends HttpServlet {
         if ("application/json".equals(content.getContentType()) || "application/xml".equals(content.getContentType())) {
             final String formatted;
             
-            if ("application/json".equals(content.getContentType())) {
-                final ObjectMapper mapper = new ObjectMapper();
-                final Object objectJson = mapper.readValue(content.getContent(), Object.class);
-                formatted = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(objectJson);
+            // leave the content alone if specified
+            if (DisplayMode.Original.equals(content.getDisplayMode())) {
+                formatted = content.getContent();
             } else {
-                final StringWriter writer = new StringWriter();
+                if ("application/json".equals(content.getContentType())) {
+                    final ObjectMapper mapper = new ObjectMapper();
+                    final Object objectJson = mapper.readValue(content.getContent(), Object.class);
+                    formatted = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(objectJson);
+                } else {
+                    final StringWriter writer = new StringWriter();
 
-                try {
-                    final StreamSource source = new StreamSource(content.getContentStream());
-                    final StreamResult result = new StreamResult(writer);
-                    
-                    final TransformerFactory transformFactory = TransformerFactory.newInstance();
-                    final Transformer transformer = transformFactory.newTransformer();
-                    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
-                    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+                    try {
+                        final StreamSource source = new StreamSource(content.getContentStream());
+                        final StreamResult result = new StreamResult(writer);
 
-                    transformer.transform(source, result);
-                } catch (final TransformerFactoryConfigurationError | TransformerException te) {
-                    throw new IOException("Unable to transform content as XML: " + te, te);
+                        final TransformerFactory transformFactory = TransformerFactory.newInstance();
+                        final Transformer transformer = transformFactory.newTransformer();
+                        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+                        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+
+                        transformer.transform(source, result);
+                    } catch (final TransformerFactoryConfigurationError | TransformerException te) {
+                        throw new IOException("Unable to transform content as XML: " + te, te);
+                    }
+
+                    // get the transformed xml
+                    formatted = writer.toString();
                 }
-                
-                // get the transformed xml
-                formatted = writer.toString();
             }
             
             // defer to the jsp
             request.setAttribute("mode", content.getContentType());
             request.setAttribute("content", formatted);
             request.getRequestDispatcher("/WEB-INF/jsp/codemirror.jsp").include(request, response);
-        } else if ("application/octet-stream".equals(content.getContentType())) {
-            // convert stream into the base 64 bytes
-            final byte[] bytes = IOUtils.toByteArray(content.getContentStream());
-            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 {
+            final PrintWriter out = response.getWriter();
+            out.println("Unexpected content type: " + content.getContentType());
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/cc0b6fe2/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/META-INF/nifi-content-viewer
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/META-INF/nifi-content-viewer b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/META-INF/nifi-content-viewer
index 8693ebb..29fed60 100644
--- a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/META-INF/nifi-content-viewer
+++ b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/META-INF/nifi-content-viewer
@@ -1,3 +1,2 @@
 application/xml
-application/json
-application/octet-stream
\ No newline at end of file
+application/json
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/cc0b6fe2/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/WEB-INF/jsp/hexview.jsp
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/WEB-INF/jsp/hexview.jsp b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/WEB-INF/jsp/hexview.jsp
deleted file mode 100644
index 04ec46f..0000000
--- a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/WEB-INF/jsp/hexview.jsp
+++ /dev/null
@@ -1,35 +0,0 @@
-<%--
- Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You 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.
---%>
-<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
-<script type="text/javascript" src="../nifi/js/jquery/jquery-2.1.1.min.js"></script>
-<link rel="stylesheet" href="${request.contextPath}/js/hexview/hexview.default.css" type="text/css" />
-<script type="text/javascript" src="${pageContext.request.contextPath}/js/hexview/hexview.js"></script>
-
-<div id="hexview-content" class="hexviewerwindow">
-    ${content}
-    <form id="hexviewwindow_params">
-        <input type="hidden" name="highlights" value="" />
-        <input type="hidden" name="row_width" value="16" />
-        <input type="hidden" name="word_size" value="1" />
-        <input type="hidden" name="caption" value="" />
-    </form>
-</div>
-
-<script type="text/javascript">
-    $(document).ready(function () {
-    });
-</script>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/cc0b6fe2/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/js/hexview/LICENSE
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/js/hexview/LICENSE b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/js/hexview/LICENSE
deleted file mode 100644
index 95e1332..0000000
--- a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/js/hexview/LICENSE
+++ /dev/null
@@ -1,32 +0,0 @@
-
-HexViewJS License
------------------
-
-HexViewJS is written by Nick McVeity <nm...@gmail.com> and is 
-licensed under the terms of the MIT license reproduced below.
-
-========================================================================
-
-Copyright (c) 2010 Nick McVeity <nm...@gmail.com>
-
-Permission is hereby granted, free of charge, to any person 
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of the Software,
-and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be 
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-========================================================================
-

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/cc0b6fe2/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/js/hexview/hexview.default.css
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/js/hexview/hexview.default.css b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/js/hexview/hexview.default.css
deleted file mode 100644
index 581161e..0000000
--- a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/js/hexview/hexview.default.css
+++ /dev/null
@@ -1,10 +0,0 @@
-.hexviewerwindow { font-family: monospace; background-color: #F2F2F2;}
-div.hexviewerwindow { padding: 20px; }
-.hexviewerwindow_table { border-collapse:collapse; border: 5px solid grey; margin-left: 16px; caption-side:bottom; }
-.hexviewerwindow_offset {background: #A9D0F5; padding-right: 8px; }
-.hexviewerwindow_visual {background: #A9F5F2; padding-left: 8px; }
-.hexviewerwindow_code {}
-.hexviewerwindow_code_hi {background: #F4FA58; }
-.hexviewerwindow_border_start {border-left: solid #E0E0E0 1px; }
-.hexviewerwindow_border_middle {border-bottom: solid #E0E0E0 1px; border-top: solid #E0E0E0 1px;}
-.hexviewerwindow_border_end {border-right: solid #E0E0E0 1px; border-top: solid #E0E0E0 1px; }

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/cc0b6fe2/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/js/hexview/hexview.js
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/js/hexview/hexview.js b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/js/hexview/hexview.js
deleted file mode 100644
index c5b4401..0000000
--- a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/webapp/js/hexview/hexview.js
+++ /dev/null
@@ -1,175 +0,0 @@
-		var HEX = '0123456789ABCDEF'
-
-		function dec2_to_hex(dec)
-		{
-			if (dec < 0)
-				dec = 0
-			
-			if (dec > 255)
-				dec = 255
-			
-			return HEX.charAt(Math.floor(dec / 16)) + HEX.charAt(dec % 16)
-		}
-		
-		function dec_to_hex8(dec)
-		{
-			var str = ""
-			
-			for (var i = 3; i >= 0; i--)
-			{
-				str += dec2_to_hex((dec >> (i*8)) & 255)
-			}
-			
-			return str;
-		}
-
-		function remove_whitespace(str)
-		{
-			return str.replace(/\n/g, "")
-					  .replace(/\t/g, "")
-					  .replace(/ /g, "")
-					  .replace(/\r/g, "")
-		}
-		
-		var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
-		
-		function base64_decode(encoded)
-		{
-			var decoded = ""
-			
-			for (var i = 0; i < encoded.length; i += 4)
-			{
-				var ch0 = encoded.charAt(i+0)
-				var ch1 = encoded.charAt(i+1)
-				var ch2 = encoded.charAt(i+2)
-				var ch3 = encoded.charAt(i+3)
-				
-				var index0 = BASE64_CHARS.indexOf(ch0);
-				var index1 = BASE64_CHARS.indexOf(ch1);
-				var index2 = BASE64_CHARS.indexOf(ch2);
-				var index3 = BASE64_CHARS.indexOf(ch3);
-				
-				decoded += String.fromCharCode((index0 << 2) | (index1 >> 4))
-				decoded += String.fromCharCode(((index1 & 15) << 4) | (index2 >> 2))
-				decoded += String.fromCharCode(((index2 & 3) << 6) | index3)
-			}
-			
-			return decoded
-		}
-		
-		function markup_hexviewwindow(div, index)
-		{
-			var bin_data = base64_decode(remove_whitespace(div.text()))
-			var line_data
-			var title = div.attr("title")
-			
-			var highlights_str = $("form#hexviewwindow_params input[name='highlights']", div).attr("value").split(',')
-			var highlights = []
-			
-			for (var i = 0; i < highlights_str.length; i++)
-			{
-				highlights.push(highlights_str[i].split(":"))
-			}
-			 
-			var params = title.split(':')
-			var step = parseInt($("form#hexviewwindow_params input[name='row_width']", div).attr("value"))
-			var word_size = parseInt($("form#hexviewwindow_params input[name='word_size']", div).attr("value"))
-			var hide_0x = parseInt($("form#hexviewwindow_params input[name='hide_0x']", div).attr("value"))
-			var decimal_offset = parseInt($("form#hexviewwindow_params input[name='decimal_offset']", div).attr("value"))
-			var start_byte_1 = parseInt($("form#hexviewwindow_params input[name='start_byte_1']", div).attr("value"))
-			var caption = $("form#hexviewwindow_params input[name='caption']", div).attr("value")
-			
-			div.text("")
-			div.append("<table></table>")
-			
-			var offset = (start_byte_1 ? 1 : 0)
-
-			function apply_highlights(index)
-			{
-				for (var j = 0; j < highlights.length; j++)
-				{
-					if ((index >= highlights[j][0]) && (index <= highlights[j][1]))
-					{
-						if (index == highlights[j][0])
-						{
-							$("table tr td:last", div).addClass("hexviewerwindow_border_start")
-						}
-						
-						if (index == highlights[j][1])
-						{
-							$("table tr td:last", div).addClass("hexviewerwindow_border_end")
-						}
-						
-						$("table tr td:last", div).addClass("hexviewerwindow_code_hi hexviewerwindow_border_middle")
-						$("table tr td:last", div).attr("style", "background-color: " + highlights[j][2] + ";")
-						$("table tr td:last", div).attr("title", highlights[j][3])
-						
-						runlen += 1
-					}
-					else
-					{
-						$("table tr td:last", div).addClass("hexviewerwindow_code")
-					}
-				}
-			}
-
-			if (caption)
-				$("table", div).append("<caption>" + caption + "</caption>")
-				
-			while (bin_data.length > 0)
-			{
-				line_data = bin_data.slice(0, step)
-				bin_data = bin_data.slice(step)
-			
-				$("table", div).addClass("hexviewerwindow_table")
-				$("table", div).append("<tr></tr>").addClass("hexviewerwindow")
-				$("table tr:last", div).append("<td>" + (decimal_offset ? ("00000000"+offset).slice(-8) : "0x" + dec_to_hex8(offset)) + "</td>")
-				$("table tr td:last", div).addClass("hexviewerwindow_offset")
-				
-				var runlen = 0
-				
-				for (var i = 0; i < line_data.length; i += word_size)
-				{
-					var num = ""
-					
-					for (var j = 0; j < word_size; j++)
-					{
-						num += dec2_to_hex(line_data.charCodeAt(i+j))
-					}
-					
-					$("table tr:last", div).append("<td>" + (hide_0x ? "" : "0x") + num + "</td>")
-
-					apply_highlights(offset+i)
-				}
-				
-				var text = ""
-				
-				for (var i = 0; i < line_data.length; i++)
-				{
-					var cc = line_data.charCodeAt(i)
-					
-					if ((cc >= 32) && (cc <= 126))
-					{
-						text = text + line_data.charAt(i)
-					}
-					else
-					{
-						text = text + "."
-					}
-				}
-				
-				if (line_data.length < step)
-					$("table tr td:last", div).attr("colspan", Math.floor((step - line_data.length) / word_size) + 1)
-
-				offset += step
-				
-				$("table tr:last", div).append("<td>" + text + "</td>")
-				$("table tr td:last", div).addClass("hexviewerwindow_visual")
-			}
-		}
-		
-		$(document).ready(function () {
-			$("div.hexviewwindow").each(function (index) {
-				markup_hexviewwindow($(this), index)
-			})
-		})
\ No newline at end of file