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; 018 019import java.io.InputStream; 020 021import jline.Completor; 022 023import org.nuxeo.ecm.automation.client.Session; 024import org.nuxeo.ecm.automation.client.jaxrs.impl.HttpAutomationClient; 025import org.nuxeo.ecm.automation.client.model.DocRef; 026import org.nuxeo.ecm.automation.client.model.OperationDocumentation; 027import org.nuxeo.shell.CommandRegistry; 028import org.nuxeo.shell.CommandType; 029import org.nuxeo.shell.CompletorProvider; 030import org.nuxeo.shell.Shell; 031import org.nuxeo.shell.ShellException; 032import org.nuxeo.shell.ShellFeature; 033import org.nuxeo.shell.ValueAdapter; 034import org.nuxeo.shell.automation.cmds.OperationCommandType; 035import org.nuxeo.shell.automation.cmds.RemoteCommands; 036import org.nuxeo.shell.cmds.GlobalCommands; 037 038/** 039 * The automation feature is providing connection with Nuxeo servers through automation service and remote commands 040 * based on operations. 041 * 042 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 043 */ 044public class AutomationFeature implements ShellFeature, ValueAdapter, CompletorProvider { 045 046 public static final String AUTOMATION_NS = "automation"; 047 048 protected RemoteContext ctx; 049 050 public void install(Shell shell) { 051 shell.putContextObject(AutomationFeature.class, this); 052 shell.addCompletorProvider(this); 053 shell.addValueAdapter(this); 054 shell.addRegistry(RemoteCommands.INSTANCE); 055 shell.getVersions().add("Nuxeo Server Minimal Version: " + getNuxeoServerVersion()); 056 } 057 058 public HttpAutomationClient connect(String url, String username, String password, String initialDirectory) 059 throws Exception { 060 if (isConnected()) { 061 disconnect(); 062 } 063 Shell shell = Shell.get(); 064 HttpAutomationClient client = new HttpAutomationClient(url); 065 Session session = client.getSession(username, password); 066 ctx = new RemoteContext(this, client, session, initialDirectory); 067 068 // switch to automation command namespace 069 RemoteCommands.INSTANCE.onConnect(); 070 CommandRegistry reg = new AutomationRegistry(); 071 // build automation registry 072 reg.addAnnotatedCommand(PrintOperation.class); 073 buildCommands(reg, session); 074 shell.addRegistry(reg); 075 076 shell.setActiveRegistry(RemoteCommands.INSTANCE.getName()); 077 return client; 078 } 079 080 public boolean isConnected() { 081 return ctx != null; 082 } 083 084 protected void buildCommands(CommandRegistry reg, Session session) { 085 for (OperationDocumentation op : session.getOperations().values()) { 086 if (!"Seam".equals(op.requires)) { 087 OperationCommandType type = OperationCommandType.fromOperation(op); 088 reg.addCommandType(type);// TODO 089 } 090 } 091 } 092 093 public void disconnect() { 094 if (ctx != null) { 095 ctx.getClient().shutdown(); 096 ctx.dispose(); 097 Shell shell = Shell.get(); 098 // shell.setActiveRegistry(FileSystemCommands.INSTANCE.getName()); 099 RemoteCommands.INSTANCE.onDisconnect(); 100 shell.removeRegistry(AUTOMATION_NS); 101 ctx = null; 102 } 103 } 104 105 public HttpAutomationClient getClient() { 106 return ctx.getClient(); 107 } 108 109 public Session getSession() { 110 return ctx.getSession(); 111 } 112 113 public RemoteContext getContext() { 114 return ctx; 115 } 116 117 public Completor getCompletor(Shell shell, CommandType cmd, Class<?> type) { 118 if (DocRef.class.isAssignableFrom(type)) { 119 return new DocRefCompletor(ctx); 120 } 121 return null; 122 } 123 124 @SuppressWarnings("unchecked") 125 public <T> T getValue(Shell shell, Class<T> type, String value) { 126 if (type == DocRef.class) { 127 return (T) ctx.resolveRef(value); 128 } 129 return null; 130 } 131 132 static class AutomationRegistry extends CommandRegistry { 133 public AutomationRegistry() { 134 super(GlobalCommands.INSTANCE, AUTOMATION_NS); 135 } 136 137 @Override 138 public String getTitle() { 139 return "Nuxeo Automation Commands"; 140 } 141 142 @Override 143 public String getDescription() { 144 return "Commands exposed by the Nuxeo Server through automation"; 145 } 146 } 147 148 public static String getNuxeoServerVersion() { 149 try { 150 InputStream in = AutomationFeature.class.getClassLoader().getResourceAsStream("META-INF/nuxeo.version"); 151 if (in != null) { 152 return org.nuxeo.shell.fs.FileSystem.read(in).trim(); 153 } else { 154 return "Unknown"; 155 } 156 } catch (Exception e) { 157 throw new ShellException("Failed to read server version", e); 158 } 159 } 160 161}