001/* 002 * Copyright (C) 2012 eXo Platform SAS. 003 * 004 * This is free software; you can redistribute it and/or modify it 005 * under the terms of the GNU Lesser General Public License as 006 * published by the Free Software Foundation; either version 2.1 of 007 * the License, or (at your option) any later version. 008 * 009 * This software is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * You should have received a copy of the GNU Lesser General Public 015 * License along with this software; if not, write to the Free 016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 018 */ 019 020/* 021 * Copyright (C) 2012 eXo Platform SAS. 022 * 023 * This is free software; you can redistribute it and/or modify it 024 * under the terms of the GNU Lesser General Public License as 025 * published by the Free Software Foundation; either version 2.1 of 026 * the License, or (at your option) any later version. 027 * 028 * This software is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 031 * Lesser General Public License for more details. 032 * 033 * You should have received a copy of the GNU Lesser General Public 034 * License along with this software; if not, write to the Free 035 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 036 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 037 */ 038 039/* 040 * Copyright (C) 2012 eXo Platform SAS. 041 * 042 * This is free software; you can redistribute it and/or modify it 043 * under the terms of the GNU Lesser General Public License as 044 * published by the Free Software Foundation; either version 2.1 of 045 * the License, or (at your option) any later version. 046 * 047 * This software is distributed in the hope that it will be useful, 048 * but WITHOUT ANY WARRANTY; without even the implied warranty of 049 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 050 * Lesser General Public License for more details. 051 * 052 * You should have received a copy of the GNU Lesser General Public 053 * License along with this software; if not, write to the Free 054 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 055 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 056 */ 057 058/* 059 * Copyright (C) 2012 eXo Platform SAS. 060 * 061 * This is free software; you can redistribute it and/or modify it 062 * under the terms of the GNU Lesser General Public License as 063 * published by the Free Software Foundation; either version 2.1 of 064 * the License, or (at your option) any later version. 065 * 066 * This software is distributed in the hope that it will be useful, 067 * but WITHOUT ANY WARRANTY; without even the implied warranty of 068 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 069 * Lesser General Public License for more details. 070 * 071 * You should have received a copy of the GNU Lesser General Public 072 * License along with this software; if not, write to the Free 073 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 074 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 075 */ 076 077package org.crsh.cli.impl.descriptor; 078 079import org.crsh.cli.SyntaxException; 080import org.crsh.cli.descriptor.CommandDescriptor; 081import org.crsh.cli.descriptor.Description; 082import org.crsh.cli.descriptor.OptionDescriptor; 083import org.crsh.cli.descriptor.ParameterDescriptor; 084import org.crsh.cli.impl.ParameterType; 085import org.crsh.cli.impl.invocation.CommandInvoker; 086import org.crsh.cli.impl.invocation.InvocationException; 087import org.crsh.cli.impl.invocation.InvocationMatch; 088import org.crsh.cli.impl.invocation.ParameterMatch; 089import org.crsh.cli.type.ValueTypeFactory; 090 091import java.lang.reflect.Type; 092import java.util.Arrays; 093import java.util.LinkedHashMap; 094import java.util.Map; 095 096/** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */ 097public class HelpDescriptor<T> extends CommandDescriptor<T> { 098 099 public static <T> HelpDescriptor<T> create(CommandDescriptor<T> descriptor) { 100 return new HelpDescriptor<T>(descriptor); 101 } 102 103 /** . */ 104 static final OptionDescriptor HELP_OPTION = new OptionDescriptor( 105 ParameterType.create(ValueTypeFactory.DEFAULT, Boolean.class), 106 Arrays.asList("h", "help"), 107 new Description("this help", "Display this help message"), 108 false, 109 false, 110 false, 111 null, 112 null 113 ); 114 115 /** . */ 116 private final HelpDescriptor<T> owner; 117 118 /** . */ 119 private final CommandDescriptor<T> delegate; 120 121 /** . */ 122 private final LinkedHashMap<String, HelpDescriptor<T>> subordinates; 123 124 public HelpDescriptor(CommandDescriptor<T> delegate) throws IntrospectionException { 125 this(null, delegate); 126 } 127 128 private HelpDescriptor(HelpDescriptor<T> owner, CommandDescriptor<T> delegate) throws IntrospectionException { 129 super(delegate.getName(), delegate.getDescription()); 130 131 // 132 for (ParameterDescriptor parameter : delegate.getParameters()) { 133 addParameter(parameter); 134 } 135 136 // Override the help parameter only for the root level 137 // otherwise it may be repeated several times 138 if (owner == null) { 139 addParameter(HELP_OPTION); 140 } 141 142 // Wrap subordinates 143 LinkedHashMap<String, HelpDescriptor<T>> subordinates = new LinkedHashMap<String, HelpDescriptor<T>>(); 144 for (CommandDescriptor<T> subordinate : delegate.getSubordinates().values()) { 145 subordinates.put(subordinate.getName(), new HelpDescriptor<T>(this, subordinate)); 146 } 147 148 // 149 this.owner = owner; 150 this.delegate = delegate; 151 this.subordinates = subordinates; 152 } 153 154 public CommandDescriptor<T> getDelegate() { 155 return delegate; 156 } 157 158 @Override 159 public CommandInvoker<T, ?> getInvoker(final InvocationMatch<T> match) { 160 161 // 162 final CommandInvoker<T, ?> invoker = delegate.getInvoker(match); 163 164 // Get the option from the top match 165 ParameterMatch<OptionDescriptor> helpDesc = null; 166 for (InvocationMatch<T> current = match;current != null && helpDesc == null;current = current.owner()) { 167 helpDesc = current.getParameter(HELP_OPTION); 168 } 169 170 // 171 final boolean help = helpDesc != null || invoker == null; 172 173 // 174 if (help) { 175 return new CommandInvoker<T, Help>(match) { 176 @Override 177 public Class<Help> getReturnType() { 178 return Help.class; 179 } 180 @Override 181 public Type getGenericReturnType() { 182 return Help.class; 183 } 184 @Override 185 public Help invoke(T command) throws InvocationException, SyntaxException { 186 return new Help<T>(HelpDescriptor.this); 187 } 188 }; 189 } else { 190 return invoker; 191 } 192 } 193 194 @Override 195 public CommandDescriptor<T> getOwner() { 196 return owner; 197 } 198 199 @Override 200 public Map<String, ? extends HelpDescriptor<T>> getSubordinates() { 201 return subordinates; 202 } 203 204}