FELIX-3874 : Create new status printer module
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1439960 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationPrinterAdapter.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationPrinterAdapter.java
deleted file mode 100644
index fecafe0..0000000
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationPrinterAdapter.java
+++ /dev/null
@@ -1,290 +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.
- */
-package org.apache.felix.webconsole.internal.misc;
-
-import java.io.PrintWriter;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.felix.webconsole.*;
-import org.osgi.framework.ServiceReference;
-
-/**
- * Helper class for a configuration printer.
- */
-public class ConfigurationPrinterAdapter
-{
-
- private final Object printer;
- public String title;
- public String label;
- private final String[] modes;
- private final boolean escapeHtml;
- private Method modeAwarePrintMethod;
- private Method printMethod;
- private Method attachmentMethod;
- private boolean checkedAttachmentMethod = false;
-
- private static final List CUSTOM_MODES = new ArrayList();
- static
- {
- CUSTOM_MODES.add( ConfigurationPrinter.MODE_TXT );
- CUSTOM_MODES.add( ConfigurationPrinter.MODE_WEB );
- CUSTOM_MODES.add( ConfigurationPrinter.MODE_ZIP );
- }
-
- public static ConfigurationPrinterAdapter createAdapter(
- final Object service,
- final ServiceReference ref)
- {
- String title;
- Object cfgPrinter = null;
- Object modes = null;
- Method printMethod = null;
- if ( service instanceof ConfigurationPrinter )
- {
- modes = ref.getProperty(WebConsoleConstants.CONFIG_PRINTER_MODES);
- if ( modes == null )
- {
- modes = ref.getProperty( ConfigurationPrinter.PROPERTY_MODES );
- }
- cfgPrinter = service;
- title = ((ConfigurationPrinter) service).getTitle();
- }
- else
- {
- modes = ref.getProperty( WebConsoleConstants.CONFIG_PRINTER_MODES );
- title = (String)ref.getProperty( WebConsoleConstants.PLUGIN_TITLE );
-
- // first: printConfiguration(PrintWriter, String)
- final Method method2Params = searchMethod(service, "printConfiguration",
- new Class[] {PrintWriter.class, String.class});
- if ( method2Params != null )
- {
- cfgPrinter = service;
- printMethod = method2Params;
- }
-
- if ( cfgPrinter == null )
- {
- // second: printConfiguration(PrintWriter)
- final Method method1Params = searchMethod(service, "printConfiguration",
- new Class[] {PrintWriter.class});
- if ( method1Params != null )
- {
- cfgPrinter = service;
- printMethod = method1Params;
- }
- }
- }
- if ( cfgPrinter != null )
- {
- Object label = ref.getProperty( WebConsoleConstants.PLUGIN_LABEL);
- boolean webUnescaped;
- Object ehObj = ref.getProperty( WebConsoleConstants.CONFIG_PRINTER_WEB_UNESCAPED );
- if ( ehObj instanceof Boolean )
- {
- webUnescaped = ( ( Boolean ) ehObj ).booleanValue();
- }
- else if ( ehObj instanceof String )
- {
- webUnescaped = Boolean.valueOf( ( String ) ehObj ).booleanValue();
- }
- else
- {
- webUnescaped = false;
- }
- return new ConfigurationPrinterAdapter(
- cfgPrinter,
- printMethod,
- title,
- (label instanceof String ? (String)label : null),
- modes,
- !webUnescaped);
- }
- return null;
- }
-
- private ConfigurationPrinterAdapter( final Object printer,
- final Method printMethod,
- final String title,
- final String label,
- final Object modes,
- final boolean escapeHtml )
- {
- this.printer = printer;
- this.title = title;
- this.label = label;
- this.escapeHtml = escapeHtml;
- if ( printMethod != null )
- {
- if ( printMethod.getParameterTypes().length > 1 )
- {
- this.modeAwarePrintMethod = printMethod;
- }
- else
- {
- this.printMethod = printMethod;
- }
- }
- if ( modes == null || !( modes instanceof String || modes instanceof String[] ) )
- {
- this.modes = null;
- }
- else
- {
- if ( modes instanceof String )
- {
- if ( CUSTOM_MODES.contains(modes) )
- {
- this.modes = new String[] {modes.toString()};
- }
- else
- {
- this.modes = null;
- }
- }
- else
- {
- final String[] values = (String[])modes;
- boolean valid = values.length > 0;
- for(int i=0; i<values.length; i++)
- {
- if ( !CUSTOM_MODES.contains(values[i]) )
- {
- valid = false;
- break;
- }
- }
- if ( valid)
- {
- this.modes = values;
- }
- else
- {
- this.modes = null;
- }
- }
- }
- }
-
- public boolean match(final String mode)
- {
- if ( this.modes == null)
- {
- return true;
- }
- for(int i=0; i<this.modes.length; i++)
- {
- if ( this.modes[i].equals(mode) )
- {
- return true;
- }
- }
- return false;
- }
-
- public boolean escapeHtml()
- {
- return escapeHtml;
- }
-
- public final void printConfiguration( final PrintWriter pw,
- final String mode )
- {
- if ( printer instanceof ModeAwareConfigurationPrinter )
- {
- ( ( ModeAwareConfigurationPrinter ) printer ).printConfiguration( pw, mode );
- }
- else if ( printer instanceof ConfigurationPrinter )
- {
- ( ( ConfigurationPrinter ) printer ).printConfiguration( pw );
- }
- else if ( this.modeAwarePrintMethod != null )
- {
- this.invoke(this.modeAwarePrintMethod, new Object[] {pw, mode});
- } else if ( this.printMethod != null )
- {
- this.invoke(this.printMethod, new Object[] {pw});
- }
- }
-
- public URL[] getAttachments( final String mode )
- {
- // check if printer implements binary configuration printer
- URL[] attachments = null;
- if ( printer instanceof AttachmentProvider )
- {
- attachments = ((AttachmentProvider)printer).getAttachments(mode);
- }
- else
- {
- if ( !checkedAttachmentMethod )
- {
- attachmentMethod = searchMethod(printer, "getAttachments", new Class[] {String.class});
- checkedAttachmentMethod = true;
- }
- if ( attachmentMethod != null )
- {
- attachments = (URL[])invoke(attachmentMethod, new Object[] {mode});
- }
- }
- return attachments;
- }
-
- /**
- * @see java.lang.Object#toString()
- */
- public String toString() {
- return title + " (" + printer.getClass() + ")";
- }
-
- /**
- * Search a method with the given name and signature
- */
- private static Method searchMethod(final Object obj, final String mName, final Class[] params)
- {
- try
- {
- return obj.getClass().getDeclaredMethod(mName, params);
- }
- catch (Throwable nsme)
- {
- // ignore, we catch Throwable above to not only catch NoSuchMethodException
- // but also other ones like ClassDefNotFoundError etc.
- }
- return null;
- }
-
- /**
- * Invoke the method on the printer with the arguments.
- */
- protected Object invoke(final Method m, final Object[] args)
- {
- try
- {
- return m.invoke(printer, args);
- }
- catch (Throwable e)
- {
- // ignore
- }
- return null;
- }
-}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java
index 5797fe9..ac3aed4 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java
@@ -17,386 +17,14 @@
package org.apache.felix.webconsole.internal.misc;
-import java.io.*;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.text.DateFormat;
-import java.text.MessageFormat;
-import java.util.*;
-import java.util.zip.*;
+import java.io.PrintWriter;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.felix.webconsole.*;
-import org.apache.felix.webconsole.internal.OsgiManagerPlugin;
-import org.apache.felix.webconsole.internal.i18n.ResourceBundleManager;
-import org.osgi.framework.*;
-import org.osgi.util.tracker.ServiceTracker;
+import org.apache.felix.webconsole.WebConsoleUtil;
-/**
- * ConfigurationRender plugin renders the configuration status - a textual
- * representation of the current framework status. The content itself is
- * internally generated by the {@link ConfigurationPrinter} plugins.
- */
-public class ConfigurationRender extends SimpleWebConsolePlugin implements OsgiManagerPlugin
+public class ConfigurationRender
{
- private static final String LABEL = "config";
- private static final String TITLE = "%configStatus.pluginTitle";
- private static final String[] CSS_REFS = { "/res/ui/configurationrender.css" };
-
- // use English as the locale for all non-display titles
- private static final Locale DEFAULT = Locale.ENGLISH;
-
- /**
- * Formatter pattern to render the current time of status generation.
- */
- private static final DateFormat DISPLAY_DATE_FORMAT = DateFormat.getDateTimeInstance( DateFormat.LONG,
- DateFormat.LONG, Locale.US );
-
- /**
- * The resource bundle manager to allow for status printer title
- * localization
- */
- private final ResourceBundleManager resourceBundleManager;
-
- private ServiceTracker cfgPrinterTracker;
-
- private int cfgPrinterTrackerCount;
-
- private ArrayList configurationPrinters;
-
- /** Default constructor */
- public ConfigurationRender( final ResourceBundleManager resourceBundleManager )
- {
- super( LABEL, TITLE, CATEGORY_OSGI_MANAGER, CSS_REFS );
- this.resourceBundleManager = resourceBundleManager;
- }
-
-
- /**
- * @see org.apache.felix.webconsole.SimpleWebConsolePlugin#deactivate()
- */
- public void deactivate()
- {
- // make sure the service tracker is closed and removed on deactivate
- ServiceTracker oldTracker = cfgPrinterTracker;
- if ( oldTracker != null )
- {
- oldTracker.close();
- }
- cfgPrinterTracker = null;
- configurationPrinters = null;
-
- super.deactivate();
- }
-
- /**
- * Returns the requested printer name if the current request contains one
- */
- private String getRequestedPrinterName(final HttpServletRequest request)
- {
- String name = request.getPathInfo();
- final int dotPos = name.lastIndexOf('.');
- if ( dotPos != -1 )
- {
- name = name.substring(0, dotPos);
- }
- name = name.substring( name.lastIndexOf('/') + 1);
- name = WebConsoleUtil.urlDecode( name );
- return name;
- }
- /**
- * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
- */
- protected final void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
- IOException
- {
- if ( request.getPathInfo().endsWith( ".txt" ) )
- {
- response.setContentType( "text/plain; charset=utf-8" );
- ConfigurationWriter pw = new PlainTextConfigurationWriter( response.getWriter() );
- printConfigurationStatus( pw, ConfigurationPrinter.MODE_TXT, getRequestedPrinterName(request) );
- pw.flush();
- }
- else if ( request.getPathInfo().endsWith( ".zip" ) )
- {
- String type = getServletContext().getMimeType( request.getPathInfo() );
- if ( type == null )
- {
- type = "application/x-zip";
- }
- response.setContentType( type );
-
- ZipOutputStream zip = new ZipOutputStream( response.getOutputStream() );
- zip.setLevel( Deflater.BEST_SPEED );
- zip.setMethod( ZipOutputStream.DEFLATED );
-
- final ConfigurationWriter pw = new ZipConfigurationWriter( zip );
- printConfigurationStatus( pw, ConfigurationPrinter.MODE_ZIP, getRequestedPrinterName(request) );
- pw.flush();
-
- addAttachments( pw, ConfigurationPrinter.MODE_ZIP );
- zip.finish();
- }
- else if ( request.getPathInfo().endsWith( ".nfo" ) )
- {
- WebConsoleUtil.setNoCache( response );
- response.setContentType( "text/html; charset=utf-8" );
-
- final String name = getRequestedPrinterName(request);
-
- 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>" );
-
- Collection printers = getPrintersForLabel(name);
- if ( printers != null )
- {
- for (Iterator i = printers.iterator(); i.hasNext();)
- {
- final ConfigurationPrinterAdapter desc = (ConfigurationPrinterAdapter) i.next();
- pw.enableFilter( desc.escapeHtml() );
- printConfigurationPrinter( pw, desc, ConfigurationPrinter.MODE_WEB );
- pw.enableFilter( false );
- pw.println( "</div></body></html>" );
- return;
- }
- }
-
- response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Invalid configuration printer: " + name);
- }
- else
- {
- super.doGet( request, response );
- }
- }
-
-
- /**
- * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#renderContent(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
- */
- protected final void renderContent( HttpServletRequest request, HttpServletResponse response ) throws IOException
- {
-
- //ConfigurationWriter pw = new HtmlConfigurationWriter( response.getWriter() );
- PrintWriter pw = response.getWriter();
- pw.println( "<script type='text/javascript' src='${appRoot}/res/ui/ui.tabs.paging.js'></script>" );
- pw.println( "<script type='text/javascript' src='${appRoot}/res/ui/configurationrender.js'></script>" );
-
- pw.println( "<br/><p class=\"statline\">");
-
- final Date currentTime = new Date();
- synchronized ( DISPLAY_DATE_FORMAT )
- {
- pw.print("Date: ");
- pw.println(DISPLAY_DATE_FORMAT.format(currentTime));
- }
-
- pw.print("<button type=\"button\" class=\"downloadZip\" style=\"float: right; margin-right: 30px; margin-top: 5px;\">Download Zip</button>");
- pw.print("<button type=\"button\" class=\"downloadTxt\" style=\"float: right; margin-right: 30px; margin-top: 5px;\">Download Text</button>");
-
- pw.println("<br/> </p>"); // status line
-
- // display some information while the data is loading
- // load the data (hidden to begin with)
- pw.println("<div id='tabs'> <!-- tabs container -->");
- pw.println("<ul> <!-- tabs on top -->");
-
- // print headers only
- final String pluginRoot = request.getAttribute( WebConsoleConstants.ATTR_PLUGIN_ROOT ) + "/";
- Collection printers = getConfigurationPrinters();
- for (Iterator i = printers.iterator(); i.hasNext();)
- {
- final ConfigurationPrinterAdapter desc = (ConfigurationPrinterAdapter) i.next();
- if ( desc.match( ConfigurationPrinter.MODE_WEB ) )
- {
- final String label = desc.label;
- final String title = desc.title;
- pw.print("<li><a href='" + pluginRoot + URLEncoder.encode(label) + ".nfo'>" + title + "</a></li>" );
- }
- }
- pw.println("</ul> <!-- end tabs on top -->");
- pw.println();
-
- pw.println("</div> <!-- end tabs container -->");
-
- pw.println("<div id=\"waitDlg\" title=\"${configStatus.wait}\" class=\"ui-helper-hidden\"><img src=\"${appRoot}/res/imgs/loading.gif\" alt=\"${configStatus.wait}\" />${configStatus.wait.msg}</div>");
-
- pw.flush();
- }
-
- private List getPrintersForLabel(final String label)
- {
- List list = null;
- for ( Iterator cpi = getConfigurationPrinters().iterator(); cpi.hasNext(); )
- {
- final ConfigurationPrinterAdapter desc = (ConfigurationPrinterAdapter) cpi.next();
- if (desc.label.equals( label ) )
- {
- if ( list == null )
- {
- list = new ArrayList();
- list.add(desc);
- }
- }
- }
- return list;
- }
-
- private void printConfigurationStatus( ConfigurationWriter pw, final String mode, final String optionalLabel )
- {
- // check if we have printers for that label
- Collection printers = getPrintersForLabel(optionalLabel);
- if ( printers == null )
- {
- // if not use all
- printers = getConfigurationPrinters();
- }
-
- for ( Iterator cpi = printers.iterator(); cpi.hasNext(); )
- {
- final ConfigurationPrinterAdapter desc = (ConfigurationPrinterAdapter) cpi.next();
- if ( desc.match(mode) )
- {
- printConfigurationPrinter( pw, desc, mode );
- }
- }
- }
-
- private final synchronized List getConfigurationPrinters()
- {
- if ( cfgPrinterTracker == null )
- {
- try
- {
- cfgPrinterTracker = new ServiceTracker( getBundleContext(),
- getBundleContext().createFilter("(|(" + Constants.OBJECTCLASS + "=" + ConfigurationPrinter.class.getName() + ")" +
- "(&(" + WebConsoleConstants.PLUGIN_LABEL + "=*)(&("
- + WebConsoleConstants.PLUGIN_TITLE + "=*)("
- + WebConsoleConstants.CONFIG_PRINTER_MODES + "=*))))"),
- null );
- }
- catch (InvalidSyntaxException e)
- {
- // ignore
- }
- cfgPrinterTracker.open();
- cfgPrinterTrackerCount = -1;
- }
-
- if ( cfgPrinterTrackerCount != cfgPrinterTracker.getTrackingCount() )
- {
- SortedMap cp = new TreeMap();
- ServiceReference[] refs = cfgPrinterTracker.getServiceReferences();
- if ( refs != null )
- {
- for ( int i = 0; i < refs.length; i++ )
- {
- final ServiceReference ref = refs[i];
- final Object service = cfgPrinterTracker.getService( ref );
- if ( service != null )
- {
- final ConfigurationPrinterAdapter desc = ConfigurationPrinterAdapter.createAdapter(service, ref);
- if ( desc != null )
- {
- addConfigurationPrinter( cp, desc, ref.getBundle() );
- }
- }
- }
- }
- configurationPrinters = new ArrayList(cp.values());
- cfgPrinterTrackerCount = cfgPrinterTracker.getTrackingCount();
- }
-
- return configurationPrinters;
- }
-
-
- private final void addConfigurationPrinter( final SortedMap printers,
- final ConfigurationPrinterAdapter desc,
- final Bundle provider)
- {
- desc.title = getTitle(desc.title, provider );
- String sortKey = desc.title;
- if ( printers.containsKey( sortKey ) )
- {
- int idx = -1;
- String idxTitle;
- do
- {
- idx++;
- idxTitle = sortKey + idx;
- }
- while ( printers.containsKey( idxTitle ) );
- sortKey = idxTitle;
- }
- if ( desc.label == null )
- {
- desc.label = sortKey;
- }
- printers.put( sortKey, desc );
- }
-
-
- // This is Sling stuff, we comment it out for now
- // private void printRawFrameworkProperties(PrintWriter pw) {
- // pw.println("*** Raw Framework properties:");
- //
- // File file = new File(getBundleContext().getProperty("sling.home"),
- // "sling.properties");
- // if (file.exists()) {
- // Properties props = new Properties();
- // InputStream ins = null;
- // try {
- // ins = new FileInputStream(file);
- // props.load(ins);
- // } catch (IOException ioe) {
- // // handle or ignore
- // } finally {
- // IOUtils.closeQuietly(ins);
- // }
- //
- // SortedSet keys = new TreeSet(props.keySet());
- // for (Iterator ki = keys.iterator(); ki.hasNext();) {
- // Object key = ki.next();
- // infoLine(pw, null, (String) key, props.get(key));
- // }
- //
- // } else {
- // pw.println(" No Framework properties in " + file);
- // }
- //
- // pw.println();
- // }
-
-
- private final void printConfigurationPrinter( final ConfigurationWriter pw,
- final ConfigurationPrinterAdapter desc,
- final String mode )
- {
- pw.title( desc.title );
- try
- {
- desc.printConfiguration(pw, mode);
- }
- catch ( Throwable t )
- {
- pw.println();
- pw.println( "Configuration Printer failed: " + t.toString() );
- pw.println();
- log( "Configuration Printer " + desc + " failed", t );
- }
- pw.end();
- }
-
-
/**
* Renders an info line - element in the framework configuration. The info line will
* look like:
@@ -428,270 +56,4 @@
pw.println();
}
-
- private final String getTitle( final String title, final Bundle provider )
- {
- if ( !title.startsWith( "%" ) )
- {
- return title;
- }
-
- ResourceBundle res = resourceBundleManager.getResourceBundle( provider, DEFAULT );
- return res.getString( title.substring( 1 ) );
- }
-
- private abstract static class ConfigurationWriter extends PrintWriter
- {
-
- ConfigurationWriter( Writer delegatee )
- {
- super( delegatee );
- }
-
-
- abstract void title( String title );
-
-
- abstract void end();
-
-
- public void handleAttachments( final String title, final URL[] urls ) throws IOException
- {
- throw new UnsupportedOperationException( "handleAttachments not supported by this configuration writer: "
- + this );
- }
-
- }
-
- private static class HtmlConfigurationWriter extends ConfigurationWriter
- {
-
- // whether or not to filter "<" signs in the output
- private boolean doFilter;
-
-
- HtmlConfigurationWriter( Writer delegatee )
- {
- super( delegatee );
- }
-
-
- void enableFilter( final boolean doFilter )
- {
- this.doFilter = doFilter;
- }
-
-
- public void title( String title )
- {
- }
-
-
- public void end()
- {
- }
-
-
- // IE has an issue with white-space:pre in our case so, we write
- // <br/> instead of [CR]LF to get the line break. This also works
- // in other browsers.
- public void println()
- {
- if ( doFilter )
- {
- this.write('\n'); // write <br/>
- }
- else
- {
- super.println();
- }
- }
-
- // some VM implementation directly write in underlying stream, instead of
- // delegation to the write() method. So we need to override this, to make
- // sure, that everything is escaped correctly
- public void print(String str)
- {
- final char[] chars = str.toCharArray();
- write(chars, 0, chars.length);
- }
-
-
- private final char[] oneChar = new char[1];
-
- // always delegate to write(char[], int, int) otherwise in some VM
- // it cause endless cycle and StackOverflowError
- public void write(final int character)
- {
- synchronized (oneChar)
- {
- oneChar[0] = (char) character;
- write(oneChar, 0, 1);
- }
- }
-
- // write the characters unmodified unless filtering is enabled in
- // which case the writeFiltered(String) method is called for filtering
- public void write(char[] chars, int off, int len)
- {
- if (doFilter)
- {
- chars = WebConsoleUtil.escapeHtml(new String(chars, off, len)).toCharArray();
- off = 0;
- len = chars.length;
- }
- super.write(chars, off, len);
- }
-
-
- // write the string unmodified unless filtering is enabled in
- // which case the writeFiltered(String) method is called for filtering
- public void write( final String string, final int off, final int len )
- {
- write(string.toCharArray(), off, len);
- }
-
- }
-
- private void addAttachments( final ConfigurationWriter cf, final String mode )
- throws IOException
- {
- for ( Iterator cpi = getConfigurationPrinters().iterator(); cpi.hasNext(); )
- {
- // check if printer supports zip mode
- final ConfigurationPrinterAdapter desc = (ConfigurationPrinterAdapter) cpi.next();
- if ( desc.match(mode) )
- {
- final URL[] attachments = desc.getAttachments(mode);
- if ( attachments != null )
- {
- cf.handleAttachments( desc.title, attachments );
- }
- }
- }
-
- }
-
- private static class PlainTextConfigurationWriter extends ConfigurationWriter
- {
-
- PlainTextConfigurationWriter( Writer delegatee )
- {
- super( delegatee );
- }
-
-
- public void title( String title )
- {
- print( "*** " );
- print( title );
- println( ":" );
- }
-
-
- public void end()
- {
- println();
- }
- }
-
- private static class ZipConfigurationWriter extends ConfigurationWriter
- {
- private final ZipOutputStream zip;
-
- private int counter;
-
-
- ZipConfigurationWriter( ZipOutputStream zip )
- {
- super( new OutputStreamWriter( zip ) );
- this.zip = zip;
- }
-
-
- public void title( String title )
- {
- String name = MessageFormat.format( "{0,number,000}-{1}.txt", new Object[]
- { new Integer( counter ), title } );
-
- counter++;
-
- ZipEntry entry = new ZipEntry( name );
- try
- {
- zip.putNextEntry( entry );
- }
- catch ( IOException ioe )
- {
- // should handle
- }
- }
-
- private OutputStream startFile( String title, String name)
- {
- final String path = MessageFormat.format( "{0,number,000}-{1}/{2}", new Object[]
- { new Integer( counter ), title, name } );
- ZipEntry entry = new ZipEntry( path );
- try
- {
- zip.putNextEntry( entry );
- }
- catch ( IOException ioe )
- {
- // should handle
- }
- return zip;
- }
-
- public void handleAttachments( final String title, final URL[] attachments)
- throws IOException
- {
- for(int i = 0; i < attachments.length; i++)
- {
- final URL current = attachments[i];
- final String path = current.getPath();
- final String name;
- if ( path == null || path.length() == 0 )
- {
- // sanity code, we should have a path, but if not let's
- // just create some random name
- name = "file" + Double.doubleToLongBits( Math.random() );
- }
- else
- {
- final int pos = path.lastIndexOf('/');
- name = (pos == -1 ? path : path.substring(pos + 1));
- }
- final OutputStream os = this.startFile(title, name);
- final InputStream is = current.openStream();
- try
- {
- IOUtils.copy(is, os);
- }
- finally
- {
- IOUtils.closeQuietly(is);
- }
- this.end();
- }
-
- // increase the filename counter
- counter++;
- }
-
-
- public void end()
- {
- flush();
-
- try
- {
- zip.closeEntry();
- }
- catch ( IOException ioe )
- {
- // should handle
- }
- }
- }
}