http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/oauth/impl/OAuthServiceImpl.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/oauth/impl/OAuthServiceImpl.java b/wave/src/main/java/com/google/wave/api/oauth/impl/OAuthServiceImpl.java deleted file mode 100644 index 8375733..0000000 --- a/wave/src/main/java/com/google/wave/api/oauth/impl/OAuthServiceImpl.java +++ /dev/null @@ -1,318 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.oauth.impl; - -import com.google.wave.api.Wavelet; -import com.google.wave.api.oauth.LoginFormHandler; -import com.google.wave.api.oauth.OAuthService; - -import net.oauth.OAuth; -import net.oauth.OAuthAccessor; -import net.oauth.OAuthConsumer; -import net.oauth.OAuthException; -import net.oauth.OAuthMessage; -import net.oauth.OAuthServiceProvider; -import net.oauth.client.OAuthClient; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Map; -import java.util.logging.Logger; - -import javax.jdo.JDOObjectNotFoundException; -import javax.jdo.PersistenceManager; -import javax.jdo.PersistenceManagerFactory; - -/** - * Implements the OAuthService interface. {@link OAuthService} - * - * @author [email protected] (Kimberly White) - * @author [email protected] (Elizabeth Ford) - */ -public class OAuthServiceImpl implements OAuthService { - - /** Writes application logs. */ - private static final Logger LOG = Logger.getLogger(OAuthServiceImpl.class.getName()); - - /** Key for OAuth request token query parameter. */ - private static final String TOKEN_KEY = "oauth_token"; - - /** Key for OAuth callback url query parameter. */ - private static final String CALLBACK_KEY = "oauth_callback"; - - /** Key to force user to enter credentials. */ - private static final String FORCE_LOGIN_KEY = "force_login"; - - /** Key for HTTP GET method. */ - private static final String GET = "GET"; - - /** Key for HTTP POST method. */ - private static final String POST = "POST"; - - /** Key for Datastore object. Consists of wave creator id and wave id. */ - private final String userRecordKey; - - /** OpenAuth client used to negotiate request/access tokens. */ - private final OAuthClient oauthClient; - - /** OpenAuth accessor that stores request/access/secret tokens. */ - private final OAuthAccessor accessor; - - /** Persistence Manager Factory to retrieve and store Datastore objects. */ - private final PersistenceManagerFactory pmf; - - /** - * Factory method. Initializes OAuthServiceProvider with necessary tokens and - * urls. - * - * @param userRecordKey key consisting of user id and wave id. - * @param consumerKey service provider OAuth consumer key. - * @param consumerSecret service provider OAuth consumer secret. - * @param requestTokenUrl url to get service provider request token. - * @param authorizeUrl url to service provider authorize page. - * @param callbackUrl url to callback page. - * @param accessTokenUrl url to get service provider access token. - * @return OAuthService instance. - */ - public static OAuthService newInstance(String userRecordKey, String consumerKey, - String consumerSecret, String requestTokenUrl, String authorizeUrl, String callbackUrl, - String accessTokenUrl) { - OAuthServiceProvider provider = - new OAuthServiceProvider(requestTokenUrl, authorizeUrl, accessTokenUrl); - OAuthConsumer consumer = new OAuthConsumer(callbackUrl, consumerKey, consumerSecret, provider); - OAuthAccessor accessor = new OAuthAccessor(consumer); - OAuthClient client = new OAuthClient(new OpenSocialHttpClient()); - PersistenceManagerFactory pmf = SingletonPersistenceManagerFactory.get(); - return new OAuthServiceImpl(accessor, client, pmf, userRecordKey); - } - - /** - * Initializes necessary OAuthClient and accessor objects for OAuth handling. - * - * @param accessor Used to store tokesn for OAuth authorization. - * @param client Handles OAuth authorization. - * @param pmf Manages datastore fetching and storing. - * @param recordKey User id for datastore object. - */ - OAuthServiceImpl(OAuthAccessor accessor, OAuthClient client, - PersistenceManagerFactory pmf, String recordKey) { - this.userRecordKey = recordKey; - this.pmf = pmf; - this.accessor = accessor; - this.oauthClient = client; - } - - @Override - public boolean checkAuthorization(Wavelet wavelet, LoginFormHandler loginForm) { - - OAuthUser user = retrieveUserProfile(); - - // Return true if the user already has an access token. - if (user != null && user.getAccessToken() != null) { - return true; - } - - // If the user doesn't have an access token but already has a request token, - // exchange the tokens. - if (user != null && user.getRequestToken() != null) { - String accessToken = exchangeTokens(user); - if (accessToken != null) { - // Yay, we're authorized. - return true; - } - } - - // Need to login. - String requestToken = getAndStoreRequestToken(); - LOG.info("Request token: " + requestToken); - buildAuthUrl(); - loginForm.renderLogin(userRecordKey, wavelet); - return false; - } - - @Override - public boolean hasAuthorization() { - OAuthUser user = retrieveUserProfile(); - return (user != null && user.getAccessToken() != null); - } - - /** - * Applies for a request token from the service provider. - * - * @return the request token. - */ - private String getAndStoreRequestToken() { - // Get the request token. - try { - oauthClient.getRequestToken(accessor); - } catch (IOException e) { - LOG.severe("Could not reach service provider to get request token: " + e); - } catch (OAuthException e) { - LOG.severe("Unable to fetch request token. Authentication error: " + e); - } catch (URISyntaxException e) { - LOG.severe("Unable to fetch request token. Invalid url: " + e); - } - - // Store request token in Datastore via a tokenData object. - String requestToken = accessor.requestToken; - storeUserProfile(new OAuthUser(userRecordKey, requestToken)); - - return accessor.requestToken; - } - - /** - * Builds the url to authenticate the request token with necessary query - * parameters and stores in Datastore. - */ - private void buildAuthUrl() { - OAuthUser userProfile = retrieveUserProfile(); - OpenSocialUrl url = new OpenSocialUrl(accessor.consumer.serviceProvider.userAuthorizationURL); - url.addQueryStringParameter(TOKEN_KEY, userProfile.getRequestToken()); - url.addQueryStringParameter(CALLBACK_KEY, accessor.consumer.callbackURL); - url.addQueryStringParameter(FORCE_LOGIN_KEY, "true"); - userProfile.setAuthUrl(url.toString()); - storeUserProfile(userProfile); - } - - /** - * Exchanges a signed request token for an access token from the service - * provider and stores it in the user profile if access token is successfully - * acquired. - * - * @return String of the access token, might return null if failed. - */ - private String exchangeTokens(OAuthUser userProfile) { - // Re-initialize an accessor with the request token and secret token. - // Request token needs to be in access token field for exchange to work. - accessor.accessToken = userProfile.getRequestToken(); - accessor.tokenSecret = accessor.consumer.consumerSecret; - - // Perform the exchange. - String accessToken = null; - String tokenSecret = null; - try { - OAuthMessage message = - oauthClient.invoke(accessor, GET, accessor.consumer.serviceProvider.accessTokenURL, null); - accessToken = message.getToken(); - tokenSecret = message.getParameter(OAuth.OAUTH_TOKEN_SECRET); - } catch (IOException e) { - LOG.warning("Failed to retrieve access token: " + e.getMessage()); - } catch (OAuthException e) { - LOG.warning("Failed to retrieve access token: " + e.getMessage()); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - - if (accessToken != null) { - // Store the access token in the user profile object and put profile back - // in the datastore. - userProfile.setAccessToken(accessToken); - userProfile.setTokenSecret(tokenSecret); - storeUserProfile(userProfile); - } - return accessToken; - } - - @Override - public String post(String url, Map<String, String> parameters) throws OAuthServiceException { - return requestResources(url, POST, parameters); - } - - @Override - public String get(String url, Map<String, String> parameters) throws OAuthServiceException { - return requestResources(url, GET, parameters); - } - - /** - * Get secure resources from the service provider. - * - * @param url service provider resource url. - * @param method Http method. - * @param parameters service provider parameters. - * @return String of the service provider response message. - * @throws OAuthServiceException the HTTP response code was not OK - */ - private String requestResources(String url, String method, Map<String, String> parameters) - throws OAuthServiceException { - - // Convert parameters to OAuth parameters. - Collection<OAuth.Parameter> queryParameters = new ArrayList<OAuth.Parameter>(); - for (Map.Entry<String, String> parameter : parameters.entrySet()) { - queryParameters.add(new OAuth.Parameter(parameter.getKey(), parameter.getValue())); - } - - // Set the accessor's access token with the access token in Datastore. - OAuthUser userProfile = retrieveUserProfile(); - accessor.accessToken = userProfile.getAccessToken(); - accessor.tokenSecret = userProfile.getTokenSecret(); - - // Send request and receive response from service provider. - String messageString = ""; - OAuthMessage message; - try { - message = oauthClient.invoke(accessor, method, url, queryParameters); - messageString = message.readBodyAsString(); - } catch (IOException e) { - LOG.severe("Response message has no body: " + e); - throw new OAuthServiceException(e); - } catch (URISyntaxException e) { - LOG.severe("Unable to fetch resources. Invalid url: " + e); - throw new OAuthServiceException(e); - } catch (OAuthException e){ - throw new OAuthServiceException(e); - } - return messageString; - } - - /** - * Stores user-specific oauth token information in Datastore. - * - * @param user profile consisting of user's request token, access token, and - * consumer secret. - */ - private void storeUserProfile(OAuthUser user) { - PersistenceManager pm = pmf.getPersistenceManager(); - try { - pm.makePersistent(user); - } finally { - pm.close(); - } - } - - /** - * Retrieves user's oauth information from Datastore. - * - * @return the user profile (or null if not found). - */ - private OAuthUser retrieveUserProfile() { - PersistenceManager pm = pmf.getPersistenceManager(); - OAuthUser userProfile = null; - try { - userProfile = pm.getObjectById(OAuthUser.class, userRecordKey); - } catch (JDOObjectNotFoundException e) { - LOG.info("Datastore object not yet initialized with key: " + userRecordKey); - } finally { - pm.close(); - } - return userProfile; - } -}
http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/oauth/impl/OAuthUser.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/oauth/impl/OAuthUser.java b/wave/src/main/java/com/google/wave/api/oauth/impl/OAuthUser.java deleted file mode 100644 index 39f0fff..0000000 --- a/wave/src/main/java/com/google/wave/api/oauth/impl/OAuthUser.java +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.oauth.impl; - -import javax.jdo.annotations.IdentityType; -import javax.jdo.annotations.PersistenceCapable; -import javax.jdo.annotations.Persistent; -import javax.jdo.annotations.PrimaryKey; - -/** - * Objects of this class are stored in Datastore to persist an association - * between user's wave id + wave id, the user's access token, - * and the service consumer secret. - * Holds the request token for later retrieval to exchange it for the access token. - * 'Detachable' attribute allows object to be altered even after - * its Persistence Manager is closed. - * - * @author [email protected] (Kimberly White) - */ -@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true") -public class OAuthUser { - - /** - * Datastore key. Consists of the user's wave id and the wave id the robot - * resides on. - */ - @SuppressWarnings("unused") - @PrimaryKey - @Persistent - private String nameKey; - - /** OAuth access token. */ - @Persistent - private String accessToken = null; - - /** OAuth request token. */ - @Persistent - private String requestToken; - - /** - * OAuth authorize url. - * By default passed to gadget to open pop-up window. - */ - @Persistent - private String authUrl = null; - - /** The token secret used to sign requests. */ - @Persistent - private String tokenSecret = null; - - /** - * Creates a new profile with the user id and OAuth request token. - * - * @param userId wave creator's id and wave id. - * @param requestToken the OAuth request token. - */ - public OAuthUser(String userId, String requestToken) { - this.nameKey = userId; - this.requestToken = requestToken; - } - - /** - * Adds the user's access token to the OAuth profile. - * - * @param accessToken the OAuth access token. - */ - public void setAccessToken(String accessToken) { - this.accessToken = accessToken; - } - - /** - * Returns the access token. - * - * @return the access token. - */ - public String getAccessToken() { - return accessToken; - } - - /** - * Returns the request token. - * - * @return the request token. - */ - public String getRequestToken() { - return requestToken; - } - - /** - * Sets the authorize url. - * - * @param authUrl the url to the service provider authorize page. - */ - public void setAuthUrl(String authUrl) { - this.authUrl = authUrl; - } - - /** - * Returns the authorize url. - * - * @return the url to the service provider authorize page. - */ - public String getAuthUrl() { - return authUrl; - } - - /** - * Sets the oauth_token_secret parameter. - * - * @param tokenSecret Token used to sign requests for protected resources. - */ - public void setTokenSecret(String tokenSecret) { - this.tokenSecret = tokenSecret; - } - - /** - * Returns the oauth_token_secret parameter. - * - * @return the oauth_token_secret parameter - */ - public String getTokenSecret() { - return tokenSecret; - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/oauth/impl/OpenSocialHttpClient.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/oauth/impl/OpenSocialHttpClient.java b/wave/src/main/java/com/google/wave/api/oauth/impl/OpenSocialHttpClient.java deleted file mode 100644 index 93154df..0000000 --- a/wave/src/main/java/com/google/wave/api/oauth/impl/OpenSocialHttpClient.java +++ /dev/null @@ -1,183 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.oauth.impl; - -import net.oauth.http.HttpMessage; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Map; - - -/** - * A small implementation of HttpClient to serve the needs of the OAuth library - * rather than requiring org.apache.http.client as a dependency. - * - * @author [email protected] (Dan Holevoet) - * @author [email protected] (David Byttow) - */ -public class OpenSocialHttpClient implements net.oauth.http.HttpClient { - - /** Size of data stream buffer. */ - private static final int BUF_SIZE = 0x1000; // 4K - - /** - * Executes the request, sending the request body if applicable. - * - * @param request - * @return Response message - * @throws IOException - */ - @Override - public OpenSocialHttpResponseMessage execute(HttpMessage request, - Map<String,Object> parameters) throws IOException { - - // If a POST message, translates the body into a string. - String body = null; - if (request.getBody() != null) { - body = new String(toByteArray(request.getBody())); - } - - OpenSocialHttpMessage openSocialRequest = new OpenSocialHttpMessage( - request.method, new OpenSocialUrl(request.url.toExternalForm()), body); - return execute(openSocialRequest); - } - - /** - * Executes the request, sending the request body if applicable. - * - * @param request - * @return Response message - * @throws IOException - */ - private OpenSocialHttpResponseMessage execute(OpenSocialHttpMessage request) - throws IOException { - final String method = request.method; - final boolean isPut = PUT.equalsIgnoreCase(method); - final boolean isPost = POST.equalsIgnoreCase(method); - final boolean isDelete = DELETE.equalsIgnoreCase(method); - - final String bodyString = request.getBodyString(); - final String contentType = request.getHeader(HttpMessage.CONTENT_TYPE); - final OpenSocialUrl url = request.getUrl(); - - OpenSocialHttpResponseMessage response = null; - if (isPut) { - response = send("PUT", url, contentType, bodyString); - } else if (isPost) { - response = send("POST", url, contentType, bodyString); - } else if (isDelete) { - response = send("DELETE", url, contentType); - } else { - response = send("GET", url, contentType); - } - - return response; - } - - /** - * Executes a request without writing any data in the request's body. - * - * @param method - * @param url - * @return Response message - */ - private OpenSocialHttpResponseMessage send(String method, OpenSocialUrl url, - String contentType) throws IOException { - return send(method, url, contentType, null); - } - - /** - * Executes a request and writes all data in the request's body to the - * output stream. - * - * @param method - * @param url - * @param body - * @return Response message - */ - private OpenSocialHttpResponseMessage send(String method, OpenSocialUrl url, - String contentType, String body) throws IOException { - HttpURLConnection connection = null; - try { - connection = getConnection(method, url, contentType); - if (body != null) { - OutputStreamWriter out = - new OutputStreamWriter(connection.getOutputStream()); - out.write(body); - out.flush(); - out.close(); - } - - return new OpenSocialHttpResponseMessage(method, url, - connection.getInputStream(), connection.getResponseCode()); - } catch (IOException e) { - throw new IOException("Container returned status " + - connection.getResponseCode() + " \"" + e.getMessage() + "\""); - } - } - - /** - * Opens a new HTTP connection for the URL associated with this object. - * - * @param method - * @param url - * @return Opened connection - * @throws IOException if URL is invalid, or unsupported - */ - private HttpURLConnection getConnection(String method, OpenSocialUrl url, - String contentType) throws IOException { - HttpURLConnection connection = - (HttpURLConnection) new URL(url.toString()).openConnection(); - if (contentType != null && !contentType.equals("")) { - connection.setRequestProperty(HttpMessage.CONTENT_TYPE, contentType); - } - connection.setRequestMethod(method); - connection.setDoOutput(true); - connection.connect(); - - return connection; - } - - private static long copy(InputStream from, OutputStream to) throws IOException { - byte[] buf = new byte[BUF_SIZE]; - long total = 0; - while (true) { - int r = from.read(buf); - if (r == -1) { - break; - } - to.write(buf, 0, r); - total += r; - } - return total; - } - - private static byte[] toByteArray(InputStream in) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - copy(in, out); - return out.toByteArray(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/oauth/impl/OpenSocialHttpMessage.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/oauth/impl/OpenSocialHttpMessage.java b/wave/src/main/java/com/google/wave/api/oauth/impl/OpenSocialHttpMessage.java deleted file mode 100644 index ec90fe6..0000000 --- a/wave/src/main/java/com/google/wave/api/oauth/impl/OpenSocialHttpMessage.java +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.oauth.impl; - -import net.oauth.http.HttpMessage; - -import java.util.HashMap; -import java.util.Map; - -/** - * A simple extension of net.oauth.http.HttpMessage using an OpenSocialUrl - * instead of java.net.URL and encoding the body as a String instead of an - * InputStream. - * - * @author [email protected] (Jason Cooper) - */ -class OpenSocialHttpMessage extends HttpMessage { - - protected String body; - protected OpenSocialUrl url; - - public OpenSocialHttpMessage(String method, OpenSocialUrl url) { - this(method, url, null); - } - - public OpenSocialHttpMessage(String method, OpenSocialUrl url, String body) { - this.method = method; - this.body = body; - this.url = url; - } - - public OpenSocialUrl getUrl() { - return url; - } - - public String getBodyString() { - return body; - } - - public void addHeader(String headerName, String value) { - Map<String, String> messageHeaders = new HashMap<String, String>(); - messageHeaders.put(headerName, value); - - for (Map.Entry<String, String> entry : messageHeaders.entrySet()) { - this.headers.add(entry); - } - } - - public void addHeaders(Map<String, String> messageHeaders) { - for (Map.Entry<String, String> entry : messageHeaders.entrySet()) { - this.headers.add(entry); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/oauth/impl/OpenSocialHttpResponseMessage.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/oauth/impl/OpenSocialHttpResponseMessage.java b/wave/src/main/java/com/google/wave/api/oauth/impl/OpenSocialHttpResponseMessage.java deleted file mode 100644 index 422784c..0000000 --- a/wave/src/main/java/com/google/wave/api/oauth/impl/OpenSocialHttpResponseMessage.java +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.oauth.impl; - -import net.oauth.http.HttpResponseMessage; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -/** - * A small implementation of an HttpResponseMessage that does not require - * org.apache.http.client as a dependency. - * - * @author [email protected] (Dan Holevoet) - * @author [email protected] (Jason Cooper) - */ -class OpenSocialHttpResponseMessage extends HttpResponseMessage { - - protected int status; - - protected OpenSocialHttpResponseMessage(String method, OpenSocialUrl url, - InputStream responseStream, int status) throws IOException { - super(method, url.toURL()); - - this.body = responseStream; - this.status = status; - } - - /** - * Returns the status code for the response. - * - * @return Status code - */ - @Override - public int getStatusCode() { - return this.status; - } - - /** - * Transforms response output contained in the InputStream object returned by - * the connection into a string representation which can later be parsed into - * a more meaningful object, e.g. OpenSocialPerson. - * - * @return Response body as a String - * @throws IOException if the InputStream is not retrievable or accessible - */ - public String getBodyString() throws IOException { - if (body != null) { - StringBuilder sb = new StringBuilder(); - BufferedReader reader = new BufferedReader( - new InputStreamReader(body)); - - String line = null; - while ((line = reader.readLine()) != null) { - sb.append(line); - } - - body.close(); - - return sb.toString(); - } - - return null; - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/oauth/impl/OpenSocialUrl.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/oauth/impl/OpenSocialUrl.java b/wave/src/main/java/com/google/wave/api/oauth/impl/OpenSocialUrl.java deleted file mode 100644 index 5debc9f..0000000 --- a/wave/src/main/java/com/google/wave/api/oauth/impl/OpenSocialUrl.java +++ /dev/null @@ -1,111 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.oauth.impl; - -import java.io.UnsupportedEncodingException; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLEncoder; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Vector; - -/** - * An object which represents a simple URL. Once an object is instantiated, - * path components and parameters can be added. Once all of the elements - * are in place, the object can be serialized into a string. This class - * is used by internal classes and not by clients directly. - * - * @author [email protected] (Jason Cooper) - */ -public class OpenSocialUrl { - - private final String base; - private final List<String> components; - private final Map<String, String> queryStringParameters; - - public OpenSocialUrl(String base) { - this.base = base; - this.components = new Vector<String>(); - this.queryStringParameters = new HashMap<String, String>(); - } - - /** - * Adds passed String to the path component queue. - * - * @param component Path component to add - */ - public void addPathComponent(String component) { - components.add(component); - } - - /** - * Creates a new entry in queryStringParameters Map with the passed key and - * value; used for adding URL parameters such as oauth_signature and the - * various other OAuth parameters that are required in order to submit a - * signed request. - * - * @param key Parameter name - * @param value Parameter value - */ - public void addQueryStringParameter(String key, String value) { - try { - queryStringParameters.put(URLEncoder.encode(key, "UTF-8"), - URLEncoder.encode(value, "UTF-8")); - } catch (UnsupportedEncodingException e) { - // "UTF-8" is a supported encoding so this exception should never be - // thrown - } - } - - /** - * Returns a String representing the serialized URL including the base - * followed by any path components added to the path component queue - * and, last but not least, appending any query string parameters as - * name-value pairs after the full path. - */ - @Override - public String toString() { - StringBuilder s = new StringBuilder(this.base); - - for (String pathComponent : this.components) { - if (s.charAt(s.length() - 1) != '/') { - s.append("/"); - } - s.append(pathComponent); - } - - char connector = '?'; - for (Map.Entry<String, String> e : this.queryStringParameters.entrySet()) { - s.append(connector); - s.append(e.getKey()); - s.append('='); - s.append(e.getValue()); - connector = '&'; - } - - return s.toString(); - } - - public URL toURL() throws MalformedURLException { - return new URL(this.toString()); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/oauth/impl/PopupLoginFormHandler.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/oauth/impl/PopupLoginFormHandler.java b/wave/src/main/java/com/google/wave/api/oauth/impl/PopupLoginFormHandler.java deleted file mode 100644 index 886555b..0000000 --- a/wave/src/main/java/com/google/wave/api/oauth/impl/PopupLoginFormHandler.java +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.oauth.impl; - -import com.google.wave.api.Gadget; -import com.google.wave.api.Wavelet; -import com.google.wave.api.oauth.LoginFormHandler; - -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.logging.Logger; - -/** - * Adds a gadget that automatically opens a new browser window directed - * to the service provider authorization url. - * - * @author [email protected] (Elizabeth Ford) - * @author [email protected] (Kimberly White) - */ -public class PopupLoginFormHandler implements LoginFormHandler { - - private static final Logger LOG = Logger.getLogger(SimpleLoginFormHandler.class.getName()); - - /** The URL of the gadget we add to handle the popup. */ - private static final String GADGET_PATH = "/popup.xml"; - - //TODO: Have this be passed in by TweetyServlet. - /** Character encoding used to encode query params. */ - private static final String CHARACTER_ENCODING = "UTF-8"; - - /** Robot address. */ - private final String remoteHost; - - /** - * Constructor - * - * @param remoteHost The robot address. - */ - public PopupLoginFormHandler(String remoteHost) { - this.remoteHost = remoteHost; - } - - @Override - public void renderLogin(String userRecordKey, Wavelet wavelet) { - // Clear login form. - wavelet.getRootBlip().all().delete(); - - // TODO (elizabethford): Eventually have buildUrl from within gadget with gadget fetching - // request key from datastore. - // Add the gadget. - String gadgetString = ""; - try { - String gadgetUrl = "http://" + remoteHost + GADGET_PATH; - gadgetString = gadgetUrl + "?" + URLEncoder.encode("key", CHARACTER_ENCODING) + "=" - + URLEncoder.encode(userRecordKey, CHARACTER_ENCODING); - } catch (UnsupportedEncodingException e) { - LOG.warning(e.toString()); - } - Gadget gadget = new Gadget(gadgetString); - LOG.info(gadgetString); - wavelet.getRootBlip().append(gadget); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/oauth/impl/SimpleLoginFormHandler.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/oauth/impl/SimpleLoginFormHandler.java b/wave/src/main/java/com/google/wave/api/oauth/impl/SimpleLoginFormHandler.java deleted file mode 100644 index e5aebc0..0000000 --- a/wave/src/main/java/com/google/wave/api/oauth/impl/SimpleLoginFormHandler.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.oauth.impl; - -import com.google.wave.api.ElementType; -import com.google.wave.api.FormElement; -import com.google.wave.api.Wavelet; -import com.google.wave.api.event.Event; -import com.google.wave.api.event.EventType; -import com.google.wave.api.event.FormButtonClickedEvent; -import com.google.wave.api.oauth.LoginFormHandler; - -import java.util.List; -import java.util.logging.Logger; - -import javax.jdo.JDOObjectNotFoundException; -import javax.jdo.PersistenceManager; - -/** - * Generates a login form in Wavelet to direct user to OAuth service login. - * Includes a link to the service provider authorization page that opens the - * page in a new window. - * - * @author [email protected] (Elizabeth Ford) - * @author [email protected] (Kimberly White) - */ -public class SimpleLoginFormHandler implements LoginFormHandler { - - private static final Logger LOG = Logger.getLogger(SimpleLoginFormHandler.class.getName()); - - /** The key of a link annotation. */ - private static final String LINK_ANNOTATION_KEY = "link/manual"; - - /** Text for the link to the authorization page. */ - private static final String LOGIN_LINK_TEXT = "Authorization Required"; - - /** The caption of the button element in the table of contents wave. */ - private static final String LOGIN_BUTTON_CAPTION = "Continue"; - - /** The id of the button element. */ - private static final String LOGIN_BUTTON_ID = "successButton"; - - @Override - public void renderLogin(String userRecordKey, Wavelet wavelet) { - // Clear login form. - wavelet.getRootBlip().all().delete(); - - PersistenceManager pm = SingletonPersistenceManagerFactory.get().getPersistenceManager(); - OAuthUser userProfile = null; - try { - userProfile = pm.getObjectById(OAuthUser.class, userRecordKey); - } catch (JDOObjectNotFoundException objectNotFound) { - LOG.severe("Error fetching object from datastore with key: " + userRecordKey); - } finally { - pm.close(); - } - String url = userProfile.getAuthUrl(); - - // Add authentication prompt and insert link to service provider log-in page - // to wavelet. - wavelet.getRootBlip().all().delete(); - StringBuilder b = new StringBuilder(); - b.append("\n"); - int startIndex = b.length(); - b.append(LOGIN_LINK_TEXT + "\n\n"); - wavelet.getRootBlip().append(b.toString()); - - // Add button to click when authentication is complete. - wavelet.getRootBlip().append(new FormElement(ElementType.BUTTON, LOGIN_BUTTON_ID, - LOGIN_BUTTON_CAPTION)); - - // Linkify the authorization link. - wavelet.getRootBlip().range(startIndex, startIndex + LOGIN_LINK_TEXT.length()).annotate( - LINK_ANNOTATION_KEY, url); - } - - /** - * Checks whether a button in a blip was clicked or not. This method will - * reset the state of the button to be "unclicked" at the end of the method - * call. - * - * @param events A list of events received from Google Wave that needs to be - * checked whether it contains form button clicked event or not. - * @return true If the user just clicked on the button. - */ - public boolean isButtonClicked(List<Event> events) { - for (Event event : events) { - if (event.getType() == EventType.FORM_BUTTON_CLICKED - && LOGIN_BUTTON_ID.equals(FormButtonClickedEvent.as(event).getButtonName())) { - return true; - } - } - return false; - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/oauth/impl/SingletonPersistenceManagerFactory.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/oauth/impl/SingletonPersistenceManagerFactory.java b/wave/src/main/java/com/google/wave/api/oauth/impl/SingletonPersistenceManagerFactory.java deleted file mode 100644 index bc897be..0000000 --- a/wave/src/main/java/com/google/wave/api/oauth/impl/SingletonPersistenceManagerFactory.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.oauth.impl; - -import javax.jdo.JDOHelper; -import javax.jdo.PersistenceManagerFactory; - -/** - * PersistenceManagerFactory singleton wrapper class. - * Allows a single instance of PersistenceManagerFactory to save from costly - * initializations. - * - * @author [email protected] (Kimberly White) - */ -public final class SingletonPersistenceManagerFactory { - private static final PersistenceManagerFactory pmfInstance = - JDOHelper.getPersistenceManagerFactory("transactions-optional"); - - /** PMF constructor. */ - private SingletonPersistenceManagerFactory() {} - - /** - * Allows app to reuse a single instance of a PersistenceManagerFactory. - * - * @return instance of persistence manager. - */ - public static PersistenceManagerFactory get() { - return pmfInstance; - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/robot/Capability.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/robot/Capability.java b/wave/src/main/java/com/google/wave/api/robot/Capability.java deleted file mode 100644 index aad22f9..0000000 --- a/wave/src/main/java/com/google/wave/api/robot/Capability.java +++ /dev/null @@ -1,171 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.robot; - -import com.google.common.collect.ImmutableList; -import com.google.common.base.Preconditions; -import com.google.wave.api.Context; -import com.google.wave.api.event.EventType; - -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * A Capability represents a Robot's interest in handling a given event. The - * Robot can request that additional context and document content be sent with - * the event. - * - */ -public class Capability { - - /** - * The context provided by default if non is declared. - */ - public static final List<Context> DEFAULT_CONTEXT = - ImmutableList.of(Context.ROOT, Context.PARENT, Context.CHILDREN); - - /** - * The list of contexts (parent, children, siblings, all) to send to the Robot - * for this capability. - */ - private final List<Context> contexts; - - /** - * The associated eventType. - */ - private EventType eventType; - - /** - * The filter applicable to this event as a regular expression. - */ - private final Pattern filter; - - /** - * Configures a Robot capability with the content, contexts and filter - * specified. - */ - public Capability(EventType eventType, List<Context> contexts, String filter) { - Preconditions.checkNotNull(contexts); - Preconditions.checkNotNull(filter); - this.contexts = ImmutableList.copyOf(contexts); - this.eventType = eventType; - if (filter.isEmpty()) { - this.filter = null; - } else { - this.filter = Pattern.compile(filter); - } - } - - /** - * Convenience constructor with default empty filter. - */ - public Capability(EventType eventType, List<Context> contexts) { - this(eventType, contexts, ""); - } - - /** - * Convenience constructor with default empty filter and default context. - */ - public Capability(EventType eventType) { - this(eventType, DEFAULT_CONTEXT, ""); - } - - /** - * @return the list of contexts requested to be sent for this capability. - */ - public List<Context> getContexts() { - return contexts; - } - - public EventType getEventType() { - return eventType; - } - - /** - * @return whether the set filter matches toMatch - */ - public boolean matches(String toMatch) { - if (filter == null) { - return true; - } else { - Matcher matcher = filter.matcher(toMatch); - return matcher.find(); - } - } - - /** - * @return the filter pattern - */ - public String getFilter() { - if (filter != null) { - return filter.pattern(); - } else { - return ""; - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((contexts == null) ? 0 : contexts.hashCode()); - result = prime * result + ((eventType == null) ? 0 : eventType.hashCode()); - result = prime * result + ((filter == null) ? 0 : filter.pattern().hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof Capability)) { - return false; - } - Capability other = (Capability) obj; - if (contexts == null) { - if (other.contexts != null) { - return false; - } - } else if (!contexts.equals(other.contexts)) { - return false; - } - if (eventType == null) { - if (other.eventType != null) { - return false; - } - } else if (!eventType.equals(other.eventType)) { - return false; - } - if (filter == null) { - if (other.filter != null) { - return false; - } - } else if (!filter.pattern().equals(other.filter.pattern())) { - return false; - } - return true; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/robot/CapabilityFetchException.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/robot/CapabilityFetchException.java b/wave/src/main/java/com/google/wave/api/robot/CapabilityFetchException.java deleted file mode 100644 index ca437df..0000000 --- a/wave/src/main/java/com/google/wave/api/robot/CapabilityFetchException.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.robot; - -/** - * Exception thrown when retrieving robot capabilities. - * - */ -public class CapabilityFetchException extends Exception { - - public final int httpStatus; - /** - * Constructs a new exception with the given detail message. - */ - public CapabilityFetchException(String message) { - super(message); - httpStatus = 0; - } - - /** - * Constructs a new exception with the given cause. - */ - public CapabilityFetchException(Throwable cause) { - super(cause); - httpStatus = 0; - } - - /** - * Constructs a new exception with the given detail message and cause. - */ - public CapabilityFetchException(String message, Throwable cause) { - super(message, cause); - httpStatus = 0; - } - - public CapabilityFetchException(String message, int status) { - super(message); - httpStatus = status; - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/robot/HttpRobotConnection.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/robot/HttpRobotConnection.java b/wave/src/main/java/com/google/wave/api/robot/HttpRobotConnection.java deleted file mode 100644 index 706f6fe..0000000 --- a/wave/src/main/java/com/google/wave/api/robot/HttpRobotConnection.java +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.robot; - -import com.google.common.base.Charsets; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.JdkFutureAdapters; -import com.google.common.util.concurrent.ListenableFuture; - -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpMethod; -import org.apache.commons.httpclient.methods.GetMethod; -import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.methods.StringRequestEntity; - -import java.io.IOException; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; - -/** - * A {@link RobotConnection} that uses Apache's {@code HTTP Client} for - * communicating with the robot. - * - */ -public class HttpRobotConnection implements RobotConnection { - - /** A user agent client that can execute HTTP methods. */ - private final HttpClient httpClient; - - /** An executor to submit tasks asynchronously. */ - private final ExecutorService executor; - - /** - * Constructor. - * - * @param client the client for executing HTTP methods. - * @param executor the executor for submitting tasks asynchronously. - */ - public HttpRobotConnection(HttpClient client, ExecutorService executor) { - this.httpClient = client; - this.executor = executor; - } - - @Override - public String get(String url) throws RobotConnectionException { - GetMethod method = new GetMethod(url); - return fetch(url, method); - } - - @Override - public ListenableFuture<String> asyncGet(final String url) { - return JdkFutureAdapters.listenInPoolThread(executor.submit(new Callable<String>() { - @Override - public String call() throws RobotConnectionException { - return get(url); - } - })); - } - - @Override - public String postJson(String url, String body) throws RobotConnectionException { - PostMethod method = new PostMethod(url); - try { - method.setRequestEntity(new StringRequestEntity(body, RobotConnection.JSON_CONTENT_TYPE, - Charsets.UTF_8.name())); - return fetch(url, method); - } catch (IOException e) { - String msg = "Robot fetch http failure: " + url + ": " + e; - throw new RobotConnectionException(msg, e); - } - } - - @Override - public ListenableFuture<String> asyncPostJson(final String url, final String body) { - return JdkFutureAdapters.listenInPoolThread(executor.submit(new Callable<String>() { - @Override - public String call() throws RobotConnectionException { - return postJson(url, body); - } - })); - } - - /** - * Fetches the given URL, given a method ({@code GET} or {@code POST}). - * - * @param url the URL to be fetched. - * @param method the method to fetch the URL, can be {@code GET} or - * {@code POST}. - * @return the content of the URL. - * - * @throws RobotConnectionException if there is a problem fetching the URL, - * for example, if the response code is not HTTP OK (200). - */ - private String fetch(String url, HttpMethod method) throws RobotConnectionException { - try { - int statusCode = httpClient.executeMethod(method); - return RobotConnectionUtil.validateAndReadResponse(url, statusCode, - method.getResponseBodyAsStream()); - } catch (IOException e) { - String msg = "Robot fetch http failure: " + url + "."; - throw new RobotConnectionException(msg, e); - } finally { - method.releaseConnection(); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/robot/RobotCapabilitiesParser.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/robot/RobotCapabilitiesParser.java b/wave/src/main/java/com/google/wave/api/robot/RobotCapabilitiesParser.java deleted file mode 100644 index 09a4b1b..0000000 --- a/wave/src/main/java/com/google/wave/api/robot/RobotCapabilitiesParser.java +++ /dev/null @@ -1,197 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.robot; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.wave.api.Context; -import com.google.wave.api.ProtocolVersion; -import com.google.wave.api.event.EventType; - -import org.jdom.Document; -import org.jdom.Element; -import org.jdom.JDOMException; -import org.jdom.Namespace; -import org.jdom.input.SAXBuilder; - -import java.io.IOException; -import java.io.StringReader; -import java.util.List; -import java.util.Map; - -/** - * RobotCapabilityParser is responsible for parsing Robot's capabilities.xml - * file. - * - */ -public class RobotCapabilitiesParser { - - private static final Namespace XML_NS = - Namespace.getNamespace("w", "http://wave.google.com/extensions/robots/1.0"); - - private static final String CAPABILITIES_TAG = "capabilities"; - private static final String CAPABILITY_TAG = "capability"; - private static final String CAPABILITY_CONTEXT_ATTRIBUTE = "context"; - private static final String CAPABILITY_FILTER_ATTRIBUTE = "filter"; - private static final String CAPABILITY_NAME_ATTRIBUTE = "name"; - - private static final String ROBOT_VERSION_TAG = "version"; - private static final String PROTOCOL_VERSION_TAG = "protocolversion"; - private static final String CONSUMER_KEYS_TAG = "consumer_keys"; - private static final String CONSUMER_KEY_TAG = "consumer_key"; - private static final String CONSUMER_KEY_FOR_ATTRIBUTE = "for"; - - private final String capabilitiesXmlUrl; - - private final Map<EventType, Capability> capabilities; - - private final RobotConnection connection; - - private String capabilitiesHash; - - private ProtocolVersion protocolVersion; - - private String consumerKey; // null if no consumer key - - private final String activeRobotApiUrl; - - public RobotCapabilitiesParser(String capabilitiesXmlUrl, RobotConnection connection, - String activeRobotApiUrl) - throws CapabilityFetchException { - this.capabilitiesXmlUrl = capabilitiesXmlUrl; - this.activeRobotApiUrl = activeRobotApiUrl; - this.capabilities = Maps.newHashMap(); - this.connection = connection; - parseRobotDescriptionXmlFile(); - } - - public Map<EventType, Capability> getCapabilities() { - return capabilities; - } - - public String getCapabilitiesHash() { - return capabilitiesHash; - } - - public ProtocolVersion getProtocolVersion() { - return protocolVersion; - } - - public String getConsumerKey() { - return consumerKey; - } - - private void parseRobotDescriptionXmlFile() throws CapabilityFetchException { - // Fetch the XML file that defines the Robot capabilities. - try { - String xmlContent = connection.get(capabilitiesXmlUrl); - if (xmlContent == null || xmlContent.isEmpty()) { - throw new CapabilityFetchException("Empty capabilities.xml"); - } - StringReader reader = new StringReader(xmlContent); - Document document = new SAXBuilder().build(reader); - - // Parse all "<w:capability>" tags. - List<Element> capabilities = getElements(document, CAPABILITIES_TAG, CAPABILITY_TAG, XML_NS); - for (Element capability : capabilities) { - parseCapabilityTag(capability); - } - - // Always react to SELF_ADDED: - if (!this.capabilities.containsKey(EventType.WAVELET_SELF_ADDED)) { - this.capabilities.put(EventType.WAVELET_SELF_ADDED, - new Capability(EventType.WAVELET_SELF_ADDED, Capability.DEFAULT_CONTEXT)); - } - - // Parse "<w:version>" tag. - Element capabilitiesHashElement = - document.getRootElement().getChild(ROBOT_VERSION_TAG, XML_NS); - if (capabilitiesHashElement != null) { - capabilitiesHash = capabilitiesHashElement.getText(); - } - - // Parse "<w:protocolversion>" tag. - Element protocolVersionElement = - document.getRootElement().getChild(PROTOCOL_VERSION_TAG, XML_NS); - if (protocolVersionElement != null) { - protocolVersion = ProtocolVersion.fromVersionString(protocolVersionElement.getText()); - } else { - // In V1 API, we don't have <w:protocolversion> tag in the - // capabilities.xml file. - protocolVersion = ProtocolVersion.V1; - } - - // Parse "<w:consumer_key>" tag(s). - for (Element consumerKeyElement : getElements(document, CONSUMER_KEYS_TAG, CONSUMER_KEY_TAG, - XML_NS)) { - String forUrl = consumerKeyElement.getAttributeValue(CONSUMER_KEY_FOR_ATTRIBUTE); - if (forUrl != null && forUrl.equals(activeRobotApiUrl)) { - consumerKey = consumerKeyElement.getText(); - } - } - } catch (IOException iox) { - throw new CapabilityFetchException("Failure reading capabilities for: " + capabilitiesXmlUrl, - iox); - } catch (JDOMException jdomx) { - throw new CapabilityFetchException("Failure parsing capabilities for: " + capabilitiesXmlUrl, - jdomx); - } catch (RobotConnectionException e) { - throw new CapabilityFetchException(e); - } - } - - private void parseCapabilityTag(Element capability) { - // Get the event type. - EventType eventType = EventType.valueOfIgnoreCase( - capability.getAttributeValue(CAPABILITY_NAME_ATTRIBUTE)); - if (eventType == EventType.UNKNOWN) { - return; - } - - // Parse comma separated "context" attribute. - List<Context> contexts; - String contextsString = capability.getAttributeValue(CAPABILITY_CONTEXT_ATTRIBUTE); - if (contextsString != null && !contextsString.isEmpty()) { - try { - contexts = Lists.newArrayList(); - for (String context : contextsString.split(",")) { - contexts.add(Context.valueOfIgnoreCase(context)); - } - } catch (IllegalArgumentException e) { - contexts = Capability.DEFAULT_CONTEXT; - } - } else { - contexts = Capability.DEFAULT_CONTEXT; - } - // Parse optional "filter" attribute. - String filter = capability.getAttributeValue(CAPABILITY_FILTER_ATTRIBUTE); - if (filter == null || filter.isEmpty()) { - filter = ""; - } - - this.capabilities.put(eventType, new Capability(eventType, contexts, filter)); - } - - @SuppressWarnings({"cast", "unchecked"}) - private List<Element> getElements(Document doc, String parentTag, String tag, Namespace ns) { - Element parent = doc.getRootElement().getChild(parentTag, ns); - return (List<Element>) (parent == null ? Lists.newArrayList() : parent.getChildren(tag, ns)); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/robot/RobotConnection.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/robot/RobotConnection.java b/wave/src/main/java/com/google/wave/api/robot/RobotConnection.java deleted file mode 100644 index 6d0f561..0000000 --- a/wave/src/main/java/com/google/wave/api/robot/RobotConnection.java +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.robot; - -import com.google.common.util.concurrent.ListenableFuture; - -import java.util.concurrent.Future; - -/** - * Interface for sending messages to robots. This utility supports synchronous - * and asynchronous {@code GET} and {@code POST} methods. - * - */ -public interface RobotConnection { - /** Constant for JSON content type. */ - static final String JSON_CONTENT_TYPE = "application/json; charset=utf-8"; - - /** - * Fetches a robot URL using {@code HTTP GET} method. - * - * @param url the robot's URL. - * @return the content of the URL. - * - * @throws RobotConnectionException if there is a problem fetching the URL, - * for example, if the response code is not HTTP OK (200). - */ - String get(String url) throws RobotConnectionException; - - /** - * Asynchronously fetches a robot URL using {@code HTTP GET} method. - * - * @param url the robot's URL. - * @return a {@link Future} that represents the content of the URL. - * - * @throws RobotConnectionException if there is a problem fetching the URL, - * for example, if the response code is not HTTP OK (200). - */ - ListenableFuture<String> asyncGet(String url) throws RobotConnectionException; - - /** - * Fetches a robot URL using {@code HTTP POST} method. - * - * @param url the robot's URL. - * @param jsonBody the POST body of the request, in JSON. - * @return the content of the URL. - * - * @throws RobotConnectionException if there is a problem fetching the URL, - * for example, if the response code is not HTTP OK (200). - */ - String postJson(String url, String jsonBody) throws RobotConnectionException; - - /** - * Asynchronously fetches a robot URL using {@code HTTP POST} method. - * - * @param url the robot's URL. - * @param jsonBody the POST body of the request, in JSON. - * @return a {@link Future} that represents the content of the URL. - * - * @throws RobotConnectionException if there is a problem fetching the URL, - * for example, if the response code is not HTTP OK (200). - */ - ListenableFuture<String> asyncPostJson(String url, String jsonBody) - throws RobotConnectionException; -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/robot/RobotConnectionException.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/robot/RobotConnectionException.java b/wave/src/main/java/com/google/wave/api/robot/RobotConnectionException.java deleted file mode 100644 index 38bcc2f..0000000 --- a/wave/src/main/java/com/google/wave/api/robot/RobotConnectionException.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.robot; - -/** - * Checked exception when a robot cannot be reached via HTTP. - * - */ -public class RobotConnectionException extends Exception { - - private final int statusCode; - - /** - * Constructor with a detail message. - * - * @param message detail message for this exception. - */ - public RobotConnectionException(String message) { - super(message); - this.statusCode = 0; - } - - /** - * Constructor with a detail message and cause. - * - * @param message detail message for this exception. - * @param cause the exception that caused this. - */ - public RobotConnectionException(String message, Throwable cause) { - super(message, cause); - this.statusCode = 0; - } - - /** - * Constructor with a detail message and status code. - * - * @param message detail message for this exception. - * @param statusCode the status code returned by the robot. - */ - public RobotConnectionException(String message, int statusCode) { - super(message); - this.statusCode = statusCode; - } - - /** @return the status code returned by the robot. */ - public int getStatusCode() { - return statusCode; - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/robot/RobotConnectionUtil.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/robot/RobotConnectionUtil.java b/wave/src/main/java/com/google/wave/api/robot/RobotConnectionUtil.java deleted file mode 100644 index 45965b9..0000000 --- a/wave/src/main/java/com/google/wave/api/robot/RobotConnectionUtil.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.robot; - -import com.google.common.base.Charsets; -import com.google.common.io.ByteStreams; - -import java.io.IOException; -import java.io.InputStream; - -import javax.servlet.http.HttpServletResponse; - -/** - * A helper class that contains utility method to be used by - * {@link RobotConnection}'s subclasses. - * - */ -public class RobotConnectionUtil { - - /** - * Validates and read the response. - * - * @param url the URL where the response was received from. - * @param statusCode the HTTP status code. - * @param response the raw response of fetching the given URL. - * @return the response, as {@link String}. - * - * @throws RobotConnectionException if the response code is not HTTP OK (200). - */ - public static String validateAndReadResponse(String url, int statusCode, byte[] response) - throws RobotConnectionException { - if (statusCode != HttpServletResponse.SC_OK) { - String msg = "Robot fetch http failure: " + url + ": " + statusCode; - throw new RobotConnectionException(msg, statusCode); - } - - // Read the response. - return new String(response, Charsets.UTF_8); - } - - /** - * Validates and read the response. - * - * @param url the URL where the response was received from. - * @param statusCode the HTTP status code. - * @param response the raw response of fetching the given URL. - * @return the response, as {@link String}. - * - * @throws RobotConnectionException if the response code is not HTTP OK (200). - */ - public static String validateAndReadResponse(String url, int statusCode, InputStream response) - throws RobotConnectionException { - try { - return validateAndReadResponse(url, statusCode, ByteStreams.toByteArray(response)); - } catch (IOException e) { - String msg = "Robot fetch http failure: " + url + "."; - throw new RobotConnectionException(msg, statusCode); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/robot/RobotName.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/robot/RobotName.java b/wave/src/main/java/com/google/wave/api/robot/RobotName.java deleted file mode 100644 index 94da21d..0000000 --- a/wave/src/main/java/com/google/wave/api/robot/RobotName.java +++ /dev/null @@ -1,251 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.robot; - -import java.util.regex.Pattern; - -/** - * Simple class representing a (parsed) address of a robot. - * The general form of these addresses is: id[+proxyfor][#version]@domain - * where id is the basic identifier of the robot, proxyfor the id on - * that is proxied for and version the appengine version that should be - * used. - * - */ -public final class RobotName { - /** - * Builds {@link RobotName}s. - */ - public static class Builder { - private final String id; - private final String domain; - private String proxyFor; - private String version; - - public Builder(String id, String domain) { - this.id = id; - this.domain = domain; - this.proxyFor = ""; - this.version = ""; - } - - public Builder withProxyFor(String proxyFor) { - this.proxyFor = proxyFor; - return this; - } - - public Builder withVersion(String version) { - this.version = version; - return this; - } - - public RobotName build() { - return new RobotName(id, domain, proxyFor, version); - } - } - - /** - * Regular expression for robot participant id. TLD is between 2 and 6 - * characters long to match the ascii IANA top level domains as of Sept 2010. - */ - // TODO(user): Make this stricter. - private static final Pattern ROBOT_ID_REGEX = - Pattern.compile("^[a-z0-9._%+#-]+?@[a-z0-9.-]+\\.[a-z]{2,6}$", Pattern.CASE_INSENSITIVE); - - /** - * Checks if the given address looks like a well-formed robot id. - * - * @param address the address to check. - * @return {@code true} if the given address is a robot id. - */ - public static boolean isWellFormedAddress(String address) { - return address != null ? ROBOT_ID_REGEX.matcher(address).matches() : false; - } - - /** - * Construct a RobotName from an address. The address must be well-formed as - * described. @see RobotName - * - * @param address the address to parse. - * @return robot name instance, or {@code null} if the address is not a robot - * address. - */ - public static RobotName fromAddress(String address) { - if (!isWellFormedAddress(address)) { - return null; - } - - int index = address.indexOf('@'); - String id = address.substring(0, index); - String domain = address.substring(index + 1); - index = id.indexOf('#'); - String version = ""; - if (index >= 0) { - version = id.substring(index + 1); - id = address.substring(0, index); - } - index = id.indexOf('+'); - String proxyFor = ""; - if (index >= 0) { - proxyFor = id.substring(index + 1); - id = id.substring(0, index); - } - return new RobotName(id, domain, proxyFor, version); - } - - private final String id; - private final String domain; - private String proxyFor; - private String version; - - public RobotName(String id, String domain) { - this.id = id; - this.domain = domain; - this.proxyFor = ""; - this.version = ""; - } - - private RobotName(String id, String domain, String proxyFor, String version) { - this.id = id; - this.domain = domain; - this.proxyFor = proxyFor; - this.version = version; - } - - public boolean hasProxyFor() { - return !proxyFor.isEmpty(); - } - - public boolean hasVersion() { - return !version.isEmpty(); - } - - public String getId() { - return id; - } - - public String getDomain() { - return domain; - } - - public String getProxyFor() { - return proxyFor; - } - - public void setProxyFor(String proxyFor) { - this.proxyFor = proxyFor; - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - /** - * Converts the robot name to the participant id form, including proxy and - * version information, for example, {@code foo+proxy#[email protected]}. - * - * @return the robot participant address. - */ - public String toParticipantAddress() { - return toAddress(true, true); - } - - /** - * Converts the robot name to the email address form, excluding proxy and - * version information, for example, {@code [email protected]}. - * - * @return the robot participant address. - */ - public String toEmailAddress() { - return toAddress(false, false); - } - - /** - * Converts the robot name to the email address form, including version but - * excluding proxy information, for example, {@code foo#[email protected]}. - * - * @return the robot participant address. - */ - public String toEmailAddressWithVersion() { - return toAddress(false, true); - } - - /** - * Converts the robot name to address form (e.g. [email protected]). - * - * @param includeVersion whether to include the version or not. - * @return the robot address. - */ - @Deprecated - public String toAddress(boolean includeVersion) { - return toAddress(false, includeVersion); - } - - /** - * Converts the robot name to address form (e.g. foo+proxy#[email protected]). - * - * @param includeProxyFor whether to include the proxy id or not. - * @param includeVersion whether to include the version or not. - * @return the robot address. - */ - private String toAddress(boolean includeProxyFor, boolean includeVersion) { - StringBuilder address = new StringBuilder(id); - if (includeProxyFor && hasProxyFor()) { - address.append('+').append(proxyFor); - } - if (includeVersion && hasVersion()) { - address.append('#').append(version); - } - address.append('@').append(domain); - return address.toString(); - } - - @Override - public boolean equals(Object other) { - if (other == null) { return false; } - if (other == this) { return true; } - if (other instanceof RobotName) { - RobotName o = (RobotName) other; - return id.equals(o.id) && domain.equals(o.domain) && proxyFor.equals(o.proxyFor) - && version.equals(o.version); - } - return false; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + id.hashCode(); - result = prime * result + domain.hashCode(); - result = prime * result + proxyFor.hashCode(); - result = prime * result + version.hashCode(); - return result; - } - - @Override - public String toString() { - return toParticipantAddress(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/com/google/wave/api/v2/ElementGsonAdaptorV2.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/com/google/wave/api/v2/ElementGsonAdaptorV2.java b/wave/src/main/java/com/google/wave/api/v2/ElementGsonAdaptorV2.java deleted file mode 100644 index 95b0a4b..0000000 --- a/wave/src/main/java/com/google/wave/api/v2/ElementGsonAdaptorV2.java +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.google.wave.api.v2; - -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.JsonSerializationContext; -import com.google.wave.api.Attachment; -import com.google.wave.api.Element; -import com.google.wave.api.ElementType; -import com.google.wave.api.Image; -import com.google.wave.api.impl.ElementGsonAdaptor; -import com.google.wave.api.impl.GsonFactory; - -import java.lang.reflect.Type; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -/** - * Gson adaptor to serialize and deserialize {@link Element}. In v0.2, we still - * use {@link Image} to represents attachment, so we need to convert all - * attachment objects into Image. - * - * @author [email protected] (Jimin Li) - * @author [email protected] (Marcel Prasetya) - */ -public class ElementGsonAdaptorV2 extends ElementGsonAdaptor { - - private static final Set<String> ATTACHMENT_ONLY_PROPERTIES = new HashSet<String>( - Arrays.asList(Attachment.MIME_TYPE, Attachment.DATA, Attachment.ATTACHMENT_URL)); - - @Override - public JsonElement serialize(Element src, Type typeOfSrc, JsonSerializationContext context) { - if (src.getType() == ElementType.ATTACHMENT) { - src = new Element(ElementType.IMAGE, createImageProperties(src.getProperties())); - } - return super.serialize(src, typeOfSrc, context); - } - - @Override - public Element deserialize(JsonElement jsonElement, Type typeOfT, - JsonDeserializationContext context) throws JsonParseException { - JsonObject json = jsonElement.getAsJsonObject(); - String type = json.get(TYPE_TAG).getAsString(); - - if (ElementType.IMAGE.name().equals(type)) { - JsonObject properties = json.getAsJsonObject(PROPERTIES_TAG); - if (!properties.has(Image.URL)) { - json.addProperty(TYPE_TAG, ElementType.ATTACHMENT.name()); - } - } - return super.deserialize(json, typeOfT, context); - } - - static Map<String, String> createImageProperties(Map<String, String> props) { - Map<String, String> imageProps = new HashMap<String, String>(); - Iterator<Entry<String, String>> iter = props.entrySet().iterator(); - while (iter.hasNext()) { - Entry<String, String> next = iter.next(); - // Removes attachment only properties, and provides backward compatible - // image support to python robot with protocol version 0.2 - if (!ATTACHMENT_ONLY_PROPERTIES.contains(next.getKey())) { - imageProps.put(next.getKey(), next.getValue()); - } - } - return imageProps; - } - - /** - * Registers this {@link ElementGsonAdaptorV2} with the given - * {@link GsonFactory}. - * @param factory {@link GsonFactory} to register the type adapters with - * @return the given {@link GsonFactory} with the registered adapters - */ - public static GsonFactory registerTypeAdapters(GsonFactory factory) { - ElementGsonAdaptorV2 elementGsonAdaptorV2 = new ElementGsonAdaptorV2(); - factory.registerTypeAdapter(Element.class, elementGsonAdaptorV2); - factory.registerTypeAdapter(Attachment.class, elementGsonAdaptorV2); - return factory; - } -}
