001/* 002 * (C) Copyright 2006-2010 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library 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 * Contributors: 015 * bstefanescu 016 */ 017package org.nuxeo.shell.automation.cmds; 018 019import java.io.File; 020import java.util.ArrayList; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024 025import jline.Completor; 026 027import org.nuxeo.ecm.automation.client.model.DocRef; 028import org.nuxeo.ecm.automation.client.model.FileBlob; 029import org.nuxeo.ecm.automation.client.model.OperationDocumentation; 030import org.nuxeo.ecm.automation.client.model.OperationDocumentation.Param; 031import org.nuxeo.ecm.automation.client.model.OperationInput; 032import org.nuxeo.shell.Shell; 033import org.nuxeo.shell.ShellException; 034import org.nuxeo.shell.automation.DocRefCompletor; 035import org.nuxeo.shell.fs.FileCompletor; 036import org.nuxeo.shell.impl.AbstractCommandType; 037 038/** 039 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 040 */ 041public class OperationCommandType extends AbstractCommandType { 042 043 public static final int TYPE_VOID = 0; 044 045 public static final int TYPE_DOC = 1; 046 047 public static final int TYPE_BLOB = 2; 048 049 public static final int TYPE_DOCS = 3; 050 051 public static final int TYPE_BLOBS = 4; 052 053 protected OperationDocumentation op; 054 055 protected int inputType = 0; 056 057 public boolean hasVoidInput() { 058 return inputType == 0; 059 } 060 061 public boolean hasBlobInput() { 062 return inputType == 2; 063 } 064 065 public boolean hasDocumentInput() { 066 return inputType == 1; 067 } 068 069 public int getInputType() { 070 return inputType; 071 } 072 073 public static OperationCommandType fromOperation(OperationDocumentation op) { 074 int inputType = 0; 075 HashMap<String, Token> params = new HashMap<String, Token>(); 076 ArrayList<Token> args = new ArrayList<Token>(); 077 078 Token tok = new Token(); 079 tok.name = "-void"; 080 tok.help = "If void the server will not return the result back"; 081 tok.isRequired = false; 082 tok.setter = new OperationParamSetter(tok.name, "boolean"); 083 params.put(tok.name, tok); 084 tok = new Token(); 085 tok.name = "-ctx"; 086 tok.help = "Can be used to inject context properties in Java properties format"; 087 tok.isRequired = true; 088 tok.setter = new OperationParamSetter(tok.name, "string"); 089 params.put(tok.name, tok); 090 091 for (Param param : op.getParams()) { 092 tok = new Token(); 093 tok.name = "-" + param.name; 094 tok.help = ""; 095 tok.isRequired = true; 096 OperationParamSetter os = new OperationParamSetter(param.name, param.getType()); 097 tok.setter = os; 098 tok.completor = os.completor; 099 params.put(tok.name, tok); 100 } 101 102 inputType = getOperationInputType(op); 103 if (inputType == TYPE_DOC || inputType == TYPE_DOCS) { 104 tok = new Token(); 105 tok.index = 0; 106 tok.isRequired = false; 107 tok.name = "the input document(s)"; 108 tok.setter = new DocInputSetter(); 109 tok.completor = DocRefCompletor.class; 110 args.add(tok); 111 } else if (inputType == TYPE_BLOB || inputType == TYPE_BLOBS) { 112 tok = new Token(); 113 tok.index = 0; 114 tok.isRequired = true; 115 tok.name = "the input file(s)"; 116 tok.setter = new BlobInputSetter(); 117 tok.completor = FileCompletor.class; 118 args.add(tok); 119 } 120 return new OperationCommandType(inputType, op, params, args); 121 } 122 123 public static int getOperationInputType(OperationDocumentation op) { 124 for (int i = 0; i < op.signature.length; i += 2) { 125 if ("void".equals(op.signature[i])) { 126 return TYPE_VOID; 127 } 128 if ("document".equals(op.signature[i])) { 129 return TYPE_DOC; 130 } 131 if ("blob".equals(op.signature[i])) { 132 return TYPE_BLOB; 133 } 134 if ("documents".equals(op.signature[i])) { 135 return TYPE_DOCS; 136 } 137 if ("bloblist".equals(op.signature[i])) { 138 return TYPE_BLOBS; 139 } 140 } 141 return TYPE_VOID; 142 } 143 144 public OperationCommandType(int inputType, OperationDocumentation op, Map<String, Token> params, List<Token> args) { 145 super(OperationCommand.class, null, params, args); 146 this.op = op; 147 this.inputType = inputType; 148 } 149 150 public String getHelp() { 151 return op.description; 152 } 153 154 public String[] getAliases() { 155 return new String[0]; 156 } 157 158 public String getName() { 159 return op.id; 160 } 161 162 @Override 163 protected Runnable createInstance(Shell shell) throws Exception { 164 OperationCommand cmd = (OperationCommand) cmdClass.newInstance(); 165 cmd.init(this, shell, op); 166 return cmd; 167 } 168 169 public static class OperationParamSetter implements Setter { 170 protected String name; 171 172 protected Class<?> type; 173 174 protected Class<? extends Completor> completor; 175 176 public OperationParamSetter(String name, String type) { 177 this.name = name; 178 if ("document".equals(type)) { 179 this.type = DocRef.class; 180 this.completor = DocRefCompletor.class; 181 } else if ("blob".equals(type)) { 182 this.type = File.class; 183 this.completor = FileCompletor.class; 184 } else { 185 this.type = String.class; 186 } 187 } 188 189 public Class<?> getType() { 190 return type; 191 } 192 193 public void set(Object obj, Object value) throws ShellException { 194 if (value instanceof File) { 195 value = new FileBlob((File) value); 196 } 197 ((OperationCommand) obj).setParam(name, value); 198 } 199 } 200 201 public static class DocInputSetter implements Setter { 202 203 public Class<?> getType() { 204 return DocRef.class; 205 } 206 207 public void set(Object obj, Object value) throws ShellException { 208 ((OperationCommand) obj).request.setInput((OperationInput) value); 209 } 210 } 211 212 public static class BlobInputSetter implements Setter { 213 public Class<?> getType() { 214 return File.class; 215 } 216 217 public void set(Object obj, Object value) throws ShellException { 218 ((OperationCommand) obj).request.setInput(new FileBlob((File) value)); 219 } 220 221 } 222 223}