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.impl.invocation.Resolver; 090import org.crsh.cli.type.ValueTypeFactory; 091 092import java.lang.reflect.Type; 093import java.util.Arrays; 094import java.util.LinkedHashMap; 095import java.util.Map; 096 097/** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */ 098public class HelpDescriptor<T> extends CommandDescriptorImpl<T> { 099 100 public static <T> HelpDescriptor<T> create(CommandDescriptorImpl<T> descriptor) { 101 return new HelpDescriptor<T>(descriptor); 102 } 103 104 /** . */ 105 static final OptionDescriptor HELP_OPTION = new OptionDescriptor( 106 null, 107 ParameterType.create(ValueTypeFactory.DEFAULT, Boolean.class), 108 Arrays.asList("h", "help"), 109 new Description("this help", "Display this help message"), 110 false, 111 false, 112 false, 113 null, 114 null 115 ); 116 117 /** . */ 118 private final HelpDescriptor<T> owner; 119 120 /** . */ 121 private final CommandDescriptorImpl<T> delegate; 122 123 /** . */ 124 private final LinkedHashMap<String, HelpDescriptor<T>> subordinates; 125 126 public HelpDescriptor(CommandDescriptorImpl<T> delegate) throws IntrospectionException { 127 this(null, delegate); 128 } 129 130 private HelpDescriptor(HelpDescriptor<T> owner, CommandDescriptorImpl<T> delegate) throws IntrospectionException { 131 super(delegate.getName(), delegate.getDescription()); 132 133 // 134 for (ParameterDescriptor parameter : delegate.getParameters()) { 135 addParameter(parameter); 136 } 137 138 // Override the help parameter only for the root level 139 // otherwise it may be repeated several times 140 if (owner == null) { 141 addParameter(HELP_OPTION); 142 } 143 144 // Wrap subordinates 145 LinkedHashMap<String, HelpDescriptor<T>> subordinates = new LinkedHashMap<String, HelpDescriptor<T>>(); 146 for (CommandDescriptorImpl<T> subordinate : delegate.getSubordinates().values()) { 147 subordinates.put(subordinate.getName(), new HelpDescriptor<T>(this, subordinate)); 148 } 149 150 // 151 this.owner = owner; 152 this.delegate = delegate; 153 this.subordinates = subordinates; 154 } 155 156 public CommandDescriptor<T> getDelegate() { 157 return delegate; 158 } 159 160 @Override 161 public CommandInvoker<T, ?> getInvoker(final InvocationMatch<T> match) { 162 163 // 164 final CommandInvoker<T, ?> invoker = delegate.getInvoker(match); 165 166 // Get the option from the top match 167 ParameterMatch<OptionDescriptor> helpDesc = null; 168 for (InvocationMatch<T> current = match;current != null && helpDesc == null;current = current.owner()) { 169 helpDesc = current.getParameter(HELP_OPTION); 170 } 171 172 // 173 final boolean help = helpDesc != null || invoker == null; 174 175 // 176 if (help) { 177 return new CommandInvoker<T, Help>() { 178 @Override 179 public InvocationMatch<T> getMatch() { 180 return match; 181 } 182 @Override 183 public Class<Help> getReturnType() { 184 return Help.class; 185 } 186 @Override 187 public Type getGenericReturnType() { 188 return Help.class; 189 } 190 @Override 191 public Class<?>[] getParameterTypes() { 192 return new Class[0]; 193 } 194 @Override 195 public Type[] getGenericParameterTypes() { 196 return new Type[0]; 197 } 198 @Override 199 public Help invoke(Resolver resolver, T command) throws InvocationException, SyntaxException { 200 return new Help<T>(delegate); 201 } 202 }; 203 } else { 204 return invoker; 205 } 206 } 207 208 @Override 209 public Class<T> getType() { 210 return delegate.getType(); 211 } 212 213 @Override 214 public CommandDescriptor<T> getOwner() { 215 return owner; 216 } 217 218 @Override 219 public Map<String, ? extends HelpDescriptor<T>> getSubordinates() { 220 return subordinates; 221 } 222 223 @Override 224 public HelpDescriptor<T> getSubordinate(String name) { 225 return subordinates.get(name); 226 } 227}