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.ecm.automation.client.jaxrs.spi; 020 021import java.util.concurrent.ExecutorService; 022import java.util.concurrent.Executors; 023import java.util.concurrent.ThreadFactory; 024import java.util.concurrent.TimeUnit; 025 026import org.nuxeo.ecm.automation.client.AdapterFactory; 027import org.nuxeo.ecm.automation.client.AdapterManager; 028import org.nuxeo.ecm.automation.client.AutomationClient; 029import org.nuxeo.ecm.automation.client.LoginCallback; 030import org.nuxeo.ecm.automation.client.LoginInfo; 031import org.nuxeo.ecm.automation.client.Session; 032 033/** 034 * Abstract class for clients running on real JVMs. 035 * <p> 036 * When your implementation is designed for running in environment that supports limited Java API like GWT or portable 037 * devices you may need to directly implement the {@link AutomationClient} interface. 038 * 039 * @author <a href="mailto:[email protected]">Bogdan Stefanescu</a> 040 */ 041public abstract class JavaClient implements AutomationClient { 042 043 protected String url; 044 045 protected AdapterManager adapters; 046 047 protected ExecutorService async; 048 049 protected JavaClient(String url) { 050 this(url, null); 051 } 052 053 public JavaClient(String url, ExecutorService executor) { 054 this.url = url.endsWith("/") ? url : url + "/"; 055 this.async = executor == null ? Executors.newCachedThreadPool(new ThreadFactory() { 056 public Thread newThread(Runnable r) { 057 return new Thread("AutomationAsyncExecutor"); 058 } 059 }) : executor; 060 } 061 062 /** 063 * Validate the credentials. The login must occurs in first place before a session is created. A stateless session 064 * may login each time using these credentials but you canot get a session without login-in first. 065 * 066 * @param username 067 * @param password 068 * @return 069 */ 070 protected abstract LoginInfo login(String username, String password); 071 072 /** 073 * Create a valid session using the authenticated login. The session will download any required data like the 074 * operation registry before being usable. 075 * 076 * @param login 077 * @return 078 */ 079 protected abstract JavaSession createSession(LoginInfo login); 080 081 @Override 082 public String getBaseUrl() { 083 return url; 084 } 085 086 public AdapterManager getAdapterManager() { 087 return adapters; 088 } 089 090 public void asyncExec(Runnable runnable) { 091 async.execute(runnable); 092 } 093 094 @Override 095 public <T> T getAdapter(Session session, Class<T> adapterType) { 096 return adapters.getAdapter(session, adapterType); 097 } 098 099 @Override 100 public void registerAdapter(AdapterFactory<?> factory) { 101 adapters.registerAdapter(factory); 102 } 103 104 @Override 105 public Session getSession(LoginCallback cb) { 106 String[] login = cb.getLogin(); 107 return getSession(login[0], login[1]); 108 } 109 110 @Override 111 public Session getSession(String username, String password) { 112 LoginInfo login = login(username, password); 113 if (login == null) { 114 throw new RuntimeException("Failed to login as " + username); 115 } 116 return createSession(login); 117 } 118 119 @Override 120 public Session getSession() { 121 return getSession((String) null, (String) null); 122 } 123 124 @Override 125 public void shutdown() { 126 shutdown(500); 127 } 128 129 /** 130 * TODO Move this in interface? 131 * 132 * @param timeout 133 */ 134 public void shutdown(long timeout) { 135 try { 136 async.awaitTermination(timeout, TimeUnit.MILLISECONDS); 137 } catch (InterruptedException e) { 138 Thread.currentThread().interrupt(); 139 // do nothing - TODO: log? 140 } finally { 141 async = null; 142 url = null; 143 adapters = null; 144 } 145 } 146 147}