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/16 00:21:25 UTC

incubator-nifi git commit: NIFI-353: - Starting to integrate the data viewer controller into the Jetty Server. - Starting to set up the data viewer controller. - Starting to set up the standard data viewer.

Repository: incubator-nifi
Updated Branches:
  refs/heads/NIFI-353 [created] b50953d9d


NIFI-353:
- Starting to integrate the data viewer controller into the Jetty Server.
- Starting to set up the data viewer controller.
- Starting to set up the standard data viewer.

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

Branch: refs/heads/NIFI-353
Commit: b50953d9d22881bcdc34edf1a34557d975b6dcc7
Parents: b8ade5b
Author: Matt Gilman <ma...@gmail.com>
Authored: Sun Feb 15 18:20:17 2015 -0500
Committer: Matt Gilman <ma...@gmail.com>
Committed: Sun Feb 15 18:20:17 2015 -0500

----------------------------------------------------------------------
 .../nifi-framework/nifi-web/nifi-jetty/pom.xml  |   5 +
 .../org/apache/nifi/web/server/DataHandler.java |  55 ++++
 .../org/apache/nifi/web/server/JettyServer.java |  72 +++--
 .../nifi-web/nifi-web-data-viewer/.gitignore    |   1 +
 .../nifi-web/nifi-web-data-viewer/pom.xml       |  51 ++++
 .../web/data/viewer/DataViewerController.java   |  68 +++++
 .../src/main/resources/META-INF/NOTICE          |  19 ++
 .../src/main/webapp/WEB-INF/jsp/footer.jsp      |  19 ++
 .../src/main/webapp/WEB-INF/jsp/header.jsp      |  27 ++
 .../src/main/webapp/WEB-INF/web.xml             |  29 ++
 .../src/main/webapp/css/main.css                | 214 ++++++++++++++
 .../src/main/webapp/js/application.js           |  20 ++
 .../nifi-framework/nifi-web/pom.xml             |   7 +
 .../nifi-standard-data-viewer/pom.xml           |  51 ++++
 .../viewer/StandardDataViewerController.java    |  59 ++++
 .../src/main/resources/META-INF/NOTICE          |  19 ++
 .../src/main/webapp/META-INF/nifi-data-viewer   |   2 +
 .../src/main/webapp/WEB-INF/jsp/content.jsp     |  18 ++
 .../src/main/webapp/WEB-INF/web.xml             |  33 +++
 .../src/main/webapp/css/main.css                | 214 ++++++++++++++
 .../src/main/webapp/js/application.js           | 282 +++++++++++++++++++
 .../nifi-standard-nar/pom.xml                   |   5 +
 .../nifi-standard-bundle/pom.xml                |  12 +-
 23 files changed, 1259 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml
index f538576..6538c3b 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml
@@ -152,6 +152,11 @@
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-web-docs</artifactId>
             <type>war</type>
