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