blob: 6a595b2c57f3dc6a2a1cee957a72e2684aab83e1 [file] [log] [blame]
/*
* 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.felix.inventory.impl;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.felix.inventory.Format;
import org.apache.felix.inventory.impl.helper.ConfigurationWriter;
import org.apache.felix.inventory.impl.helper.HtmlConfigurationWriter;
import org.apache.felix.inventory.impl.helper.JSONConfigurationWriter;
import org.apache.felix.inventory.impl.helper.PlainTextConfigurationWriter;
import org.apache.felix.inventory.impl.helper.ZipConfigurationWriter;
/**
* The web console plugin for a inventory printer.
*/
public abstract class AbstractWebConsolePlugin extends HttpServlet
{
private static final long serialVersionUID = 1L;
/** The inventory printer manager. */
protected final InventoryPrinterManagerImpl inventoryPrinterManager;
/**
* Constructor
*
* @param inventoryPrinterManager The manager
*/
AbstractWebConsolePlugin(final InventoryPrinterManagerImpl inventoryPrinterManager)
{
this.inventoryPrinterManager = inventoryPrinterManager;
}
protected abstract InventoryPrinterHandler getInventoryPrinterHandler();
private void printConfigurationInventory(final ConfigurationWriter pw, final Format format,
final InventoryPrinterHandler handler) throws IOException
{
if (handler == null)
{
final InventoryPrinterHandler[] adapters = this.inventoryPrinterManager.getHandlers(format);
for (int i = 0; i < adapters.length; i++)
{
pw.printInventory(format, adapters[i]);
}
}
else
{
if (format == null || handler.supports(format))
{
pw.printInventory(format, handler);
}
}
}
/**
* Sets response headers to force the client to not cache the response
* sent back. This method must be called before the response is committed
* otherwise it will have no effect.
* <p>
* This method sets the <code>Cache-Control</code>, <code>Expires</code>,
* and <code>Pragma</code> headers.
*
* @param response The response for which to set the cache prevention
*/
private final void setNoCache(final HttpServletResponse response)
{
response.setHeader("Cache-Control", "no-cache"); //$NON-NLS-1$ //$NON-NLS-2$
response.addHeader("Cache-Control", "no-store"); //$NON-NLS-1$ //$NON-NLS-2$
response.addHeader("Cache-Control", "must-revalidate"); //$NON-NLS-1$ //$NON-NLS-2$
response.addHeader("Cache-Control", "max-age=0"); //$NON-NLS-1$ //$NON-NLS-2$
response.setHeader("Expires", "Thu, 01 Jan 1970 01:00:00 GMT"); //$NON-NLS-1$ //$NON-NLS-2$
response.setHeader("Pragma", "no-cache"); //$NON-NLS-1$ //$NON-NLS-2$
}
protected InventoryPrinterHandler getInventoryPrinterHandler(final String label)
{
return null; // all by default
}
protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException
{
this.setNoCache(response);
// full request?
final InventoryPrinterHandler handler;
final String pathInfo = request.getPathInfo();
final int lastSlash = pathInfo.lastIndexOf('/');
if (lastSlash > 0)
{
final int lastDot = pathInfo.lastIndexOf('.');
final String label = (lastDot < lastSlash ? pathInfo.substring(lastSlash + 1) : pathInfo.substring(lastSlash + 1, lastDot));
handler = this.getInventoryPrinterHandler(label); // usually all;
}
else
{
handler = this.getInventoryPrinterHandler();
if (handler == null)
{
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
}
if (request.getPathInfo().endsWith(".txt")) { //$NON-NLS-2$
response.setContentType("text/plain; charset=utf-8"); //$NON-NLS-2$
final ConfigurationWriter pw = new PlainTextConfigurationWriter(response.getWriter());
printConfigurationInventory(pw, Format.TEXT, handler);
pw.flush();
}
else if (request.getPathInfo().endsWith(".zip")) { //$NON-NLS-2$
String type = getServletContext().getMimeType(request.getPathInfo());
if (type == null)
{
type = "application/x-zip"; //$NON-NLS-2$
}
response.setContentType(type);
final ZipConfigurationWriter pw = ZipConfigurationWriter.create(response.getOutputStream());
printConfigurationInventory(pw, null, handler);
pw.finish();
}
else if (request.getPathInfo().endsWith(".nfo"))
{
if (handler == null)
{
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
response.setContentType("text/html; charset=utf-8");
final HtmlConfigurationWriter pw = new HtmlConfigurationWriter(response.getWriter());
pw.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"");
pw.println(" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
pw.println("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
pw.println("<head><title>dummy</title></head><body><div>");
if (handler.supports(Format.HTML))
{
handler.print(pw, Format.HTML, false);
}
else if (handler.supports(Format.TEXT))
{
pw.enableFilter(true);
handler.print(pw, Format.TEXT, false);
pw.enableFilter(false);
}
else
{
pw.enableFilter(true);
handler.print(pw, Format.JSON, false);
pw.enableFilter(false);
}
pw.println("</div></body></html>");
return;
}
else if (request.getPathInfo().endsWith(".json"))
{
if (handler == null)
{
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
response.setContentType("application/json"); //$NON-NLS-1$
response.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
final JSONConfigurationWriter jcw = new JSONConfigurationWriter(response.getWriter());
final Format format;
if (handler.supports(Format.JSON))
{
format = Format.JSON;
}
else
{
format = Format.TEXT;
jcw.startJSONWrapper();
}
printConfigurationInventory(jcw, format, handler);
jcw.endJSONWrapper();
jcw.flush();
}
else
{
if (handler == null)
{
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
final HtmlConfigurationWriter pw = new HtmlConfigurationWriter(response.getWriter());
pw.println("<script type=\"text/javascript\">");
pw.println("// <![CDATA[");
pw.println("function pad(value) { if ( value < 10 ) { return '0' + value;} return '' + value;}");
pw.println("function downloadDump(ext, full) {");
pw.println(" if (full) {");
pw.println(" var now = new Date();");
pw.println(" var name = \"configuration-status-\" + now.getUTCFullYear() + pad(now.getUTCMonth() + 1) + pad(now.getUTCDate()) + \"-\" + pad(now.getUTCHours()) + pad(now.getUTCMinutes()) + pad(now.getUTCSeconds()) + \".\";");
pw.println(" location.href = location.href + \"/\" + name + ext;");
pw.println(" } else {");
pw.println(" location.href = location.href + '.' + ext;");
pw.println(" }");
pw.println("}");
pw.println("$(document).ready(function() {");
pw.println(" $('.downloadTxt').click(function() { downloadDump('txt', false)});");
pw.println(" $('.downloadJson').click(function() { downloadDump('json', false)});");
pw.println(" $('.downloadZip').click(function() { downloadDump('zip', false)});");
pw.println(" $('.downloadFullZip').click(function() { downloadDump('zip', true)});");
pw.println(" $('.downloadFullTxt').click(function() { downloadDump('txt', true)});");
pw.println("});");
pw.println("// ]]>");
pw.println("</script>");
pw.println("<br/><p class=\"statline\">");
pw.print("Date: ");
pw.println(DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.US).format(new Date()));
pw.print("<button type=\"button\" class=\"downloadFullZip\" style=\"float: right; margin-right: 30px; margin-top: 5px;\">Download Full Zip</button>");
pw.print("<button type=\"button\" class=\"downloadFullTxt\" style=\"float: right; margin-right: 30px; margin-top: 5px;\">Download Full Text</button>");
if (handler.supports(Format.JSON))
{
pw.print("<button type=\"button\" class=\"downloadJson\" style=\"float: right; margin-right: 30px; margin-top: 5px;\">Download As JSON</button>");
}
pw.print("<button type=\"button\" class=\"downloadZip\" style=\"float: right; margin-right: 30px; margin-top: 5px;\">Download As Zip</button>");
if (handler.supports(Format.TEXT))
{
pw.print("<button type=\"button\" class=\"downloadTxt\" style=\"float: right; margin-right: 30px; margin-top: 5px;\">Download As Text</button>");
}
pw.println("<br/>&nbsp;</p>"); // status line
pw.print("<div>");
final boolean filter;
final Format format;
if (handler.supports(Format.HTML))
{
filter = false;
format = Format.HTML;
}
else if (handler.supports(Format.TEXT))
{
// prefer TEXT of JSON if available
filter = true;
format = Format.TEXT;
}
else if (handler.supports(Format.JSON))
{
filter = true;
format = Format.JSON;
}
else
{
// fallback to TEXT (if unknown format)
filter = true;
format = Format.TEXT;
}
pw.enableFilter(filter);
handler.print(pw, format, false);
pw.enableFilter(false);
pw.print("</div>");
}
}
}