diff --git a/appengine/.classpath b/appengine/.classpath new file mode 100644 index 000000000..cc1ca7b80 --- /dev/null +++ b/appengine/.classpath @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/appengine/.externalToolBuilders/com.google.appengine.eclipse.core.projectValidator.launch b/appengine/.externalToolBuilders/com.google.appengine.eclipse.core.projectValidator.launch new file mode 100644 index 000000000..3a3b1b194 --- /dev/null +++ b/appengine/.externalToolBuilders/com.google.appengine.eclipse.core.projectValidator.launch @@ -0,0 +1,7 @@ + + + + + + + diff --git a/appengine/.externalToolBuilders/com.google.gdt.eclipse.core.webAppProjectValidator.launch b/appengine/.externalToolBuilders/com.google.gdt.eclipse.core.webAppProjectValidator.launch new file mode 100644 index 000000000..eb4252719 --- /dev/null +++ b/appengine/.externalToolBuilders/com.google.gdt.eclipse.core.webAppProjectValidator.launch @@ -0,0 +1,7 @@ + + + + + + + diff --git a/appengine/.project b/appengine/.project new file mode 100644 index 000000000..c7fc93149 --- /dev/null +++ b/appengine/.project @@ -0,0 +1,43 @@ + + + gridworks appengine + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/com.google.gdt.eclipse.core.webAppProjectValidator.launch + + + + + com.google.appengine.eclipse.core.enhancerbuilder + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/com.google.appengine.eclipse.core.projectValidator.launch + + + + + + org.eclipse.jdt.core.javanature + com.google.appengine.eclipse.core.gaeNature + + diff --git a/appengine/.settings/com.google.appengine.eclipse.core.prefs b/appengine/.settings/com.google.appengine.eclipse.core.prefs new file mode 100644 index 000000000..b727dd4d9 --- /dev/null +++ b/appengine/.settings/com.google.appengine.eclipse.core.prefs @@ -0,0 +1,3 @@ +#Wed May 26 15:13:15 PDT 2010 +eclipse.preferences.version=1 +validationExclusions=src/com/metaweb/gridworks/appengine/*ClientConnection*.java diff --git a/appengine/.settings/com.google.gdt.eclipse.core.prefs b/appengine/.settings/com.google.gdt.eclipse.core.prefs new file mode 100644 index 000000000..a060470b7 --- /dev/null +++ b/appengine/.settings/com.google.gdt.eclipse.core.prefs @@ -0,0 +1,5 @@ +#Wed May 26 15:11:38 PDT 2010 +eclipse.preferences.version=1 +jarsExcludedFromWebInfLib= +warSrcDir= +warSrcDirIsOutput=true diff --git a/appengine/lib/slf4j-jdk14-1.5.6.jar b/appengine/lib/slf4j-jdk14-1.5.6.jar new file mode 100644 index 000000000..1ce0a28e7 Binary files /dev/null and b/appengine/lib/slf4j-jdk14-1.5.6.jar differ diff --git a/appengine/src/com/metaweb/gridworks/appengine/AppEngineClientConnection.java b/appengine/src/com/metaweb/gridworks/appengine/AppEngineClientConnection.java new file mode 100644 index 000000000..9f0effa08 --- /dev/null +++ b/appengine/src/com/metaweb/gridworks/appengine/AppEngineClientConnection.java @@ -0,0 +1,243 @@ +package com.metaweb.gridworks.appengine; + +import static com.google.appengine.api.urlfetch.FetchOptions.Builder.allowTruncate; + +import java.io.ByteArrayOutputStream; +import java.net.InetAddress; +import java.net.URL; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.SSLSession; + +import org.apache.http.Header; +import org.apache.http.HttpConnectionMetrics; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolVersion; +import org.apache.http.conn.ManagedClientConnection; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.message.BasicHttpResponse; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.HttpContext; + +import com.google.appengine.api.urlfetch.HTTPHeader; +import com.google.appengine.api.urlfetch.HTTPMethod; +import com.google.appengine.api.urlfetch.HTTPRequest; +import com.google.appengine.api.urlfetch.HTTPResponse; +import com.google.appengine.api.urlfetch.URLFetchService; +import com.google.appengine.api.urlfetch.URLFetchServiceFactory; + +class AppEngineClientConnection implements ManagedClientConnection { + // Managed is the composition of ConnectionReleaseTrigger, + // HttpClientConnection, HttpConnection, HttpInetConnection + + private HttpRoute _route; + private Object _state; + private boolean _reuseable; + + public AppEngineClientConnection(HttpRoute route, Object state) { + _route = route; + _state = state; + } + + // ManagedClientConnection methods + + public HttpRoute getRoute() { + return _route; + } + + public Object getState() { + return _state; + } + + public SSLSession getSSLSession() { + return null; + } + + public boolean isSecure() { + // XXX maybe parse the url to see if it's https? + return false; + } + + public boolean isMarkedReusable() { + return _reuseable; + } + + public void markReusable() { + _reuseable = true; + } + + public void layerProtocol(HttpContext context, HttpParams params) { + return; + } + + public void open(HttpRoute route, HttpContext context, HttpParams params) { + return; + } + + public void setIdleDuration(long duration, TimeUnit unit) { + return; + } + + public void setState(Object state) { + _state = state; + } + + public void tunnelProxy(HttpHost next, boolean secure, HttpParams params) { + return; + } + + public void tunnelTarget(boolean secure, HttpParams params) { + return; + } + + public void unmarkReusable() { + _reuseable = false; + } + + + // ConnectionReleaseTrigger methods + + public void releaseConnection() { + return; + } + + public void abortConnection() { + return; + } + + // HttpClientConnection methods + + private HTTPRequest _appengine_hrequest; + private HTTPResponse _appengine_hresponse; + + public void flush() { + return; + } + + public boolean isResponseAvailable(int timeout) { + // XXX possibly use Async fetcher + return true; + } + + public void receiveResponseEntity(org.apache.http.HttpResponse apache_response) { + byte[] data = _appengine_hresponse.getContent(); + + if (data != null) { + apache_response.setEntity(new ByteArrayEntity(data)); + } + } + + public HttpResponse receiveResponseHeader() { + URLFetchService ufs = URLFetchServiceFactory.getURLFetchService(); + try { + _appengine_hresponse = ufs.fetch(_appengine_hrequest); + } catch (java.io.IOException e) { + throw new RuntimeException(e); + } + + org.apache.http.HttpResponse apache_response = + new BasicHttpResponse(new ProtocolVersion("HTTP", 1, 0), + _appengine_hresponse.getResponseCode(), + null); + + for (HTTPHeader h : _appengine_hresponse.getHeaders()) { + apache_response.addHeader(h.getName(), h.getValue()); + } + + return apache_response; + } + + public void sendRequestEntity(org.apache.http.HttpEntityEnclosingRequest request) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + + org.apache.http.HttpEntity ent = request.getEntity(); + if (ent != null) { + try { + ent.writeTo(os); + } catch (java.io.IOException e) { + throw new RuntimeException(e); + } + } + + _appengine_hrequest.setPayload(os.toByteArray()); + } + + public void sendRequestHeader(org.apache.http.HttpRequest apache_request) { + URL request_url; + + HttpHost host = _route.getTargetHost(); + + String protocol = host.getSchemeName(); + String addr = host.getHostName(); + int port = host.getPort(); + + String path = apache_request.getRequestLine().getUri(); + + try { + request_url = new URL(protocol, addr, port, path); + } catch (java.net.MalformedURLException e) { + throw new RuntimeException(e); + } + + HTTPMethod method = HTTPMethod.valueOf(apache_request.getRequestLine().getMethod()); + _appengine_hrequest = new HTTPRequest(request_url, method, allowTruncate() + .doNotFollowRedirects()); + + Header[] apache_headers = apache_request.getAllHeaders(); + for (int i = 0; i < apache_headers.length; i++) { + Header h = apache_headers[i]; + _appengine_hrequest + .setHeader(new HTTPHeader(h.getName(), h.getValue())); + } + } + + // HttpConnection methods + + public void close() { + return; + } + + public HttpConnectionMetrics getMetrics() { + return null; + } + + public int getSocketTimeout() { + return -1; + } + + public boolean isOpen() { + return true; + } + + public boolean isStale() { + return false; + } + + public void setSocketTimeout(int timeout) { + return; + } + + public void shutdown() { + return; + } + + // HttpInetConnection methods + + public InetAddress getLocalAddress() { + return null; + } + + public int getLocalPort() { + return -1; + } + + public InetAddress getRemoteAddress() { + return null; + } + + public int getRemotePort() { + return -1; + } +} \ No newline at end of file diff --git a/appengine/src/com/metaweb/gridworks/appengine/AppEngineClientConnectionManager.java b/appengine/src/com/metaweb/gridworks/appengine/AppEngineClientConnectionManager.java new file mode 100644 index 000000000..9bbc1e9f4 --- /dev/null +++ b/appengine/src/com/metaweb/gridworks/appengine/AppEngineClientConnectionManager.java @@ -0,0 +1,83 @@ +package com.metaweb.gridworks.appengine; + +import java.net.InetAddress; +import java.net.Socket; +import java.util.concurrent.TimeUnit; + +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.ClientConnectionRequest; +import org.apache.http.conn.ManagedClientConnection; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.scheme.SocketFactory; +import org.apache.http.params.HttpParams; + +public class AppEngineClientConnectionManager implements ClientConnectionManager { + private SchemeRegistry schemes; + + class NoopSocketFactory implements SocketFactory { + public Socket connectSocket(Socket sock, String host, int port, + InetAddress addr, int lport, + HttpParams params) { + return null; + } + + public Socket createSocket() { + return null; + } + + public boolean isSecure(Socket sock) { + return false; + } + } + + public AppEngineClientConnectionManager() { + SocketFactory noop_sf = new NoopSocketFactory(); + + schemes = new SchemeRegistry(); + schemes.register(new Scheme("http", noop_sf, 80)); + schemes.register(new Scheme("https", noop_sf, 443)); + } + + public void closeExpiredConnections() { + return; + } + + public void closeIdleConnections(long idletime, TimeUnit tunit) { + return; + } + + public ManagedClientConnection getConnection(HttpRoute route, Object state) { + return new AppEngineClientConnection(route, state); + } + + public SchemeRegistry getSchemeRegistry() { + return schemes; + } + + public void releaseConnection(ManagedClientConnection conn, + long valid, TimeUnit tuint) { + return; + } + + public ClientConnectionRequest requestConnection(final HttpRoute route, + final Object state) { + return new ClientConnectionRequest() { + public void abortRequest() { + return; + } + + public ManagedClientConnection getConnection(long idletime, + TimeUnit tunit) { + + return AppEngineClientConnectionManager.this.getConnection(route, state); + } + }; + } + + public void shutdown() { + return; + } +} +