SourceForge.JP: Open Source Software

LoginCreate AccountHelp[auto][en][zh][de][fr][ko][es][pt]

Browse Subversion Repository

View of /gaejtools/src/main/java/appengine/util/MakeSyncCallServletDelegate.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 85 - (download) (as text) (annotate)
Mon Dec 7 16:35:18 2009 UTC (2 months ago) by shin1
File size: 6790 byte(s)
1.2.8への対応を行う。

package appengine.util;

import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

import com.google.apphosting.api.ApiProxy;
import com.google.apphosting.api.ApiProxy.ApiConfig;
import com.google.apphosting.api.ApiProxy.ApiProxyException;
import com.google.apphosting.api.ApiProxy.Environment;
import com.google.apphosting.api.ApiProxy.LogRecord;

/**
 * MakeSyncCallを行うサーブレットへ処理を委譲する{@link ApiProxy.Delegate}の実装。
 * @author shin1ogawa
 */
public class MakeSyncCallServletDelegate implements ApiProxy.Delegate<Environment> {

	static final Logger logger = Logger.getLogger(MakeSyncCallServletDelegate.class.getName());

	@SuppressWarnings("unchecked")
	final ApiProxy.Delegate<Environment> original = ApiProxy.getDelegate();

	final URI uri;

	final HttpClient httpClient;


	/**
	 * リモートに接続した状態で{@code runnable}を実行する。
	 * @param runnable
	 * @param uri 
	 */
	public static void runInDelegate(Runnable runnable, URI uri) {
		MakeSyncCallServletDelegate delegate = new MakeSyncCallServletDelegate(uri);
		ApiProxy.setDelegate(delegate);
		try {
			runnable.run();
		} finally {
			ApiProxy.setDelegate(delegate.getOriginal());
		}
	}

	/**
	 * 認証を行い、リモートに接続した状態で{@code runnable}を実行する。
	 * <p>{@code applicationUrl}と{@code servletName}を連結した文字列をmakeSyncCallServletへのURLとして使用する。</p>
	 * @param runnable
	 * @param email 
	 * @param password 
	 * @param applicationUrl 
	 * @param servletName 
	 * @throws NullPointerException 
	 * @throws IOException 
	 * @throws HttpException 
	 */
	public static void runInDelegateWithAuth(Runnable runnable, String email, String password,
			String applicationUrl, String servletName) throws NullPointerException, HttpException,
			IOException {
		MakeSyncCallServletDelegate delegate =
				new MakeSyncCallServletDelegate(new URI(applicationUrl + servletName, false));
		delegate.auth(email, password, applicationUrl, servletName);
		ApiProxy.setDelegate(delegate);
		try {
			runnable.run();
		} finally {
			ApiProxy.setDelegate(delegate.getOriginal());
		}
	}

	/**
	 * the constructor.
	 * @param uri
	 * @category constructor
	 */
	public MakeSyncCallServletDelegate(URI uri) {
		this.uri = uri;
		httpClient = new HttpClient();
	}

	public void log(Environment environment, LogRecord logRecord) {
		getOriginal().log(environment, logRecord);
	}

	/**
	 * Google Account Authentication APIで認証する。
	 * @param email
	 * @param password
	 * @param applicationUri 
	 * @param servletName 
	 * @return {@link AccountAuthenticationApiUtil#auth(HttpClient, String, String, String)}
	 * @throws HttpException
	 * @throws IOException
	 */
	public String auth(String email, String password, String applicationUri, String servletName)
			throws HttpException, IOException {
		String authToken =
				AccountAuthenticationApiUtil.auth(httpClient, email, password, ApiProxy
					.getCurrentEnvironment().getAppId());
		AccountAuthenticationApiUtil.getFromAdminServlet(httpClient, authToken, applicationUri,
				servletName);
		return authToken;
	}

	public byte[] makeSyncCall(Environment environment, String serviceName, String methodName,
			byte[] request) throws ApiProxyException {
		return protocolBufferOnHttp(environment, serviceName, methodName, request);
	}

	public Future<byte[]> makeAsyncCall(Environment arg0, String arg1, String arg2, byte[] arg3,
			ApiConfig arg4) {
		throw new UnsupportedOperationException();
	}

	private byte[] protocolBufferOnHttp(Environment environment, String serviceName,
			String methodName, final byte[] request) {
		PostMethod method = new PostMethod();
		try {
			method.setURI(uri);
		} catch (URIException e) {
			throw new MakeSyncCallServletFailureException(e);
		}
		method.addRequestHeader("serviceName", serviceName);
		method.addRequestHeader("methodName", methodName);
		method.addRequestHeader("applicationId", environment.getAppId());
		method.setRequestEntity(new RequestEntity() {

			public void writeRequest(OutputStream outputstream) throws IOException {
				outputstream.write(request);
			}

			public boolean isRepeatable() {
				return false;
			}

			public String getContentType() {
				return "application/octet-stream";
			}

			public long getContentLength() {
				return request.length;
			}
		});
		try {
			httpClient.executeMethod(method);
			int statusCode = method.getStatusCode();
			if (statusCode != HttpStatus.SC_OK) {
				if (StringUtils.isNotEmpty(method.getStatusText())) {
					logger.log(Level.WARNING, statusCode + ": " + method.getStatusText());
					throw new MakeSyncCallServletFailureException(statusCode + ": "
							+ method.getStatusText());
				} else {
					logger.log(Level.WARNING, statusCode + ": "
							+ new String(IOUtils.toByteArray(method.getResponseBodyAsStream())));
					throw new MakeSyncCallServletFailureException(statusCode + ": "
							+ new String(IOUtils.toByteArray(method.getResponseBodyAsStream())));
				}
			}
			return IOUtils.toByteArray(method.getResponseBodyAsStream());
		} catch (HttpException e) {
			throw new MakeSyncCallServletFailureException(e);
		} catch (IOException e) {
			throw new MakeSyncCallServletFailureException(e);
		} finally {
			method.releaseConnection();
		}
	}

	/**
	 * @return 元々ApiProxyに設定されていた{@link ApiProxy.Delegate}のインスタンス
	 */
	public ApiProxy.Delegate<Environment> getOriginal() {
		return original;
	}


	/**
	 * {@link MakeSyncCallServletDelegate#makeSyncCall(Environment, String, String, byte[])}
	 * を実行中に{@link Exception}が発生した場合にそれをラップして投げ直す{@link RuntimeException}.
	 * @author shin1ogawa
	 */
	public static class MakeSyncCallServletFailureException extends RuntimeException {

		private static final long serialVersionUID = -6963701246227196182L;


		/**
		 * the constructor.
		 * @param message
		 * @category constructor
		 */
		public MakeSyncCallServletFailureException(String message) {
			super(message);
		}

		/**
		 * the constructor.
		 * @param cause
		 * @category constructor
		 */
		public MakeSyncCallServletFailureException(Throwable cause) {
			super(cause);
		}
	}
}

Back to Project
Back to SourceForge.jp
  SourceForge.jp (Powered by ViewVC)
Powered by ViewVC 1.0.5
ViewVC Help