+        </dependency> 
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-web-data-viewer</artifactId>
+            <type>war</type>
         </dependency>   
         <dependency>
             <groupId>org.apache.nifi</groupId>

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/DataHandler.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/DataHandler.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/DataHandler.java
new file mode 100644
index 0000000..1e9e4e0
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/DataHandler.java
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+package org.apache.nifi.web.server;
+
+import java.io.IOException;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.webapp.WebAppContext;
+
+/**
+ *
+ */
+public class DataHandler extends HttpServlet {
+
+    private final WebAppContext dataApps;
+
+    public DataHandler(WebAppContext dataApps) {
+        this.dataApps = dataApps;
+    }
+    
+    @Override
+    protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
+        // detect file type and appropriate data app to forward to
+        
+        // header
+        final RequestDispatcher header = request.getRequestDispatcher("/WEB-INF/jsp/header.jsp");
+        header.include(request, response);
+        
+        // content
+        final RequestDispatcher content = dataApps.getServletContext().getRequestDispatcher("/WEB-INF/jsp/content.jsp");
+        content.include(request, response);
+        
+        // footer
+        final RequestDispatcher footer = request.getRequestDispatcher("/WEB-INF/jsp/footer.jsp");
+        footer.include(request, response);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
index 95052a7..5fc99ac 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
@@ -100,6 +100,7 @@ public class JettyServer implements NiFiServer {
     private WebAppContext webApiContext;
     private WebAppContext webDocsContext;
     private Collection<WebAppContext> customUiWebContexts;
+    private Collection<WebAppContext> dataViewerWebContexts;
     private final NiFiProperties props;
 
     /**
@@ -164,6 +165,7 @@ public class JettyServer implements NiFiServer {
         File webApiWar = null;
         File webErrorWar = null;
         File webDocsWar = null;
+        File webDataViewerWar = null;
         List<File> otherWars = new ArrayList<>();
         for (File war : warToNarWorkingDirectoryLookup.keySet()) {
             if (war.getName().toLowerCase().startsWith("nifi-web-api")) {
@@ -172,6 +174,8 @@ public class JettyServer implements NiFiServer {
                 webErrorWar = war;
             } else if (war.getName().toLowerCase().startsWith("nifi-web-docs")) {
                 webDocsWar = war;
+            } else if (war.getName().toLowerCase().startsWith("nifi-web-data-viewer")) {
+                webDataViewerWar = war;
             } else if (war.getName().toLowerCase().startsWith("nifi-web")) {
                 webUiWar = war;
             } else {
@@ -188,11 +192,14 @@ public class JettyServer implements NiFiServer {
             throw new RuntimeException("Unable to load nifi-web-docs WAR");
         } else if (webErrorWar == null) {
             throw new RuntimeException("Unable to load nifi-web-error WAR");
+        } else if (webDataViewerWar == null) {
+            throw new RuntimeException("Unable to load nifi-web-data-viewer WAR");
         }
 
         // handlers for each war and init params for the web api
         final HandlerCollection handlers = new HandlerCollection();
-        final Map<String, String> initParams = new HashMap<>();
+        final Map<String, String> customUiMappings = new HashMap<>();
+        final Map<String, String> mimeTypeMappings = new HashMap<>();
         final ClassLoader frameworkClassLoader = getClass().getClassLoader();
         final ClassLoader jettyClassLoader = frameworkClassLoader.getParent();
 
@@ -201,10 +208,11 @@ public class JettyServer implements NiFiServer {
             customUiWebContexts = new ArrayList<>();
             for (File war : otherWars) {
                 // see if this war is a custom processor ui
-                List<String> customUiProcessorTypes = getCustomUiProcessorTypes(war);
+                List<String> customUiProcessorTypes = getWarExtensions(war, "META-INF/nifi-processor");
+                List<String> dataViewerMimeTypes = getWarExtensions(war, "META-INF/nifi-data-viewer");
 
-                // only include wars that are for custom processor ui's
-                if (CollectionUtils.isNotEmpty(customUiProcessorTypes)) {
+                // only include wars that are for extensions
+                if (!customUiProcessorTypes.isEmpty() || !dataViewerMimeTypes.isEmpty()) {
                     String warName = StringUtils.substringBeforeLast(war.getName(), ".");
                     String warContextPath = String.format("/%s", warName);
 
@@ -216,19 +224,27 @@ public class JettyServer implements NiFiServer {
                         narClassLoaderForWar = jettyClassLoader;
                     }
 
-                    // create the custom ui web app context
-                    WebAppContext customUiContext = loadWar(war, warContextPath, narClassLoaderForWar);
+                    // create the extension web app context
+                    WebAppContext extensionUiContext = loadWar(war, warContextPath, narClassLoaderForWar);
 
-                    // hold on to a reference to all custom ui web app contexts
-                    customUiWebContexts.add(customUiContext);
+                    // also store it by type so we can populate the appropriate initialization parameters
+                    if (!customUiProcessorTypes.isEmpty()) {
+                        customUiWebContexts.add(extensionUiContext);
+                    } else {
+                        // record the mime type to web app mapping (need to handle type collision)
+                        dataViewerWebContexts.add(extensionUiContext);
+                    }
 
                     // include custom ui web context in the handlers
-                    handlers.addHandler(customUiContext);
+                    handlers.addHandler(extensionUiContext);
 
                     // add the initialization paramters
                     for (String customUiProcessorType : customUiProcessorTypes) {
                         // map the processor type to the custom ui path
-                        initParams.put(customUiProcessorType, warContextPath);
+                        customUiMappings.put(customUiProcessorType, warContextPath);
+                    }
+                    for (final String dataViewerMimeType : dataViewerMimeTypes) {
+                        mimeTypeMappings.put(dataViewerMimeType, warContextPath);
                     }
                 }
             }
@@ -239,10 +255,14 @@ public class JettyServer implements NiFiServer {
 
         // load the web api app
         webApiContext = loadWar(webApiWar, "/nifi-api", frameworkClassLoader);
-        Map<String, String> webApiInitParams = webApiContext.getInitParams();
-        webApiInitParams.putAll(initParams);
+        webApiContext.getInitParams().putAll(customUiMappings);
         handlers.addHandler(webApiContext);
 
+        // load the data viewer app
+        final WebAppContext webDataViewerContext = loadWar(webDataViewerWar, "/nifi-data-viewer", frameworkClassLoader);
+        webDataViewerContext.getInitParams().putAll(mimeTypeMappings);
+        handlers.addHandler(webDataViewerContext);
+        
         // create a web app for the docs
         final String docsContextPath = "/nifi-docs";
 
@@ -292,18 +312,18 @@ public class JettyServer implements NiFiServer {
     }
 
     /**
-     * Loads the processor types that the specified war file is a custom UI for.
+     * Returns the extension in the specified WAR using the specified path.
      *
-     * @param warFile
+     * @param war
      * @return
      */
-    private List<String> getCustomUiProcessorTypes(final File warFile) {
+    private List<String> getWarExtensions(final File war, final String path) {
         List<String> processorTypes = new ArrayList<>();
         JarFile jarFile = null;
         try {
             // load the jar file and attempt to find the nifi-processor entry
-            jarFile = new JarFile(warFile);
-            JarEntry jarEntry = jarFile.getJarEntry("META-INF/nifi-processor");
+            jarFile = new JarFile(war);
+            JarEntry jarEntry = jarFile.getJarEntry(path);
 
             // ensure the nifi-processor entry was found
             if (jarEntry != null) {
@@ -320,7 +340,7 @@ public class JettyServer implements NiFiServer {
                 }
             }
         } catch (IOException ioe) {
-            logger.warn(String.format("Unable to inspect %s for a custom processor UI.", warFile));
+            logger.warn(String.format("Unable to inspect %s for a custom processor UI.", war));
         } finally {
             try {
                 // close the jar file - which closes all input streams obtained via getInputStream above
@@ -540,12 +560,12 @@ public class JettyServer implements NiFiServer {
             if (webApiContext != null && CollectionUtils.isNotEmpty(customUiWebContexts)) {
                 final ServletContext webApiServletContext = webApiContext.getServletHandler().getServletContext();
                 final WebApplicationContext webApplicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(webApiServletContext);
-                final NiFiWebContext NiFiWebContext = webApplicationContext.getBean("nifiWebContext", NiFiWebContext.class);
+                final NiFiWebContext niFiWebContext = webApplicationContext.getBean("nifiWebContext", NiFiWebContext.class);
 
                 for (final WebAppContext customUiContext : customUiWebContexts) {
                     // set the NiFi context in each custom ui servlet context
                     final ServletContext customUiServletContext = customUiContext.getServletHandler().getServletContext();
-                    customUiServletContext.setAttribute("nifi-web-context", NiFiWebContext);
+                    customUiServletContext.setAttribute("nifi-web-context", niFiWebContext);
 
                     // add the security filter to any custom ui wars
                     final FilterHolder securityFilter = webApiContext.getServletHandler().getFilter("springSecurityFilterChain");
@@ -553,6 +573,16 @@ public class JettyServer implements NiFiServer {
                         customUiContext.addFilter(securityFilter, "/*", EnumSet.of(DispatcherType.REQUEST));
                     }
                 }
+                
+                for (final WebAppContext dataViewerContext : dataViewerWebContexts) {
+                    
+                    
+                    // add the security filter to any custom ui wars
+                    final FilterHolder securityFilter = webApiContext.getServletHandler().getFilter("springSecurityFilterChain");
+                    if (securityFilter != null) {
+                        dataViewerContext.addFilter(securityFilter, "/*", EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE));
+                    }
+                }
             }
 
             // ensure the web document war was loaded and provide the extension mapping
@@ -560,7 +590,7 @@ public class JettyServer implements NiFiServer {
                 final ServletContext webDocsServletContext = webDocsContext.getServletHandler().getServletContext();
                 webDocsServletContext.setAttribute("nifi-extension-mapping", extensionMapping);
             }
-
+            
             // if this nifi is a node in a cluster, start the flow service and load the flow - the 
             // flow service is loaded here for clustered nodes because the loading of the flow will 
             // initialize the connection between the node and the NCM. if the node connects (starts 

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/.gitignore
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/.gitignore b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/.gitignore
new file mode 100755
index 0000000..ea8c4bf
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/.gitignore
@@ -0,0 +1 @@
+/target

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/pom.xml
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/pom.xml b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/pom.xml
new file mode 100644
index 0000000..0ff1696
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/pom.xml
@@ -0,0 +1,51 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <!--
+      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.
+    -->
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.nifi</groupId>
+        <artifactId>nifi-web</artifactId>
+        <version>0.0.2-incubating-SNAPSHOT</version>
+    </parent>
+    <groupId>org.apache.nifi</groupId>
+    <artifactId>nifi-web-data-viewer</artifactId>
+    <packaging>war</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet.jsp</groupId>
+            <artifactId>javax.servlet.jsp-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.el</groupId>
+            <artifactId>javax.el-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet.jsp.jstl</groupId>
+            <artifactId>javax.servlet.jsp.jstl-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/java/org/apache/nifi/web/data/viewer/DataViewerController.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/java/org/apache/nifi/web/data/viewer/DataViewerController.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/java/org/apache/nifi/web/data/viewer/DataViewerController.java
new file mode 100644
index 0000000..734568d
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/java/org/apache/nifi/web/data/viewer/DataViewerController.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+package org.apache.nifi.web.data.viewer;
+
+import java.io.IOException;
+import java.util.Map;
+import javax.servlet.RequestDispatcher;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ *
+ */
+@WebServlet(name = "DataViewerController", urlPatterns = {"/*"})
+public class DataViewerController extends HttpServlet {
+
+    // context for accessing the extension mapping
+    private ServletContext servletContext;
+
+    @Override
+    public void init(final ServletConfig config) throws ServletException {
+        super.init(config);
+        servletContext = config.getServletContext();
+    }
+
+    /**
+     *
+     * @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(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+        // header
+        final RequestDispatcher header = request.getRequestDispatcher("/WEB-INF/jsp/header.jsp");
+        header.include(request, response);
+        
+        // content
+        final RequestDispatcher content = servletContext.getContext(getServletConfig().getInitParameter("application/xml")).getRequestDispatcher("/WEB-INF/jsp/content.jsp");
+        content.include(request, response);
+        
+        // footer
+        final RequestDispatcher footer = request.getRequestDispatcher("/WEB-INF/jsp/footer.jsp");
+        footer.include(request, response);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/resources/META-INF/NOTICE
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/resources/META-INF/NOTICE b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..d91a952
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,19 @@
+nifi-web-docs
+Copyright 2014-2015 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+===========================================
+Apache Software License v2
+===========================================
+
+The following binary components are provided under the Apache Software License v2
+
+  (ASLv2) Apache Commons Lang
+    The following NOTICE information applies:
+      Apache Commons Lang
+      Copyright 2001-2014 The Apache Software Foundation
+
+      This product includes software from the Spring Framework,
+      under the Apache License 2.0 (see: StringUtils.containsWhitespace())

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/WEB-INF/jsp/footer.jsp
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/WEB-INF/jsp/footer.jsp b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/WEB-INF/jsp/footer.jsp
new file mode 100644
index 0000000..195c9e8
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/WEB-INF/jsp/footer.jsp
@@ -0,0 +1,19 @@
+<%--
+ 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" %>
+    </body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-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-data-viewer/src/main/webapp/WEB-INF/jsp/header.jsp b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/WEB-INF/jsp/header.jsp
new file mode 100644
index 0000000..9079e71
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/WEB-INF/jsp/header.jsp
@@ -0,0 +1,27 @@
+<%--
+ 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" %>
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>NiFi</title>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+        <link rel="shortcut icon" href="../nifi/images/nifi16.ico"/>
+        <link href="../../css/component-usage.css" rel="stylesheet" type="text/css" />
+    </head>
+    <body>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/WEB-INF/web.xml b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..64a9a48
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
+    <display-name>nifi-data-viewer</display-name>
+    <servlet>
+        <servlet-name>DataViewerController</servlet-name>
+        <servlet-class>org.apache.nifi.web.data.viewer.DataViewerController</servlet-class>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>DataViewerController</servlet-name>
+        <url-pattern>/data-viewer</url-pattern>
+    </servlet-mapping>
+    <welcome-file-list>
+        <welcome-file>data-viewer</welcome-file>
+    </welcome-file-list>
+</web-app>

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/css/main.css
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/css/main.css b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/css/main.css
new file mode 100644
index 0000000..918eb7a
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/css/main.css
@@ -0,0 +1,214 @@
+/*
+ * 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.
+ */
+* {
+    margin: 0;
+    padding: 0;
+}
+
+#documentation-body {
+    width: 100%;
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+}
+
+/* banners */
+
+div.main-banner-header {
+    display: none;
+    z-index: 100;
+    font-weight: bold;
+    font-size: 1em;
+    text-align: center;
+    line-height: 15px;
+    color: #7e7e7e;
+    margin: 0px auto;
+    width: 900px;
+    height: 17px;
+    background-color: #fff;
+    z-index: 100;
+    background-image: url(../images/bgHeader.png);
+}
+
+div.main-banner-footer {
+    display: none;
+    position: absolute;
+    left: 0px;
+    right: 0px;
+    bottom: 0px;
+    height: 15px;
+    color: #fff;
+    text-align: center;
+    font-weight: bold;
+    font-size: 1em;
+    line-height: 15px;
+    overflow: visible;
+    background-color: #9eb9c7;
+    background-image: url(../images/bgBannerFoot.png);
+    background-repeat: repeat-x;
+    background-position: left top;
+}
+
+/* documentation */
+
+div.documentation-header {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    height: 45px;
+    border-bottom: 1px solid #d1dee5;
+    color: #365c6a;
+    font-size: 13px;
+}
+
+#nf-title {
+    float: left;
+    height: 50px;
+    padding: 5px;
+    font-size: 20px;
+    margin-top: 10px;
+}
+
+#nf-version {
+    float: left;
+    font-size: 14px;
+    margin-left: 10px;
+    margin-top: 21px;
+    font-style: italic;
+    color: #aaa;
+}
+
+#selected-component {
+    float: right;
+    height: 50px;
+    padding: 5px;
+    margin-top: 10px;
+    font-size: 20px;
+}
+
+/* component listing */
+
+div.component-listing {
+    width: 300px;
+    position: absolute;
+    top: 46px;
+    left: 0;
+    bottom: 40px;
+    overflow: auto;
+    font-size: 16px;
+    padding: 4px;
+}
+
+div.component-listing div.section {
+    margin-bottom: 15px;
+}
+
+div.component-listing div.header {
+    font-weight: bold;
+    color: #264c58;
+}
+
+div.component-links ul {
+    list-style: none;
+}
+
+li.component-item {
+    padding: 2px;
+    padding-left: 4px;
+    border-left: 8px solid transparent;
+    font-family: "Open Sans","DejaVu Sans",sans-serif;
+    font-size: 15px;
+}
+
+li.component-item a {
+    color: #1e373f;
+}
+
+li.component-item:hover {
+    border-left: 8px solid #d1dee5;
+}
+
+li.component-item:hover a {
+    color: #264c58;
+}
+
+li.component-item.selected {
+    border-left: 8px solid #7098ad;
+}
+
+div.component-links span.no-components {
+    font-style: italic;
+    color: #777;
+}
+
+/* component filter control */
+
+#component-filter-controls {
+    width: 308px;
+    height: 40px;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+}
+
+#component-filter-container {
+    height: 24px;
+    margin-left: 2px;
+    margin-top: 1px;
+}
+
+#component-filter {
+    padding: 1px;
+    font-size: 12px;
+    height: 18px;
+    line-height: 20px;
+    width: 299px;
+    float: left;
+}
+
+input.component-filter-list {
+    color: #888;
+    font-style: italic;
+}
+
+#component-filter-stats {
+    font-size: 9px;
+    font-weight: bold;
+    color: #9f6000;
+    clear: left; 
+    line-height: normal;
+    margin-left: 7px;
+    margin-top: 2px;
+}
+
+/* component usage */
+
+#component-usage-container {
+    position: absolute;
+    top: 46px;
+    right: 0px;
+    bottom: 0px;
+    left: 312px;
+    overflow: hidden;
+}
+
+#component-usage {
+    overflow: auto;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/js/application.js
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/js/application.js b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/js/application.js
new file mode 100644
index 0000000..cea8078
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-data-viewer/src/main/webapp/js/application.js
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+$(document).ready(function () {
+
+    
+});

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/pom.xml
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/pom.xml b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/pom.xml
index b776086..5e0a2bb 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/pom.xml
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/pom.xml
@@ -29,6 +29,7 @@
         <module>nifi-web-api</module>
         <module>nifi-web-error</module>
         <module>nifi-web-docs</module>
