blob: 071689d4658d955e0a239f7425bf76ce245974fd [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.status.impl.webconsole;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.felix.status.PrinterMode;
import org.apache.felix.status.impl.ClassUtils;
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 final Method printMethod;
private final Method attachmentMethod;
private static final List<String> CUSTOM_MODES = new ArrayList<String>();
static {
CUSTOM_MODES.add( ConsoleConstants.MODE_TXT);
CUSTOM_MODES.add( ConsoleConstants.MODE_WEB );
CUSTOM_MODES.add( ConsoleConstants.MODE_ZIP );
}
/**
* Check whether the class implements the configuration printer.
* This is done manually to avoid having the configuration printer class available.
*/
private static boolean isConfigurationPrinter(final Class<?> clazz) {
for(final Class<?> i : clazz.getInterfaces() ) {
if ( i.getName().equals(ConsoleConstants.INTERFACE_CONFIGURATION_PRINTER) ) {
return true;
}
}
if ( clazz.getSuperclass() != null ) {
return isConfigurationPrinter(clazz.getSuperclass());
}
return false;
}
/**
* Try to create a new configuration printer adapter.
*/
public static ConfigurationPrinterAdapter createAdapter(
final Object service,
final ServiceReference ref) {
String title;
Object modes = null;
if ( isConfigurationPrinter(service.getClass()) ) {
modes = ref.getProperty(ConsoleConstants.CONFIG_PRINTER_MODES);
if ( modes == null ) {
modes = ref.getProperty( ConsoleConstants.PROPERTY_MODES );
}
final Method titleMethod = ClassUtils.searchMethod(service.getClass(), "getTitle", null);
if ( titleMethod == null ) {
return null;
}
title = (String)ClassUtils.invoke(service, titleMethod, null);
} else {
modes = ref.getProperty( ConsoleConstants.CONFIG_PRINTER_MODES );
title = (String)ref.getProperty( ConsoleConstants.PLUGIN_TITLE );
}
Object cfgPrinter = null;
Method printMethod = null;
// first: printConfiguration(PrintWriter, String)
final Method method2Params = ClassUtils.searchMethod(service.getClass(), "printConfiguration",
new Class[] {PrintWriter.class, String.class});
if ( method2Params != null ) {
cfgPrinter = service;
printMethod = method2Params;
}
if ( cfgPrinter == null ) {
// second: printConfiguration(PrintWriter)
final Method method1Params = ClassUtils.searchMethod(service.getClass(), "printConfiguration",
new Class[] {PrintWriter.class});
if ( method1Params != null ) {
cfgPrinter = service;
printMethod = method1Params;
}
}
if ( cfgPrinter != null ) {
final Object label = ref.getProperty( ConsoleConstants.PLUGIN_LABEL );
// check escaping
boolean webUnescaped;
Object ehObj = ref.getProperty( ConsoleConstants.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;
}
final String[] modesArray;
// check modes
if ( modes == null || !( modes instanceof String || modes instanceof String[] ) ) {
modesArray = null;
} else {
if ( modes instanceof String ) {
if ( CUSTOM_MODES.contains(modes) ) {
modesArray = new String[] {modes.toString()};
} else {
modesArray = 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) {
modesArray = values;
} else {
modesArray = null;
}
}
}
return new ConfigurationPrinterAdapter(
cfgPrinter,
printMethod,
ClassUtils.searchMethod(cfgPrinter.getClass(), "getAttachments", new Class[] {String.class}),
title,
(label instanceof String ? (String)label : null),
modesArray,
!webUnescaped);
}
return null;
}
private ConfigurationPrinterAdapter( final Object printer,
final Method printMethod,
final Method attachmentMethod,
final String title,
final String label,
final String[] modesArray,
final boolean escapeHtml ) {
this.printer = printer;
this.title = title;
this.label = label;
this.escapeHtml = escapeHtml;
this.printMethod = printMethod;
this.attachmentMethod = attachmentMethod;
this.modes = modesArray;
}
/**
* Map the modes to status printer modes
*/
public String[] getPrinterModes() {
final Set<String> list = new HashSet<String>();
if ( this.match(ConsoleConstants.MODE_TXT) || this.match(ConsoleConstants.MODE_ZIP) ) {
list.add(PrinterMode.ZIP_FILE_BIN.name());
}
if ( this.match(ConsoleConstants.MODE_WEB) ) {
if ( !escapeHtml ) {
list.add(PrinterMode.HTML_BODY.name());
} else {
list.add(PrinterMode.TEXT.name());
}
}
return list.toArray(new String[list.size()]);
}
private 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 final void printConfiguration( final PrintWriter pw, final String mode ) {
if ( printMethod.getParameterTypes().length > 1 ) {
ClassUtils.invoke(this.printer, this.printMethod, new Object[] {pw, mode});
} else {
ClassUtils.invoke(this.printer, this.printMethod, new Object[] {pw});
}
}
public URL[] getAttachments() {
// check if printer implements binary configuration printer
URL[] attachments = null;
if ( attachmentMethod != null ) {
attachments = (URL[])ClassUtils.invoke(printer, attachmentMethod, new Object[] {ConsoleConstants.MODE_ZIP});
}
return attachments;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return title + " (" + printer.getClass() + ")";
}
}