001/* 002 * (C) Copyright 2006-2010 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * bstefanescu 018 */ 019package org.nuxeo.shell.automation; 020 021import java.io.InputStream; 022 023import jline.Completor; 024 025import org.nuxeo.ecm.automation.client.Session; 026import org.nuxeo.ecm.automation.client.jaxrs.impl.HttpAutomationClient; 027import org.nuxeo.ecm.automation.client.model.DocRef; 028import org.nuxeo.ecm.automation.client.model.OperationDocumentation; 029import org.nuxeo.shell.CommandRegistry; 030import org.nuxeo.shell.CommandType; 031import org.nuxeo.shell.CompletorProvider; 032import org.nuxeo.shell.Shell; 033import org.nuxeo.shell.ShellException; 034import org.nuxeo.shell.ShellFeature; 035import org.nuxeo.shell.ValueAdapter; 036import org.nuxeo.shell.automation.cmds.OperationCommandType; 037import org.nuxeo.shell.automation.cmds.RemoteCommands; 038import org.nuxeo.shell.cmds.GlobalCommands; 039 040/** 041 * The automation feature is providing connection with Nuxeo servers through automation service and remote commands 042 * based on operations. 043 * 044 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 045 */ 046public class AutomationFeature implements ShellFeature, ValueAdapter, CompletorProvider { 047 048 public static final String AUTOMATION_NS = "automation"; 049 050 protected RemoteContext ctx; 051 052 public void install(Shell shell) { 053 shell.putContextObject(AutomationFeature.class, this); 054 shell.addCompletorProvider(this); 055 shell.addValueAdapter(this); 056 shell.addRegistry(RemoteCommands.INSTANCE); 057 shell.getVersions().add("Nuxeo Server Minimal Version: " + getNuxeoServerVersion()); 058 } 059 060 public HttpAutomationClient connect(String url, String username, String password, String initialDirectory) 061 throws Exception { 062 if (isConnected()) { 063 disconnect(); 064 } 065 Shell shell = Shell.get(); 066 HttpAutomationClient client = new HttpAutomationClient(url); 067 Session session = client.getSession(username, password); 068 ctx = new RemoteContext(this, client, session, initialDirectory); 069 070 // switch to automation command namespace 071 RemoteCommands.INSTANCE.onConnect(); 072 CommandRegistry reg = new AutomationRegistry(); 073 // build automation registry 074 reg.addAnnotatedCommand(PrintOperation.class); 075 buildCommands(reg, session); 076 shell.addRegistry(reg); 077 078 shell.setActiveRegistry(RemoteCommands.INSTANCE.getName()); 079 return client; 080 } 081 082 public boolean isConnected() { 083 return ctx != null; 084 } 085 086 protected void buildCommands(CommandRegistry reg, Session session) { 087 for (OperationDocumentation op : session.getOperations().values()) { 088 if (!"Seam".equals(op.requires)) { 089 OperationCommandType type = OperationCommandType.fromOperation(op); 090 reg.addCommandType(type);// TODO 091 } 092 } 093 } 094 095 public void disconnect() { 096 if (ctx != null) { 097 ctx.getClient().shutdown(); 098 ctx.dispose(); 099 Shell shell = Shell.get(); 100 // shell.setActiveRegistry(FileSystemCommands.INSTANCE.getName()); 101 RemoteCommands.INSTANCE.onDisconnect(); 102 shell.removeRegistry(AUTOMATION_NS); 103 ctx = null; 104 } 105 } 106 107 public HttpAutomationClient getClient() { 108 return ctx.getClient(); 109 } 110 111 public Session getSession() { 112 return ctx.getSession(); 113 } 114 115 public RemoteContext getContext() { 116 return ctx; 117 } 118 119 public Completor getCompletor(Shell shell, CommandType cmd, Class<?> type) { 120 if (DocRef.class.isAssignableFrom(type)) { 121 return new DocRefCompletor(ctx); 122 } 123 return null; 124 } 125 126 @SuppressWarnings("unchecked") 127 public <T> T getValue(Shell shell, Class<T> type, String value) { 128 if (type == DocRef.class) { 129 return (T) ctx.resolveRef(value); 130 } 131 return null; 132 } 133 134 static class AutomationRegistry extends CommandRegistry { 135 public AutomationRegistry() { 136 super(GlobalCommands.INSTANCE, AUTOMATION_NS); 137 } 138 139 @Override 140 public String getTitle() { 141 return "Nuxeo Automation Commands"; 142 } 143 144 @Override 145 public String getDescription() { 146 return "Commands exposed by the Nuxeo Server through automation"; 147 } 148 } 149 150 public static String getNuxeoServerVersion() { 151 try { 152 InputStream in = AutomationFeature.class.getClassLoader().getResourceAsStream("META-INF/nuxeo.version"); 153 if (in != null) { 154 return org.nuxeo.shell.fs.FileSystem.read(in).trim(); 155 } else { 156 return "Unknown"; 157 } 158 } catch (Exception e) { 159 throw new ShellException("Failed to read server version", e); 160 } 161 } 162 163}