+        <module>nifi-web-data-viewer</module>
         <module>nifi-web-ui</module>
         <module>nifi-jetty</module>
     </modules>
@@ -54,6 +55,12 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
+                <artifactId>nifi-web-data-viewer</artifactId>
+                <type>war</type>
+                <version>0.0.2-incubating-SNAPSHOT</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-web-ui</artifactId>
                 <type>war</type>
                 <version>0.0.2-incubating-SNAPSHOT</version>

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/pom.xml
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/pom.xml b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/pom.xml
new file mode 100644
index 0000000..839ce43
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/pom.xml
@@ -0,0 +1,51 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <!--
+      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.
+    -->
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.nifi</groupId>
+        <artifactId>nifi-standard-bundle</artifactId>
+        <version>0.0.2-incubating-SNAPSHOT</version>
+    </parent>
+    <groupId>org.apache.nifi</groupId>
+    <artifactId>nifi-standard-data-viewer</artifactId>
+    <packaging>war</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet.jsp</groupId>
+            <artifactId>javax.servlet.jsp-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.el</groupId>
+            <artifactId>javax.el-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet.jsp.jstl</groupId>
+            <artifactId>javax.servlet.jsp.jstl-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/java/org/apache/nifi/standard/data/viewer/StandardDataViewerController.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/java/org/apache/nifi/standard/data/viewer/StandardDataViewerController.java b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/java/org/apache/nifi/standard/data/viewer/StandardDataViewerController.java
new file mode 100644
index 0000000..410270d
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/java/org/apache/nifi/standard/data/viewer/StandardDataViewerController.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+package org.apache.nifi.standard.data.viewer;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ *
+ */
+@WebServlet(name = "StandardDataViewer", urlPatterns = {"/content"})
+public class StandardDataViewerController extends HttpServlet {
+
+    // context for accessing the extension mapping
+    private ServletContext servletContext;
+
+    @Override
+    public void init(final ServletConfig config) throws ServletException {
+        super.init(config);
+        servletContext = config.getServletContext();
+    }
+
+    /**
+     *
+     * @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(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+//        final ExtensionMapping extensionMappings = (ExtensionMapping) servletContext.getAttribute("nifi-extension-mapping");
+
+        // forward appropriately
+        request.getRequestDispatcher("/WEB-INF/jsp/content.jsp").forward(request, response);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/resources/META-INF/NOTICE
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/resources/META-INF/NOTICE b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..d91a952
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,19 @@
+nifi-web-docs
+Copyright 2014-2015 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+===========================================
+Apache Software License v2
+===========================================
+
+The following binary components are provided under the Apache Software License v2
+
+  (ASLv2) Apache Commons Lang
+    The following NOTICE information applies:
+      Apache Commons Lang
+      Copyright 2001-2014 The Apache Software Foundation
+
+      This product includes software from the Spring Framework,
+      under the Apache License 2.0 (see: StringUtils.containsWhitespace())

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/META-INF/nifi-data-viewer
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/META-INF/nifi-data-viewer b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/META-INF/nifi-data-viewer
new file mode 100644
index 0000000..29fed60
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/META-INF/nifi-data-viewer
@@ -0,0 +1,2 @@
+application/xml
+application/json
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/WEB-INF/jsp/content.jsp
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/WEB-INF/jsp/content.jsp b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/WEB-INF/jsp/content.jsp
new file mode 100644
index 0000000..adabebd
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/WEB-INF/jsp/content.jsp
@@ -0,0 +1,18 @@
+<%--
+ 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" %>
+<p>This is the content rendered...</p>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/WEB-INF/web.xml b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..7eb4ee2
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
+    <display-name>nifi-docs</display-name>
+    <error-page>
+        <error-code>404</error-code>
+        <location>/WEB-INF/jsp/no-documentation-found.jsp</location>
+    </error-page>
+    <servlet>
+        <servlet-name>documentation-controller</servlet-name>
+        <servlet-class>org.apache.nifi.standard.data.viewer.StandardDataViewerController</servlet-class>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>documentation-controller</servlet-name>
+        <url-pattern>/documentation</url-pattern>
+    </servlet-mapping>
+    <welcome-file-list>
+        <welcome-file>documentation</welcome-file>
+    </welcome-file-list>
+</web-app>

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/css/main.css
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/css/main.css b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/css/main.css
new file mode 100644
index 0000000..918eb7a
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/css/main.css
@@ -0,0 +1,214 @@
+/*
+ * 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.
+ */
+* {
+    margin: 0;
+    padding: 0;
+}
+
+#documentation-body {
+    width: 100%;
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+}
+
+/* banners */
+
+div.main-banner-header {
+    display: none;
+    z-index: 100;
+    font-weight: bold;
+    font-size: 1em;
+    text-align: center;
+    line-height: 15px;
+    color: #7e7e7e;
+    margin: 0px auto;
+    width: 900px;
+    height: 17px;
+    background-color: #fff;
+    z-index: 100;
+    background-image: url(../images/bgHeader.png);
+}
+
+div.main-banner-footer {
+    display: none;
+    position: absolute;
+    left: 0px;
+    right: 0px;
+    bottom: 0px;
+    height: 15px;
+    color: #fff;
+    text-align: center;
+    font-weight: bold;
+    font-size: 1em;
+    line-height: 15px;
+    overflow: visible;
+    background-color: #9eb9c7;
+    background-image: url(../images/bgBannerFoot.png);
+    background-repeat: repeat-x;
+    background-position: left top;
+}
+
+/* documentation */
+
+div.documentation-header {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    height: 45px;
+    border-bottom: 1px solid #d1dee5;
+    color: #365c6a;
+    font-size: 13px;
+}
+
+#nf-title {
+    float: left;
+    height: 50px;
+    padding: 5px;
+    font-size: 20px;
+    margin-top: 10px;
+}
+
+#nf-version {
+    float: left;
+    font-size: 14px;
+    margin-left: 10px;
+    margin-top: 21px;
+    font-style: italic;
+    color: #aaa;
+}
+
+#selected-component {
+    float: right;
+    height: 50px;
+    padding: 5px;
+    margin-top: 10px;
+    font-size: 20px;
+}
+
+/* component listing */
+
+div.component-listing {
+    width: 300px;
+    position: absolute;
+    top: 46px;
+    left: 0;
+    bottom: 40px;
+    overflow: auto;
+    font-size: 16px;
+    padding: 4px;
+}
+
+div.component-listing div.section {
+    margin-bottom: 15px;
+}
+
+div.component-listing div.header {
+    font-weight: bold;
+    color: #264c58;
+}
+
+div.component-links ul {
+    list-style: none;
+}
+
+li.component-item {
+    padding: 2px;
+    padding-left: 4px;
+    border-left: 8px solid transparent;
+    font-family: "Open Sans","DejaVu Sans",sans-serif;
+    font-size: 15px;
+}
+
+li.component-item a {
+    color: #1e373f;
+}
+
+li.component-item:hover {
+    border-left: 8px solid #d1dee5;
+}
+
+li.component-item:hover a {
+    color: #264c58;
+}
+
+li.component-item.selected {
+    border-left: 8px solid #7098ad;
+}
+
+div.component-links span.no-components {
+    font-style: italic;
+    color: #777;
+}
+
+/* component filter control */
+
+#component-filter-controls {
+    width: 308px;
+    height: 40px;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+}
+
+#component-filter-container {
+    height: 24px;
+    margin-left: 2px;
+    margin-top: 1px;
+}
+
+#component-filter {
+    padding: 1px;
+    font-size: 12px;
+    height: 18px;
+    line-height: 20px;
+    width: 299px;
+    float: left;
+}
+
+input.component-filter-list {
+    color: #888;
+    font-style: italic;
+}
+
+#component-filter-stats {
+    font-size: 9px;
+    font-weight: bold;
+    color: #9f6000;
+    clear: left; 
+    line-height: normal;
+    margin-left: 7px;
+    margin-top: 2px;
+}
+
+/* component usage */
+
+#component-usage-container {
+    position: absolute;
+    top: 46px;
+    right: 0px;
+    bottom: 0px;
+    left: 312px;
+    overflow: hidden;
+}
+
+#component-usage {
+    overflow: auto;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/js/application.js
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/js/application.js b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/js/application.js
new file mode 100644
index 0000000..3efdbcc
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-data-viewer/src/main/webapp/js/application.js
@@ -0,0 +1,282 @@
+/*
+ * 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.
+ */
+$(document).ready(function () {
+
+    var isUndefined = function (obj) {
+        return typeof obj === 'undefined';
+    };
+
+    var isNull = function (obj) {
+        return obj === null;
+    };
+
+    var isDefinedAndNotNull = function (obj) {
+        return !isUndefined(obj) && !isNull(obj);
+    };
+
+    /**
+     * Get the filter text.
+     * 
+     * @returns {unresolved}
+     */
+    var getFilterText = function () {
+        var filter = '';
+        var ruleFilter = $('#component-filter');
+        if (!ruleFilter.hasClass('component-filter-list')) {
+            filter = ruleFilter.val();
+        }
+        return filter;
+    };
+
+    var applyComponentFilter = function (componentContainer) {
+        var matchingComponents = 0;
+        var componentLinks = $(componentContainer).find('a.component-link');
+
+        if (componentLinks.length === 0) {
+            return matchingComponents;
+        }
+
+        // get the filter text
+        var filter = getFilterText();
+        if (filter !== '') {
+            var filterExp = new RegExp(filter, 'i');
+
+            // update the displayed rule count
+            $.each(componentLinks, function (_, componentLink) {
+                var a = $(componentLink);
+                var li = a.closest('li.component-item');
+
+                // get the rule text for matching
+                var componentName = a.text();
+
+                // see if any of the text from this rule matches
+                var componentMatches = componentName.search(filterExp) >= 0;
+
+                // handle whether the rule matches
+                if (componentMatches === true) {
+                    li.show();
+                    matchingComponents++;
+                } else {
+                    // hide the rule
+                    li.hide();
+                }
+            });
+        } else {
+            // ensure every rule is visible
+            componentLinks.closest('li.component-item').show();
+
+            // set the number of displayed rules
+            matchingComponents = componentLinks.length;
+        }
+
+        // show whether there are status if appropriate
+        var noMatching = componentContainer.find('span.no-matching');
+        if (matchingComponents === 0) {
+            noMatching.show();
+        } else {
+            noMatching.hide();
+        }
+
+        return matchingComponents;
+    };
+
+    var applyFilter = function () {
+        var matchingGeneral = applyComponentFilter($('#general-links'));
+        var matchingProcessors = applyComponentFilter($('#processor-links'));
+        var matchingControllerServices = applyComponentFilter($('#controller-service-links'));
+        var matchingReportingTasks = applyComponentFilter($('#reporting-task-links'));
+        var matchingDeveloper = applyComponentFilter($('#developer-links'));
+
+        // update the rule count
+        $('#displayed-components').text(matchingGeneral + matchingProcessors + matchingControllerServices + matchingReportingTasks + matchingDeveloper);
+    };
+
+    var selectComponent = function (componentName) {
+        var componentLinks = $('a.component-link');
+
+        // consider each link
+        $.each(componentLinks, function () {
+            var componentLink = $(this);
+            if (componentName === componentLink.text()) {
+                // remove all selected styles
+                $('li.component-item').removeClass('selected');
+
+                // select this links item
+                componentLink.closest('li.component-item').addClass('selected');
+
+                // set the header
+                $('#selected-component').text(componentLink.text());
+
+                // stop iteration
+                return false;
+            }
+        });
+    };
+
+    // get the banners if we're not in the shell
+    var banners = $.Deferred(function (deferred) {
+        if (top === window) {
+            $.ajax({
+                type: 'GET',
+                url: '../nifi-api/controller/banners',
+                dataType: 'json'
+            }).then(function (response) {
+                // ensure the banners response is specified
+                if (isDefinedAndNotNull(response.banners)) {
+                    if (isDefinedAndNotNull(response.banners.headerText) && response.banners.headerText !== '') {
+                        // update the header text
+                        var bannerHeader = $('#banner-header').html(response.banners.headerText).show();
+
+                        // show the banner
+                        var updateTop = function (elementId) {
+                            var element = $('#' + elementId);
+                            element.css('top', (parseInt(bannerHeader.css('height')) + parseInt(element.css('top'))) + 'px');
+                        };
+
+                        // update the position of elements affected by top banners
+                        updateTop('documentation-header');
+                        updateTop('component-listing');
+                        updateTop('component-usage-container');
+                    }
+
+                    if (isDefinedAndNotNull(response.banners.footerText) && response.banners.footerText !== '') {
+                        // update the footer text and show it
+                        var bannerFooter = $('#banner-footer').html(response.banners.footerText).show();
+
+                        var updateBottom = function (elementId) {
+                            var element = $('#' + elementId);
+                            element.css('bottom', parseInt(bannerFooter.css('height')) + parseInt(element.css('bottom')) + 'px');
+                        };
+
+                        // update the position of elements affected by bottom banners
+                        updateBottom('component-filter-controls');
+                        updateBottom('component-listing');
+                        updateBottom('component-usage-container');
+                    }
+                }
+
+                deferred.resolve();
+            }, function () {
+                deferred.reject();
+            });
+        } else {
+            deferred.resolve();
+        }
+    }).promise();
+
+    // get the about details
+    var about = $.ajax({
+        type: 'GET',
+        url: '../nifi-api/controller/about',
+        dataType: 'json'
+    }).done(function (response) {
+        var aboutDetails = response.about;
+
+        // set the document title and the about title
+        $('#nf-version').text(aboutDetails.version);
+    });
+
+    // once the banners have loaded, function with remainder of the page
+    $.when(banners, about).always(function () {
+        // define the function for filtering the list
+        $('#component-filter').keyup(function () {
+            applyFilter();
+        }).focus(function () {
+            if ($(this).hasClass('component-filter-list')) {
+                $(this).removeClass('component-filter-list').val('');
+            }
+        }).blur(function () {
+            if ($(this).val() === '') {
+                $(this).addClass('component-filter-list').val('Filter');
+            }
+        }).addClass('component-filter-list').val('Filter');
+
+        // get the component usage container to install the window listener
+        var componentUsageContainer = $('#component-usage-container');
+
+        // size the iframe accordingly
+        var componentUsage = $('#component-usage').css({
+            width: componentUsageContainer.width(),
+            height: componentUsageContainer.height()
+        });
+
+        // add a window resize listener
+        $(window).resize(function () {
+            componentUsage.css({
+                width: componentUsageContainer.width(),
+                height: componentUsageContainer.height()
+            });
+        });
+
+        // listen for loading of the iframe to update the title
+        $('#component-usage').on('load', function () {
+            var componentName = '';
+            var href = $(this).contents().get(0).location.href;
+
+            // see if the href ends in index.htm[l]
+            var indexOfIndexHtml = href.indexOf('index.htm');
+            if (indexOfIndexHtml >= 0) {
+                href = href.substring(0, indexOfIndexHtml);
+            }
+
+            // remove the trailing separator
+            if (href.length > 0) {
+                var indexOfSeparator = href.lastIndexOf('/');
+                if (indexOfSeparator === href.length - 1) {
+                    href = href.substring(0, indexOfSeparator);
+                }
+            }
+
+            // extract the simple name
+            if (href.length > 0) {
+                var indexOfLastDot = href.lastIndexOf('.');
+                if (indexOfLastDot >= 0) {
+                    var indexAfterStrToFind = indexOfLastDot + 1;
+                    if (indexAfterStrToFind < href.length) {
+                        componentName = href.substr(indexAfterStrToFind);
+                    }
+                }
+            }
+
+            // if we could figure out the name
+            if (componentName !== '') {
+                selectComponent(componentName);
+            }
+        });
+        
+        // listen for on the rest api and user guide and developer guide and admin guide and overview
+        $('a.rest-api, a.user-guide, a.developer-guide, a.admin-guide, a.overview, a.expression-language-guide').on('click', function() {
+            selectComponent($(this).text());
+        });
+
+        // get the initial selection
+        var initialComponentLink = $('a.component-link:first');
+        var initialSelection = $('#initial-selection').text();
+        if (initialSelection !== '') {
+            $('a.component-link').each(function () {
+                var componentLink = $(this);
+                if (componentLink.text() === initialSelection) {
+                    initialComponentLink = componentLink;
+                    return false;
+                }
+            });
+        }
+
+        // click the first link
+        initialComponentLink[0].click();
+    });
+});

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-nar/pom.xml
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-nar/pom.xml b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-nar/pom.xml
index 64ad45e..23e481b 100644
--- a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-nar/pom.xml
+++ b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-nar/pom.xml
@@ -41,5 +41,10 @@
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-standard-reporting-tasks</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-standard-data-viewer</artifactId>
+            <type>war</type>
+        </dependency>
     </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/b50953d9/nifi/nifi-nar-bundles/nifi-standard-bundle/pom.xml
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-standard-bundle/pom.xml b/nifi/nifi-nar-bundles/nifi-standard-bundle/pom.xml
index 14d076c..fafd81e 100644
--- a/nifi/nifi-nar-bundles/nifi-standard-bundle/pom.xml
+++ b/nifi/nifi-nar-bundles/nifi-standard-bundle/pom.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
     <!--
       Licensed to the Apache Software Foundation (ASF) under one or more
@@ -27,8 +28,9 @@
         <module>nifi-standard-processors</module>
         <module>nifi-standard-prioritizers</module>
         <module>nifi-standard-reporting-tasks</module>
+        <module>nifi-standard-data-viewer</module>
         <module>nifi-standard-nar</module>
-    </modules>
+  </modules>
     <dependencyManagement>
         <dependencies>
             <dependency>
@@ -46,8 +48,14 @@
                 <artifactId>nifi-standard-reporting-tasks</artifactId>
                 <version>0.0.2-incubating-SNAPSHOT</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.nifi</groupId>
+                <artifactId>nifi-standard-data-viewer</artifactId>
+                <type>war</type>
+                <version>0.0.2-incubating-SNAPSHOT</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
 
-</project>
+</project>
\ No newline at end of file