/* * Copyright 2013, 2014 Deutsche Nationalbibliothek * * Licensed 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.culturegraph.mf.flux; import java.io.IOException; import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.culturegraph.mf.commons.ResourceUtil; import org.culturegraph.mf.commons.reflection.ObjectFactory; import org.culturegraph.mf.framework.MetafactureException; import org.culturegraph.mf.framework.annotations.Description; import org.culturegraph.mf.framework.annotations.In; import org.culturegraph.mf.framework.annotations.Out; import org.culturegraph.mf.framework.annotations.ReturnsAvailableArguments; /** * prints Flux help for a given {@link ObjectFactory} * * @author Markus Michael Geipel */ public final class HelpPrinter { private HelpPrinter() { // no instances } public static void print(final ObjectFactory<?> factory, final PrintStream out) { out.println("WELCOME TO METAFACTURE"); out.println(getVersionInfo()); out.println("\nUsage:\tflux FLOW_FILE [VARNAME=VALUE ...]\n"); out.println("Available pipe elements:\n"); final List<String> keyWords = new ArrayList<String>(); keyWords.addAll(factory.keySet()); Collections.sort(keyWords); for (String name : keyWords) { describe(name, factory, out); } } private static String getVersionInfo() { try { return ResourceUtil.loadProperties("build.properties").toString(); } catch (IOException e) { throw new MetafactureException("Failed to load build infos", e); } } private static <T> void describe(String name, ObjectFactory<T> factory, PrintStream out) { final Class<? extends T> moduleClass = factory.get(name).getPlainClass(); final Description desc = moduleClass.getAnnotation(Description.class); out.println(name); if (desc != null) { out.println("description:\t" + desc.value()); } final Collection<String> arguments = getAvailableArguments(moduleClass); if (!arguments.isEmpty()) { out.println("argument in\t" + arguments); } final Map<String, Class<?>> attributes = factory.get(name).getSetterTypes(); if (!attributes.isEmpty()) { out.print("options:\t"); final StringBuilder builder = new StringBuilder(); for (Entry<String, Class<?>> entry : attributes.entrySet()) { if (entry.getValue().isEnum()) { builder.append(entry.getKey()) .append(" ") .append(Arrays.toString(entry.getValue().getEnumConstants())) .append(", "); } else { builder.append(entry.getKey()) .append(" (") .append(entry.getValue().getName()) .append("), "); } } out.println(builder.substring(0, builder.length() - 2)); } out.println("implementation:\t" + moduleClass.getCanonicalName()); String inString = "<unknown>"; String outString = ""; final In inClass = moduleClass.getAnnotation(In.class); if (inClass != null) { inString = inClass.value().getCanonicalName(); } final Out outClass = moduleClass.getAnnotation(Out.class); if (outClass != null) { outString = outClass.value().getCanonicalName(); } out.println("signature:\t" + inString + " -> " + outString); out.println(); } @SuppressWarnings("unchecked") private static Collection<String> getAvailableArguments( Class<?> moduleClass) { for (Method method : moduleClass.getMethods()) { if (method.getAnnotation(ReturnsAvailableArguments.class) != null) { try { return (Collection<String>) method.invoke(moduleClass); } catch (IllegalAccessException | InvocationTargetException | IllegalArgumentException e) { // silently ignore } } } return Collections.emptyList(); } }