| /* |
| * 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() + ")"; |
| } |
| } |