http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/com/google/wave/api/Tags.java ---------------------------------------------------------------------- diff --git a/src/com/google/wave/api/Tags.java b/src/com/google/wave/api/Tags.java deleted file mode 100644 index a9c92e4..0000000 --- a/src/com/google/wave/api/Tags.java +++ /dev/null @@ -1,177 +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; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.Set; - -/** - * A class that represents wavelet's tags. This class supports various - * tag related operations, such as, adding or removing tag from a wavelet. - */ -public class Tags implements Iterable<String>, Serializable { - - /** A set of string that represents wavelet tags. */ - private final Set<String> tags; - - /** The wavelet that this tag list represents. */ - private final Wavelet wavelet; - - /** The operation queue to queue operation to the robot proxy. */ - private final OperationQueue operationQueue; - - /** - * Constructor. - * - * @param tags a collection of initial tags of the wavelet. - * @param wavelet the wavelet that this tag list represents. - * @param operationQueue the operation queue to queue operation to the robot - * proxy. - */ - public Tags(Collection<String> tags, Wavelet wavelet, OperationQueue operationQueue) { - this.tags = new LinkedHashSet<String>(tags); - this.wavelet = wavelet; - this.operationQueue = operationQueue; - } - - /** - * Adds the given tag id if it doesn't exist. - * - * @param tag the tag that will be added. - * @return {@code true} if the given tag does not exist yet - * in the owning wavelet, which means that a new - * {@code wavelet.modifyTag()} has been queued. Otherwise, returns - * {@code false}. - */ - public boolean add(String tag) { - if (tags.contains(tag)) { - return false; - } - - operationQueue.modifyTagOfWavelet(wavelet, tag, "add"); - tags.add(tag); - return true; - } - - /** - * Removes the given tag id if it exists. - * - * @param tag the tag that will be removed. - * @return {@code true} if the given tag exists in the owning wavelet, which - * means that a new {@code wavelet.modifyTag()} has been queued. - * Otherwise, returns {@code false}. - */ - public boolean remove(String tag) { - if (!tags.contains(tag)) { - return false; - } - - operationQueue.modifyTagOfWavelet(wavelet, tag, "remove"); - tags.remove(tag); - return true; - } - - /** - * Checks whether the owning wavelet has the given tag or not. - * - * @param tag the name of the tag to check. - * @return {@code true} if the wavelet has the given tag. - * Otherwise, returns {@code false}. - */ - public boolean contains(String tag) { - return tags.contains(tag); - } - - /** - * Returns the number of tags in the owning wavelet. - * - * @return the number of tags. - */ - public int size() { - return tags.size(); - } - - /** - * Checks whether the owning wavelet has any tag or not. - * - * @return {@code true} if the owning wavelet has at least one tag. Otherwise, - * returns {@code false}. - */ - public boolean isEmpty() { - return tags.isEmpty(); - } - - @Override - public Iterator<String> iterator() { - return new TagsIterator(); - } - - /** - * An iterator for {@link Tags}. - */ - private class TagsIterator implements Iterator<String> { - - /** The iterator of the underlying tag store. */ - private final Iterator<String> storeIterator; - - /** The pointer to the current tag. */ - private String currentTag; - - /** A flag that denotes whether {@link #remove} has been called or not. */ - private boolean removeCalled; - - /** - * Constructor. - */ - private TagsIterator() { - this.storeIterator = tags.iterator(); - } - - @Override - public boolean hasNext() { - return storeIterator.hasNext(); - } - - @Override - public String next() { - removeCalled = false; - currentTag = storeIterator.next(); - return currentTag; - } - - @Override - public void remove() { - if (removeCalled) { - throw new IllegalStateException("remove() has been called after the last call to next()."); - } - - if (currentTag == null) { - throw new IllegalStateException("Please call next() first before calling remove()."); - } - - removeCalled = true; - operationQueue.modifyTagOfWavelet(wavelet, currentTag, "remove"); - storeIterator.remove(); - } - } -}
http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/com/google/wave/api/Util.java ---------------------------------------------------------------------- diff --git a/src/com/google/wave/api/Util.java b/src/com/google/wave/api/Util.java deleted file mode 100644 index 311af50..0000000 --- a/src/com/google/wave/api/Util.java +++ /dev/null @@ -1,94 +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; - -import org.apache.commons.codec.binary.Base64; - -import java.net.URLEncoder; -import java.util.regex.Pattern; - -import javax.annotation.Nullable; - -/** - * A class that contains various utility methods. - */ -public final class Util { - - /** - * A regular expression that defines reserved {@code proxy_for} id. - */ - private static final Pattern RESERVED_PROXY_FOR_CHARS_REGEX = - Pattern.compile("[\\s\u0000-\u001F@,:<>\u007F]"); - - /** - * Checks if the given string is a valid proxy id, by asserting whether the - * string contains reserved characters or not. This check is to ensure that - * when we concatenate the robot id and the proxy id, it doesn't result in an - * invalid participant id. - * - * The reserved characters are: - * <ul> - * <li>whitespaces</li> - * <li>non-printing characters: decimal 0 - 31 (hex 00 - 1F), and decimal - * 127 (hex 7F)</li> - * <li>{@code @}, {@code ,}, {@code :}, {@code <}, {@code >}</li> - * </ul> - * - * If you need to pass in an arbitrary string as the proxy id, please consider - * encoding the string with a Base64 encoder (for example, {@link Base64}) or - * a URL encoder (for example, {@link URLEncoder}). - * - * @param string the string to be checked. - * @return {@code true} if the string doesn't contain any reserved characters. - */ - public static boolean isValidProxyForId(String string) { - return !RESERVED_PROXY_FOR_CHARS_REGEX.matcher(string).find(); - } - - /** - * Checks if the given string is a valid proxy id. Please see - * {@link #isValidProxyForId(String)} for more details on the assertion. This - * method throws an {@link IllegalArgumentException} if the input string is - * not a valid proxy id. - * - * @param string the string to check. - * @throws IllegalArgumentException if the input string is not a valid proxy - * id. - */ - public static void checkIsValidProxyForId(String string) { - if (string != null && !isValidProxyForId(string)) { - throw new IllegalArgumentException("The input string \"" + string + "\" is not a valid " + - "proxy id. A valid proxy id may not contain whitespace characters, non-printing" + - "characters (decimal 0 - 31, and decimal 127), @, :, <, >, and comma."); - } - } - - /** - * Returns {@code true} if the given string is null, empty, or comprises only - * whitespace characters. - * - * @param string the string reference to check - * @return {@code true} if {@code string} is null, empty, or consists of - * whitespace characters only - */ - public static boolean isEmptyOrWhitespace(@Nullable String string) { - return string == null || string.matches("\\s*"); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/com/google/wave/api/WaveService.java ---------------------------------------------------------------------- diff --git a/src/com/google/wave/api/WaveService.java b/src/com/google/wave/api/WaveService.java deleted file mode 100644 index 4277fa2..0000000 --- a/src/com/google/wave/api/WaveService.java +++ /dev/null @@ -1,1011 +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; - -import com.google.gson.Gson; -import com.google.wave.api.JsonRpcConstant.ParamsProperty; -import com.google.wave.api.impl.RawAttachmentData; -import com.google.wave.api.impl.GsonFactory; -import com.google.wave.api.impl.RawDeltasListener; -import com.google.wave.api.impl.WaveletData; - -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.codec.digest.DigestUtils; -import org.waveprotocol.wave.model.id.InvalidIdException; -import org.waveprotocol.wave.model.id.WaveId; -import org.waveprotocol.wave.model.id.WaveletId; -import org.waveprotocol.wave.media.model.AttachmentId; - -import net.oauth.OAuth; -import net.oauth.OAuthAccessor; -import net.oauth.OAuthConsumer; -import net.oauth.OAuthException; -import net.oauth.OAuthMessage; -import net.oauth.OAuthValidator; -import net.oauth.SimpleOAuthValidator; -import net.oauth.client.OAuthClient; -import net.oauth.http.HttpClient; -import net.oauth.http.HttpMessage; -import net.oauth.http.HttpResponseMessage; -import net.oauth.signature.OAuthSignatureMethod; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; -import java.net.HttpURLConnection; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLEncoder; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.AbstractMap.SimpleEntry; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Utility class for using OAuth to talk to Wave service. - */ -public class WaveService { - - /** Infinite {@code urlfetch} fetch timeout. */ - public static final int FETCH_INFINITE_TIMEOUT = 0; - - /** Default {@code urlfetch} fetch timeout in ms. */ - public static final int FETCH_DEFAILT_TIMEOUT_IN_MS = 10 * 1000; - - /** - * Helper class to make outgoing OAuth HTTP requests. - */ - static class HttpFetcher implements HttpClient { - - private static final String HTTP_POST_METHOD = "POST"; - private static final String HTTP_PUT_METHOD = "PUT"; - - private int fetchTimeout = FETCH_DEFAILT_TIMEOUT_IN_MS; - - @Override - public HttpResponseMessage execute(HttpMessage request, Map<String, Object> stringObjectMap) - throws IOException { - String body = readInputStream(request.getBody()); - OutputStreamWriter out = null; - HttpURLConnection conn = null; - // Open the connection. - conn = (HttpURLConnection) request.url.openConnection(); - conn.setReadTimeout(fetchTimeout); - conn.setRequestMethod(request.method); - // Add the headers - if (request.headers != null) { - for (java.util.Map.Entry<String, String> header : request.headers) { - conn.setRequestProperty(header.getKey(), header.getValue()); - } - } - - boolean doOutput = - body != null && (HTTP_POST_METHOD.equalsIgnoreCase(request.method) - || HTTP_PUT_METHOD.equalsIgnoreCase(request.method)); - - if (doOutput) { - conn.setDoOutput(true); - } - - conn.connect(); - - if (doOutput) { - // Send the request body. - out = new OutputStreamWriter(conn.getOutputStream(), UTF_8); - try { - out.write(body); - out.flush(); - } finally { - out.close(); - } - } - - // Return the response stream. - return new HttpResponse( - request.method, request.url, conn.getResponseCode(), conn.getInputStream()); - } - - /** - * Reads the given {@link java.io.InputStream} into a {@link String} - * - * @param inputStream the {@link java.io.InputStream} to be read. - * @return a string content of the {@link java.io.InputStream}. - * @throws IOException if there is a problem reading the stream. - */ - static String readInputStream(InputStream inputStream) throws IOException { - if (inputStream == null) { - return null; - } - BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); - StringBuilder result = new StringBuilder(); - String s; - while ((s = reader.readLine()) != null) { - result.append(s); - } - return result.toString(); - } - - /** - * Sets the fetch timeout to a specified timeout, in milliseconds. - * A timeout of zero is interpreted as an infinite timeout. - * - * @param fetchTimeout - */ - void setTimeout(int fetchTimeout) { - this.fetchTimeout = fetchTimeout; - } - } - - /** - * A simple implementation of {@link HttpResponseMessage} that gets the - * response from {@link HttpURLConnection#getInputStream()}. - */ - static class HttpResponse extends HttpResponseMessage { - - /** The HTTP response code. */ - private final int statusCode; - - /** The response stream. */ - private final InputStream responseStream; - - /** - * Constructor. - * - * @param method the HTTP method, for example, GET or POST. - * @param url the URL where the response comes from. - * @param statusCode the HTTP response code. - * @param responseStream the response stream. - */ - public HttpResponse(String method, URL url, int statusCode, InputStream responseStream) { - super(method, url); - this.statusCode = statusCode; - this.responseStream = responseStream; - } - - @Override - public int getStatusCode() { - return statusCode; - } - - @Override - public InputStream openBody() { - return responseStream; - } - } - - /** - * Helper class that contains various OAuth credentials. - */ - static class ConsumerData { - - /** Consumer key used to sign the operations in the active mode. */ - private final String consumerKey; - - /** Consumer secret used to sign the operations in the active mode. */ - private final String consumerSecret; - - /** The URL that handles the JSON-RPC request in the active mode. */ - private final String rpcServerUrl; - - /** Whether this session is user authenticated */ - private final boolean userAuthenticated; - - /** The OAuth Accessor contains authentication data used to make requests */ - private final OAuthAccessor accessor; - - /** - * Constructor. - * - * @param consumerKey the consumer key. - * @param consumerSecret the consumer secret - * @param rpcServerUrl the URL of the JSON-RPC request handler - */ - public ConsumerData(String consumerKey, String consumerSecret, String rpcServerUrl) { - String consumerKeyPrefix = ""; - // NOTE(ljvderijk): Present for backwards capability. - if (RPC_URL.equals(rpcServerUrl) || SANDBOX_RPC_URL.equals(rpcServerUrl)) { - consumerKeyPrefix = "google.com:"; - } - this.consumerKey = consumerKeyPrefix + consumerKey; - this.consumerSecret = consumerSecret; - this.rpcServerUrl = rpcServerUrl; - - userAuthenticated = false; - OAuthConsumer consumer = new OAuthConsumer(null, consumerKey, consumerSecret, null); - consumer.setProperty(OAuth.OAUTH_SIGNATURE_METHOD, OAuth.HMAC_SHA1); - accessor = new OAuthAccessor(consumer); - } - - public ConsumerData(OAuthAccessor accessor, String rpcServerUrl) { - this.consumerKey = accessor.consumer.consumerKey; - this.consumerSecret = accessor.consumer.consumerSecret; - this.accessor = accessor; - this.rpcServerUrl = rpcServerUrl; - userAuthenticated = true; - } - - /** - * @return the consumer key used to sign the operations in the active mode. - */ - public String getConsumerKey() { - return consumerKey; - } - - /** - * @return the consumer secret used to sign the operations in the active mode. - */ - public String getConsumerSecret() { - return consumerSecret; - } - - /** - * @return the URL of the JSON-RPC request handler. - */ - public String getRpcServerUrl() { - return rpcServerUrl; - } - - public boolean isUserAuthenticated() { - return userAuthenticated; - } - - public OAuthAccessor getAccessor() { - return accessor; - } - - } - - /** The wire protocol version. */ - public static final ProtocolVersion PROTOCOL_VERSION = ProtocolVersion.DEFAULT; - - private static final String JSON_MIME_TYPE = "application/json; charset=utf-8"; - private static final String OAUTH_BODY_HASH = "oauth_body_hash"; - private static final String POST = "POST"; - private static final String SHA_1 = "SHA-1"; - private static final String UTF_8 = "UTF-8"; - - /** Wave RPC URLs. */ - public static final String RPC_URL = "https://www-opensocial.googleusercontent.com/api/rpc"; - public static final String SANDBOX_RPC_URL = - "https://www-opensocial-sandbox.googleusercontent.com/api/rpc"; - - private static final Logger LOG = Logger.getLogger(WaveService.class.getName()); - - /** Namespace to prefix all active api operation calls. */ - private static final String OPERATION_NAMESPACE = "wave"; - - /** Serializer to serialize events and operations in active mode. */ - private static final Gson SERIALIZER = new GsonFactory().create(OPERATION_NAMESPACE); - - /** OAuth request validator. */ - private static final OAuthValidator VALIDATOR = new SimpleOAuthValidator(); - - /** A map of RPC server URL to its consumer data object. */ - private final Map<String, ConsumerData> consumerDataMap = new HashMap<String, ConsumerData>(); - - /** A version number. */ - private final String version; - - /** A utility to make HTTP requests. */ - private final HttpFetcher httpFetcher; - - /** - * Constructor. - */ - public WaveService() { - this(new HttpFetcher(), null); - } - - /** - * Constructor. - * - * @param version the version number. - */ - public WaveService(String version) { - this(new HttpFetcher(), version); - } - - /** - * Constructor. - * - * @param httpFetcher the fetcher to make HTTP calls. - * @param version the version number. - */ - public WaveService(HttpFetcher httpFetcher, String version) { - this.httpFetcher = httpFetcher; - this.version = version; - } - - /** - * Sets the OAuth related properties, including the consumer key and secret - * that are used to sign the outgoing operations. - * - * <p> - * This version of the method is for 2-legged OAuth, where the robot is not - * acting on behalf of a user. - * - * <p> - * For the rpcServerUrl you can use: - * <ul> - * <li>https://www-opensocial.googleusercontent.com/api/rpc - for wave - * preview. - * <li> - * https://www-opensocial-sandbox.googleusercontent.com/api/rpc - for wave - * sandbox. - * </ul> - * - * @param consumerKey the consumer key. - * @param consumerSecret the consumer secret. - * @param rpcServerUrl the URL of the server that serves the JSON-RPC request. - */ - public void setupOAuth(String consumerKey, String consumerSecret, String rpcServerUrl) { - if (consumerKey == null || consumerSecret == null || rpcServerUrl == null) { - throw new IllegalArgumentException( - "Consumer Key, Consumer Secret and RPCServerURL " + "have to be non-null"); - } - consumerDataMap.put(rpcServerUrl, new ConsumerData(consumerKey, consumerSecret, rpcServerUrl)); - } - - /** - * Sets the OAuth related properties that are used to sign the outgoing - * operations for 3-legged OAuth. - * - * <p> - * Performing the OAuth dance is not part of this interface - once you've done - * the dance, pass the constructed accessor and rpc endpoint into this method. - * - * <p> - * Ensure that the endpoint URL you pass in matches exactly the URL used to - * request an access token (including https vs http). - * - * For the rpcServerUrl you can use: - * <ul> - * <li>https://www-opensocial.googleusercontent.com/api/rpc - for wave - * preview. - * <li> - * https://www-opensocial-sandbox.googleusercontent.com/api/rpc - for wave - * sandbox. - * </ul> - * - * @param accessor the {@code OAuthAccessor} with access token and secret - * @param rpcServerUrl the endpoint URL of the server that serves the JSON-RPC - * request. - */ - public void setupOAuth(OAuthAccessor accessor, String rpcServerUrl) { - if (accessor == null || rpcServerUrl == null) { - throw new IllegalArgumentException("Accessor and RPCServerURL have to be non-null"); - } - consumerDataMap.put(rpcServerUrl, new ConsumerData(accessor, rpcServerUrl)); - } - - /** - * Validates the incoming HTTP request. - * - * @param requestUrl the URL of the request. - * @param jsonBody the request body to be validated. - * @param rpcServerUrl the RPC server URL. - * - * @throws OAuthException if it can't validate the request. - */ - public void validateOAuthRequest( - String requestUrl, Map<String, String[]> requestParams, String jsonBody, String rpcServerUrl) - throws OAuthException { - ConsumerData consumerData = consumerDataMap.get(rpcServerUrl); - if (consumerData == null) { - throw new IllegalArgumentException( - "There is no consumer key and secret associated " + "with the given RPC URL " - + rpcServerUrl); - } - - List<OAuth.Parameter> params = new ArrayList<OAuth.Parameter>(); - for (Map.Entry<String, String[]> entry : requestParams.entrySet()) { - for (String value : entry.getValue()) { - params.add(new OAuth.Parameter(entry.getKey(), value)); - } - } - OAuthMessage message = new OAuthMessage(POST, requestUrl, params); - - // Compute and check the hash of the body. - try { - MessageDigest md = MessageDigest.getInstance(SHA_1); - byte[] hash = md.digest(jsonBody.getBytes(UTF_8)); - String encodedHash = new String(Base64.encodeBase64(hash, false), UTF_8); - if (!encodedHash.equals(message.getParameter(OAUTH_BODY_HASH))) { - throw new IllegalArgumentException( - "Body hash does not match. Expected: " + encodedHash + ", provided: " - + message.getParameter(OAUTH_BODY_HASH)); - } - - OAuthAccessor accessor = consumerData.getAccessor(); - if (LOG.isLoggable(Level.FINE)) { - LOG.fine("Signature base string: " + OAuthSignatureMethod.getBaseString(message)); - } - VALIDATOR.validateMessage(message, accessor); - } catch (NoSuchAlgorithmException e) { - throw new OAuthException("Error validating OAuth request", e); - } catch (URISyntaxException e) { - throw new OAuthException("Error validating OAuth request", e); - } catch (OAuthException e) { - throw new OAuthException("Error validating OAuth request", e); - } catch (IOException e) { - throw new OAuthException("Error validating OAuth request", e); - } - } - - /** - * Submits the pending operations associated with this {@link Wavelet}. - * - * @param wavelet the bundle that contains the operations to be submitted. - * @param rpcServerUrl the active gateway to send the operations to. - * @return a list of {@link JsonRpcResponse} that represents the responses - * from the server for all operations that were submitted. - * - * @throws IllegalStateException if this method is called prior to setting the - * proper consumer key, secret, and handler URL. - * @throws IOException if there is a problem submitting the operations. - */ - public List<JsonRpcResponse> submit(Wavelet wavelet, String rpcServerUrl) throws IOException { - List<JsonRpcResponse> responses = makeRpc(wavelet.getOperationQueue(), rpcServerUrl); - wavelet.getOperationQueue().clear(); - return responses; - } - - /** - * Returns an empty/blind stub of a wavelet with the given wave id and wavelet - * id. - * - * <p> - * Call this method if you would like to apply wavelet-only operations - * without fetching the wave first. - * - * The returned wavelet has its own {@link OperationQueue}. It is the - * responsibility of the caller to make sure this wavelet gets submitted to - * the server, either by calling {@link AbstractRobot#submit(Wavelet, String)} - * or by calling {@link Wavelet#submitWith(Wavelet)} on the new wavelet, to - * join its queue with another wavelet, for example, the event wavelet. - * - * @param waveId the id of the wave. - * @param waveletId the id of the wavelet. - * @return a stub of a wavelet. - */ - public Wavelet blindWavelet(WaveId waveId, WaveletId waveletId) { - return blindWavelet(waveId, waveletId, null); - } - - /** - * @see #blindWavelet(WaveId, WaveletId) - * - * @param proxyForId the proxying information that should be set on the - * operation queue. Please note that this parameter should be properly - * encoded to ensure that the resulting participant id is valid (see - * {@link Util#checkIsValidProxyForId(String)} for more details). - */ - public Wavelet blindWavelet(WaveId waveId, WaveletId waveletId, String proxyForId) { - return blindWavelet(waveId, waveletId, proxyForId, new HashMap<String, Blip>()); - } - - /** - * @see #blindWavelet(WaveId, WaveletId, String) - * - * @param blips a collection of blips that belong to this wavelet. - */ - public Wavelet blindWavelet( - WaveId waveId, WaveletId waveletId, String proxyForId, Map<String, Blip> blips) { - return blindWavelet(waveId, waveletId, proxyForId, blips, new HashMap<String, BlipThread>()); - } - - /** - * @see #blindWavelet(WaveId, WaveletId, String, Map) - * - * @param threads a collection of threads that belong to this wavelet. - */ - public Wavelet blindWavelet(WaveId waveId, WaveletId waveletId, String proxyForId, - Map<String, Blip> blips, Map<String, BlipThread> threads) { - Util.checkIsValidProxyForId(proxyForId); - Map<String, String> roles = new HashMap<String, String>(); - return new Wavelet(waveId, waveletId, null, - new BlipThread("", -1, new ArrayList<String>(), blips), Collections.<String>emptySet(), - roles, blips, threads, new OperationQueue(proxyForId)); - } - - /** - * Creates a new wave with a list of participants on it. - * - * The root wavelet of the new wave is returned with its own - * {@link OperationQueue}. It is the responsibility of the caller to make sure - * this wavelet gets submitted to the server, either by calling - * {@link AbstractRobot#submit(Wavelet, String)} or by calling - * {@link Wavelet#submitWith(Wavelet)} on the new wavelet. - * - * @param domain the domain to create the wavelet on. In general, this should - * correspond to the domain of the incoming event wavelet, except when - * the robot is calling this method outside of an event or when the - * server is handling multiple domains. - * @param participants the initial participants on the wave. The robot, as the - * creator of the wave, will be added by default. The order of the - * participants will be preserved. - */ - public Wavelet newWave(String domain, Set<String> participants) { - return newWave(domain, participants, null); - } - - /** - * @see #newWave(String, Set) - * - * @param proxyForId the proxy id that should be used to create the new wave. - * If specified, the creator of the wave would be - * robotid+<proxyForId>@appspot.com. Please note that this parameter - * should be properly encoded to ensure that the resulting participant - * id is valid (see {@link Util#checkIsValidProxyForId(String)} for - * more details). - */ - public Wavelet newWave(String domain, Set<String> participants, String proxyForId) { - return newWave(domain, participants, "", proxyForId); - } - - /** - * @see #newWave(String, Set, String) - * - * @param msg the message that will be passed back to the robot when - * WAVELET_CREATED event is fired as a result of this operation. - */ - public Wavelet newWave(String domain, Set<String> participants, String msg, String proxyForId) { - Util.checkIsValidProxyForId(proxyForId); - return new OperationQueue(proxyForId).createWavelet(domain, participants, msg); - } - - /** - * @see #newWave(String, Set, String, String) - * - * @param rpcServerUrl if specified, this operation will be submitted - * immediately to this active gateway, that will return immediately the - * actual wave id, the id of the root wavelet, and id of the root blip. - * - * @throws IOException if there is a problem submitting the operation to the - * server, when {@code submit} is {@code true}. - * @throws InvalidIdException - */ - public Wavelet newWave( - String domain, Set<String> participants, String msg, String proxyForId, String rpcServerUrl) - throws IOException, InvalidIdException { - Util.checkIsValidProxyForId(proxyForId); - OperationQueue opQueue = new OperationQueue(proxyForId); - Wavelet newWavelet = opQueue.createWavelet(domain, participants, msg); - - if (rpcServerUrl != null && !rpcServerUrl.isEmpty()) { - // Get the response for the robot.fetchWavelet() operation, which is the - // second operation, since makeRpc prepends the robot.notify() operation. - JsonRpcResponse response = this.submit(newWavelet, rpcServerUrl).get(1); - if (response.isError()) { - throw new IOException(response.getErrorMessage()); - } - WaveId waveId = ApiIdSerializer.instance().deserialiseWaveId( - (String) response.getData().get(ParamsProperty.WAVE_ID)); - WaveletId waveletId = ApiIdSerializer.instance().deserialiseWaveletId( - (String) response.getData().get(ParamsProperty.WAVELET_ID)); - String rootBlipId = (String) response.getData().get(ParamsProperty.BLIP_ID); - - Map<String, Blip> blips = new HashMap<String, Blip>(); - Map<String, BlipThread> threads = new HashMap<String, BlipThread>(); - Map<String, String> roles = new HashMap<String, String>(); - - List<String> blipIds = new ArrayList<String>(); - blipIds.add(rootBlipId); - BlipThread rootThread = new BlipThread("", -1, blipIds, blips); - - newWavelet = new Wavelet(waveId, waveletId, rootBlipId, rootThread, participants, - roles, blips, threads, opQueue); - blips.put(rootBlipId, new Blip(rootBlipId, "", null, "", newWavelet)); - } - return newWavelet; - } - - /** - * Requests SearchResult for a query. - * - * @param query the query to execute. - * @param index the index from which to return results. - * @param numresults the number of results to return. - * @param rpcServerUrl the active gateway. - * - * @throws IOException if remote server returns error. - */ - public SearchResult search(String query, Integer index, Integer numResults, String rpcServerUrl) - throws IOException { - OperationQueue opQueue = new OperationQueue(); - opQueue.search(query, index, numResults); - Map<ParamsProperty, Object> response = makeSingleOperationRpc(opQueue, rpcServerUrl); - return (SearchResult) response.get(ParamsProperty.SEARCH_RESULTS); - } - - /** - * Fetches a wavelet using the active API. - * - * The returned wavelet contains a snapshot of the state of the wavelet at - * that point. It can be used to modify the wavelet, but the wavelet might - * change in between, so treat carefully. - * - * Also, the returned wavelet has its own {@link OperationQueue}. It is the - * responsibility of the caller to make sure this wavelet gets submitted to - * the server, either by calling {@link AbstractRobot#submit(Wavelet, String)} - * or by calling {@link Wavelet#submitWith(Wavelet)} on the new wavelet. - * - * @param waveId the id of the wave to fetch. - * @param waveletId the id of the wavelet to fetch. - * @param rpcServerUrl the active gateway that is used to fetch the wavelet. - * - * @throws IOException if there is a problem fetching the wavelet. - */ - public Wavelet fetchWavelet(WaveId waveId, WaveletId waveletId, String rpcServerUrl) - throws IOException { - return fetchWavelet(waveId, waveletId, null, rpcServerUrl); - } - - /** - * @see #fetchWavelet(WaveId, WaveletId, String) - * - * @param proxyForId the proxy id that should be used to fetch this wavelet. - * Please note that this parameter should be properly encoded to ensure - * that the resulting participant id is valid (see - * {@link Util#checkIsValidProxyForId(String)} for more details). - */ - public Wavelet fetchWavelet( - WaveId waveId, WaveletId waveletId, String proxyForId, String rpcServerUrl) - throws IOException { - Util.checkIsValidProxyForId(proxyForId); - OperationQueue opQueue = new OperationQueue(proxyForId); - opQueue.fetchWavelet(waveId, waveletId); - - Map<ParamsProperty, Object> response = makeSingleOperationRpc(opQueue, rpcServerUrl); - - // Deserialize wavelet. - opQueue.clear(); - WaveletData waveletData = (WaveletData) response.get(ParamsProperty.WAVELET_DATA); - Map<String, Blip> blips = new HashMap<String, Blip>(); - Map<String, BlipThread> threads = new HashMap<String, BlipThread>(); - Wavelet wavelet = Wavelet.deserialize(opQueue, blips, threads, waveletData); - - // Deserialize threads. - @SuppressWarnings("unchecked") - Map<String, BlipThread> tempThreads = - (Map<String, BlipThread>) response.get(ParamsProperty.THREADS); - for (Map.Entry<String, BlipThread> entry : tempThreads.entrySet()) { - BlipThread thread = entry.getValue(); - threads.put(entry.getKey(), - new BlipThread(thread.getId(), thread.getLocation(), thread.getBlipIds(), blips)); - } - - // Deserialize blips. - @SuppressWarnings("unchecked") - Map<String, BlipData> blipDatas = - (Map<String, BlipData>) response.get(ParamsProperty.BLIPS); - for (Map.Entry<String, BlipData> entry : blipDatas.entrySet()) { - blips.put(entry.getKey(), Blip.deserialize(opQueue, wavelet, entry.getValue())); - } - - return wavelet; - } - - /** - * Retrieves wavelets ids of the specified wave. - * - * @param waveId the id of the wave. - * @param rpcServerUrl the URL of the JSON-RPC request handler. - * @return list of wavelets ids. - * @throws IOException if there is a problem fetching the wavelet. - */ - public List<WaveletId> retrieveWaveletIds(WaveId waveId, String rpcServerUrl) - throws IOException { - OperationQueue opQueue = new OperationQueue(); - opQueue.retrieveWaveletIds(waveId); - - Map<ParamsProperty, Object> response = makeSingleOperationRpc(opQueue, rpcServerUrl); - @SuppressWarnings("unchecked") - List<WaveletId> list = (List<WaveletId>)response.get(ParamsProperty.WAVELET_IDS); - return list; - } - - /** - * Exports wavelet deltas history. - * - * @param waveId the id of the wave to export. - * @param waveletId the id of the wavelet to export. - * @param rpcServerUrl the URL of the JSON-RPC request handler. - * @return WaveletSnapshot in Json. - * @throws IOException if there is a problem fetching the wavelet. - */ - public String exportRawSnapshot(WaveId waveId, WaveletId waveletId, String rpcServerUrl) throws IOException { - OperationQueue opQueue = new OperationQueue(); - opQueue.exportSnapshot(waveId, waveletId); - - Map<ParamsProperty, Object> response = makeSingleOperationRpc(opQueue, rpcServerUrl); - return (String)response.get(ParamsProperty.RAW_SNAPSHOT); - } - - /** - * Exports wavelet deltas history. - * - * @param waveId the id of the wave to export. - * @param waveletId the id of the wavelet to export. - * @param fromVersion start ProtocolHashedVersion. - * @param toVersion end ProtocolHashedVersion. - * @param rpcServerUrl the URL of the JSON-RPC request handler. - * @return history of deltas. - * @throws IOException if there is a problem fetching the deltas. - */ - public void exportRawDeltas(WaveId waveId, WaveletId waveletId, - byte[] fromVersion, byte[] toVersion, String rpcServerUrl, - RawDeltasListener listener) throws IOException { - OperationQueue opQueue = new OperationQueue(); - opQueue.exportRawDeltas(waveId, waveletId, fromVersion, toVersion); - - Map<ParamsProperty, Object> response = makeSingleOperationRpc(opQueue, rpcServerUrl); - @SuppressWarnings("unchecked") - List<byte[]> rawHistory = (List<byte[]>)response.get(ParamsProperty.RAW_DELTAS); - byte[] rawTargetVersion = (byte[])response.get(ParamsProperty.TARGET_VERSION); - listener.onSuccess(rawHistory, rawTargetVersion); - } - - /** - * Exports attachment. - * - * @param attachmentId the id of attachment. - * @param rpcServerUrl the URL of the JSON-RPC request handler. - * @return the data of attachment. - * @throws IOException if there is a problem fetching the wavelet. - */ - public RawAttachmentData exportAttachment(AttachmentId attachmentId, - String rpcServerUrl) throws IOException { - OperationQueue opQueue = new OperationQueue(); - opQueue.exportAttachment(attachmentId); - - Map<ParamsProperty, Object> response = makeSingleOperationRpc(opQueue, rpcServerUrl); - return (RawAttachmentData)response.get(ParamsProperty.ATTACHMENT_DATA); - } - - /** - * Imports deltas to wavelet. - * - * @param waveId the id of the wave to import. - * @param waveletId the id of the wavelet to import. - * @param history the history of deltas. - * @param rpcServerUrl the URL of the JSON-RPC request handler. - * @return the version from which importing started. - * @throws IOException if there is a problem fetching the wavelet. - */ - public long importRawDeltas(WaveId waveId, WaveletId waveletId, - List<byte[]> history, String rpcServerUrl) throws IOException { - OperationQueue opQueue = new OperationQueue(); - opQueue.importRawDeltas(waveId, waveletId, history); - - Map<ParamsProperty, Object> response = makeSingleOperationRpc(opQueue, rpcServerUrl); - return (Long)response.get(ParamsProperty.IMPORTED_FROM_VERSION); - } - - /** - * Imports attachment. - * - * @param waveId the id of the wave to import. - * @param waveletId the id of the wavelet to import. - * @param attachmentId the id of attachment. - * @param attachmentData the data of attachment. - * @param rpcServerUrl the URL of the JSON-RPC request handler. - * @throws IOException if there is a problem fetching the wavelet. - */ - public void importAttachment(WaveId waveId, WaveletId waveletId, AttachmentId attachmentId, - RawAttachmentData attachmentData, String rpcServerUrl) throws IOException { - OperationQueue opQueue = new OperationQueue(); - opQueue.importAttachment(waveId, waveletId, attachmentId, attachmentData); - - makeSingleOperationRpc(opQueue, rpcServerUrl); - } - - /** - * @return the map of consumer key and secret. - */ - protected Map<String, ConsumerData> getConsumerDataMap() { - return consumerDataMap; - } - - /** - * @return {@code true} if this service object contains a consumer key and - * secret for the given RPC server URL. - */ - protected boolean hasConsumerData(String rpcServerUrl) { - return consumerDataMap.containsKey(rpcServerUrl); - } - - /** - * Submits the given operation. - * - * @param opQueue the operation queue with operation to be submitted. - * @param rpcServerUrl the active gateway to send the operations to. - * @return the data of response. - * @throws IllegalStateException if this method is called prior to setting the - * proper consumer key, secret, and handler URL. - * @throws IOException if there is a problem submitting the operations, or error response. - */ - private Map<ParamsProperty, Object> makeSingleOperationRpc(OperationQueue opQueue, String rpcServerUrl) - throws IOException { - JsonRpcResponse response = makeRpc(opQueue, rpcServerUrl).get(0); - if (response.isError()) { - throw new IOException(response.getErrorMessage()); - } - return response.getData(); - } - - /** - * Submits the given operations. - * - * @param opQueue the operation queue to be submitted. - * @param rpcServerUrl the active gateway to send the operations to. - * @return a list of {@link JsonRpcResponse} that represents the responses - * from the server for all operations that were submitted. - * - * @throws IllegalStateException if this method is called prior to setting the - * proper consumer key, secret, and handler URL. - * @throws IOException if there is a problem submitting the operations. - */ - private List<JsonRpcResponse> makeRpc(OperationQueue opQueue, String rpcServerUrl) - throws IOException { - if (rpcServerUrl == null) { - throw new IllegalStateException("RPC Server URL is not set up."); - } - - ConsumerData consumerDataObj = consumerDataMap.get(rpcServerUrl); - if (consumerDataObj == null) { - throw new IllegalStateException("Consumer key, consumer secret, and JSON-RPC server URL " - + "have to be set first, by calling AbstractRobot.setupOAuth(), before invoking " - + "AbstractRobot.submit()."); - } - - opQueue.notifyRobotInformation(PROTOCOL_VERSION, version); - String json = - SERIALIZER.toJson(opQueue.getPendingOperations(), GsonFactory.OPERATION_REQUEST_LIST_TYPE); - - try { - InputStream bodyStream; - InputStream responseStream; - try { - bodyStream = new ByteArrayInputStream(json.getBytes("UTF-8")); - } catch (UnsupportedEncodingException e) { - throw new IllegalStateException(e); - } - if (!consumerDataObj.isUserAuthenticated()) { - String url = createOAuthUrlString( - json, consumerDataObj.getRpcServerUrl(), consumerDataObj.getAccessor()); - if (LOG.isLoggable(Level.FINE)) { - LOG.fine("JSON request to be sent: " + json); - } - HttpMessage request = new HttpMessage("POST", new URL(url), bodyStream); - request.headers.add( - new SimpleEntry<String, String>(HttpMessage.CONTENT_TYPE, JSON_MIME_TYPE)); - request.headers.add(new SimpleEntry<String, String>("oauth_version", "1.0")); - responseStream = - httpFetcher.execute(request, Collections.<String, Object>emptyMap()).getBody(); - } else { - OAuthAccessor accessor = consumerDataObj.getAccessor(); - OAuthMessage message = accessor.newRequestMessage("POST", rpcServerUrl, null, bodyStream); - message.getHeaders().add( - new SimpleEntry<String, String>(HttpMessage.CONTENT_TYPE, JSON_MIME_TYPE)); - message.getHeaders().add(new SimpleEntry<String, String>("oauth_version", "1.0")); - OAuthClient client = new OAuthClient(httpFetcher); - responseStream = client.invoke(message, net.oauth.ParameterStyle.BODY).getBodyAsStream(); - } - - String responseString = HttpFetcher.readInputStream(responseStream); - if (LOG.isLoggable(Level.FINE)) { - LOG.fine("Response returned: " + responseString); - } - - List<JsonRpcResponse> responses = null; - if (responseString.startsWith("[")) { - responses = SERIALIZER.fromJson(responseString, GsonFactory.JSON_RPC_RESPONSE_LIST_TYPE); - } else { - responses = new ArrayList<JsonRpcResponse>(1); - responses.add(SERIALIZER.fromJson(responseString, JsonRpcResponse.class)); - } - responses.remove(0); // removes response to the notify operation. - return responses; - } catch (OAuthException e) { - LOG.warning("OAuthException when constructing the OAuth parameters: " + e); - throw new IOException(e); - } catch (URISyntaxException e) { - LOG.warning("URISyntaxException when constructing the OAuth parameters: " + e); - throw new IOException(e); - } - } - - /** - * Creates a URL that contains the necessary OAuth query parameters for the - * given JSON string. - * - * The required OAuth parameters are: - * <ul> - * <li>oauth_body_hash</li> - * <li>oauth_consumer_key</li> - * <li>oauth_signature_method</li> - * <li>oauth_timestamp</li> - * <li>oauth_nonce</li> - * <li>oauth_version</li> - * <li>oauth_signature</li> - * </ul> - * - * @param jsonBody the JSON string to construct the URL from. - * @param rpcServerUrl the URL of the handler that services the JSON-RPC - * request. - * @param accessor the OAuth accessor used to create the signed string. - * @return a URL for the given JSON string, and the required OAuth parameters. - */ - public static String createOAuthUrlString( - String jsonBody, String rpcServerUrl, OAuthAccessor accessor) - throws IOException, URISyntaxException, OAuthException { - OAuthMessage message = - new OAuthMessage(POST, rpcServerUrl, Collections.<SimpleEntry<String, String>>emptyList()); - - // Compute the hash of the body. - byte[] rawBody = jsonBody.getBytes(UTF_8); - byte[] hash = DigestUtils.sha(rawBody); - byte[] encodedHash = Base64.encodeBase64(hash); - message.addParameter(OAUTH_BODY_HASH, new String(encodedHash, UTF_8)); - - // Add other parameters. - - message.addRequiredParameters(accessor); - if (LOG.isLoggable(Level.FINE)) { - LOG.fine("Signature base string: " + OAuthSignatureMethod.getBaseString(message)); - } - - // Construct the resulting URL. - StringBuilder sb = new StringBuilder(rpcServerUrl); - char connector = '?'; - for (Map.Entry<String, String> p : message.getParameters()) { - if (!p.getKey().equals(jsonBody)) { - sb.append(connector); - sb.append(URLEncoder.encode(p.getKey(), UTF_8)); - sb.append('='); - sb.append(URLEncoder.encode(p.getValue(), UTF_8)); - connector = '&'; - } - } - return sb.toString(); - } - - /** - * Sets the fetch timeout to a specified timeout, in milliseconds. - * A timeout of zero is interpreted as an infinite timeout. - * - * @param fetchTimeout - */ - public void setFetchFimeout(int fetchTimeout) { - httpFetcher.setTimeout(fetchTimeout); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/com/google/wave/api/Wavelet.java ---------------------------------------------------------------------- diff --git a/src/com/google/wave/api/Wavelet.java b/src/com/google/wave/api/Wavelet.java deleted file mode 100644 index b132747..0000000 --- a/src/com/google/wave/api/Wavelet.java +++ /dev/null @@ -1,680 +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; - -import com.google.wave.api.Participants.Role; -import com.google.wave.api.impl.WaveletData; - -import org.waveprotocol.wave.model.id.InvalidIdException; -import org.waveprotocol.wave.model.id.WaveId; -import org.waveprotocol.wave.model.id.WaveletId; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Map.Entry; - -/** - * A class that models a single wavelet instance. - * - * A single wavelet is composed of metadata, for example, id,creator, creation - * time, last modified time, title. A wavelet is also composed of a set of - * participants, a set of tags, a list of blips, and a data document, which - * is a map of key-value pairs of data. - */ -public class Wavelet implements Serializable { - - /** Delimiter constants for robot participant id. */ - private static final char ROBOT_ID_PROXY_DELIMITER = '+'; - private static final char ROBOT_ID_VERSION_DELIMITER = '#'; - private static final char ROBOT_ID_DOMAIN_DELIMITER = '@'; - - /** The id of the wave that owns this wavelet. */ - private transient WaveId waveId; - - /** The id of this wavelet. */ - private transient WaveletId waveletId; - - /** The serialized form of waveId **/ - private String serializedWaveId; - - /** The serialized form of waveletId **/ - private String serializedWaveletId; - - /** The participant id that created this wavelet. */ - private final String creator; - - /** This wavelet's creation time, in milliseconds. */ - private final long creationTime; - - /** This wavelet's last modified time, in milliseconds. */ - private final long lastModifiedTime; - - /** The id of the root blip of this wavelet. */ - private final String rootBlipId; - - /** The root thread of this wavelet. */ - private final BlipThread rootThread; - - /** The participants of this wavelet. */ - private final Participants participants; - - /** The data documents of this wavelet. */ - private final DataDocuments dataDocuments; - - /** The tags that this wavelet has. */ - private final Tags tags; - - /** The title of this wavelet. */ - private String title; - - /** The blips that are contained in this wavelet. */ - @NonJsonSerializable private final Map<String, Blip> blips; - - /** The conversation threads that are contained in this wavelet. */ - @NonJsonSerializable private final Map<String, BlipThread> threads; - - /** The operation queue to queue operation to the robot proxy. */ - @NonJsonSerializable private final OperationQueue operationQueue; - - /** The address of the current robot. */ - @NonJsonSerializable private String robotAddress; - - /** - * Constructor. - * - * @param waveId the id of the wave that owns this wavelet. - * @param waveletId the id of this wavelet. - * @param creator the creator of this wavelet. - * @param creationTime the creation time of this wavelet. - * @param lastModifiedTime the last modified time of this wavelet. - * @param title the title of this wavelet. - * @param rootBlipId the root blip id of this wavelet. - * @param rootThread the root thread of this wavelet. - * @param participantRoles the roles for those participants - * @param participants the participants of this wavelet. - * @param dataDocuments the data documents of this wavelet. - * @param tags the tags that this wavelet has. - * @param blips the blips that are contained in this wavelet. - * @param threads the conversation threads that are contained in this wavelet. - * @param operationQueue the operation queue to queue operation to the robot - * proxy. - */ - Wavelet(WaveId waveId, WaveletId waveletId, String creator, long creationTime, - long lastModifiedTime, String title, String rootBlipId, BlipThread rootThread, - Map<String, String> participantRoles, Set<String> participants, - Map<String, String> dataDocuments, Set<String> tags, Map<String, Blip> blips, - Map<String, BlipThread> threads, OperationQueue operationQueue) { - this.waveId = waveId; - this.waveletId = waveletId; - this.creator = creator; - this.creationTime = creationTime; - this.lastModifiedTime = lastModifiedTime; - this.title = title; - this.rootBlipId = rootBlipId; - this.rootThread = rootThread; - this.participants = new Participants(participants, participantRoles, this, operationQueue); - this.dataDocuments = new DataDocuments(dataDocuments, this, operationQueue); - this.tags = new Tags(tags, this, operationQueue); - this.blips = blips; - this.threads = threads; - this.operationQueue = operationQueue; - } - - /** - * Constructor. - * - * @param waveId the id of the wave that owns this wavelet. - * @param waveletId the id of this wavelet. - * @param rootBlipId the root blip id of this wavelet. - * @param rootThread the root thread of this wavelet. - * @param participants the participants of this wavelet. - * @param participantRoles the roles for those participants. - * @param blips the blips that are contained in this wavelet. - * @param threads the conversation threads that are contained in this wavelet. - * @param operationQueue the operation queue to queue operation to the robot - * proxy. - */ - Wavelet(WaveId waveId, WaveletId waveletId, String rootBlipId, BlipThread rootThread, - Set<String> participants, Map<String, String> participantRoles, Map<String, Blip> blips, - Map<String, BlipThread> threads, OperationQueue operationQueue) { - this.waveId = waveId; - this.waveletId = waveletId; - this.rootBlipId = rootBlipId; - this.rootThread = rootThread; - this.creator = null; - this.creationTime = -1; - this.lastModifiedTime = -1; - this.title = null; - this.participants = new Participants(participants, participantRoles, this, operationQueue); - this.dataDocuments = new DataDocuments(new HashMap<String, String>(), this, - operationQueue); - this.tags = new Tags(Collections.<String>emptySet(), this, operationQueue); - this.blips = blips; - this.threads = threads; - this.operationQueue = operationQueue; - } - - /** - * Shallow copy constructor. - * - * @param other the other {@link Wavelet} instance to copy. - * @param operationQueue the operation queue for this new wavelet instance. - */ - private Wavelet(Wavelet other, OperationQueue operationQueue) { - this.waveId = other.waveId; - this.waveletId = other.waveletId; - this.creator = other.creator; - this.creationTime = other.creationTime; - this.lastModifiedTime = other.lastModifiedTime; - this.title = other.title; - this.rootBlipId = other.rootBlipId; - this.rootThread = other.rootThread; - this.participants = other.participants; - this.dataDocuments = other.dataDocuments; - this.tags = other.tags; - this.blips = other.blips; - this.threads = other.threads; - this.robotAddress = other.robotAddress; - this.operationQueue = operationQueue; - } - - /** - * Returns the wave id that owns this wavelet. - * - * @return the wave id. - */ - public WaveId getWaveId() { - return waveId; - } - - /** - * Returns the id of this wavelet. - * - * @return the wavelet id. - */ - public WaveletId getWaveletId() { - return waveletId; - } - - /** - * Returns the participant id of the creator of this wavelet. - * - * @return the creator of this wavelet. - */ - public String getCreator() { - return creator; - } - - /** - * Returns the creation time of this wavelet. - * - * @return the wavelet's creation time. - */ - public long getCreationTime() { - return creationTime; - } - - /** - * Returns the last modified time of this wavelet. - * - * @return the wavelet's last modified time. - */ - public long getLastModifiedTime() { - return lastModifiedTime; - } - - /** - * Returns the data documents of this wavelet, which is a series of key-value - * pairs of data. - * - * @return an instance of {@link DataDocuments}, which represents the data - * documents of this wavelet. - */ - public DataDocuments getDataDocuments() { - return dataDocuments; - } - - /** - * Returns a list of participants of this wavelet. - * - * @return an instance of {@link Participants}, which represents the - * participants of this wavelet. - */ - public Participants getParticipants() { - return participants; - } - - /** - * Returns a list of tags of this wavelet. - * - * @return an instance of {@link Tags}, which represents the tags that have - * been associated with this wavelet. - */ - public Tags getTags() { - return tags; - } - - /** - * Returns the title of this wavelet. - * - * @return the wavelet title. - */ - public String getTitle() { - return title; - } - - /** - * Sets the wavelet title. - * - * @param title the new title to be set. - */ - public void setTitle(String title) { - if (title.contains("\n")) { - throw new IllegalArgumentException("Wavelet title should not contain a newline character. " + - "Specified: " + title); - } - - operationQueue.setTitleOfWavelet(this, title); - this.title = title; - - // Adjust the content of the root blip, if it is available in the context. - Blip rootBlip = getRootBlip(); - if (rootBlip != null) { - String content = "\n"; - int indexOfSecondNewline = rootBlip.getContent().indexOf('\n', 1); - if (indexOfSecondNewline != -1) { - content = rootBlip.getContent().substring(indexOfSecondNewline); - } - rootBlip.setContent("\n" + title + content); - } - } - - /** - * Returns the address of the robot that receives events or performs events - * on this wavelet. - * - * @return the robot address. - */ - public String getRobotAddress() { - return robotAddress; - } - - /** - * Sets the address of the robot that receives events or performs events on - * this wavelet. - * - * @param address the robot address. - * @throw IllegalStateException if this method has been called before. - */ - public void setRobotAddress(String address) { - if (this.robotAddress != null) { - throw new IllegalStateException("Robot address has been set previously to " + - this.robotAddress); - } - this.robotAddress = address; - } - - /** - * Returns the id of the root blip of this wavelet. - * - * @return the id of the root blip. - */ - public String getRootBlipId() { - return rootBlipId; - } - - /** - * Returns the root blip of this wavelet. - * - * @return an instance of {@link Blip} that represents the root blip of this - * wavelet. - */ - public Blip getRootBlip() { - return blips.get(rootBlipId); - } - - /** - * @return an instance of {@link BlipThread} that represents the root thread of - * this wavelet. - */ - public BlipThread getRootThread() { - return rootThread; - } - - /** - * Returns a blip with the given id. - * - * @return an instance of {@link Blip} that has the given blip id. - */ - public Blip getBlip(String blipId) { - return blips.get(blipId); - } - - /** - * Returns all blips that are in this wavelet. - * - * @return a map of blips in this wavelet, that is keyed by blip id. - */ - public Map<String, Blip> getBlips() { - return blips; - } - - /** - * Returns a thread with the given id. - * - * @param threadId the thread id. - * @return a thread that has the given thread id. - */ - public BlipThread getThread(String threadId) { - if (threadId == null || threadId.isEmpty()) { - return getRootThread(); - } - return threads.get(threadId); - } - - /** - * Returns all threads that are in this wavelet. - * - * @return a map of threads in this wavelet, that is keyed by thread id. - */ - public Map<String, BlipThread> getThreads() { - return threads; - } - - /** - * Adds a thread to this wavelet. - * - * @param thread the thread to add. - */ - protected void addThread(BlipThread thread) { - threads.put(thread.getId(), thread); - } - - /** - * Returns the operation queue that this wavelet uses to queue operation to - * the robot proxy. - * - * @return an instance of {@link OperationQueue} that represents this - * wavelet's operation queue. - */ - protected OperationQueue getOperationQueue() { - return operationQueue; - } - - /** - * Returns the domain of this wavelet. - * - * @return the wavelet domain, which is encoded in the wave/wavelet id. - */ - public String getDomain() { - return waveId.getDomain(); - } - - /** - * Returns a view of this wavelet that will proxy for the specified id. - * - * A shallow copy of the current wavelet is returned with the - * {@code proxyingFor} field set. Any modifications made to this copy will be - * done using the {@code proxyForId}, i.e. the - * {@code robot+<proxyForId>@appspot.com} address will be used. - * - * If the wavelet was retrieved using the Active Robot API, that is - * by {@code fetchWavelet}, then the address of the robot must be added to the - * wavelet by calling {@code setRobotAddress} with the robot's address - * before calling {@code proxy_for}. - * - * @param proxyForId the id to proxy. Please note that this parameter should - * be properly encoded to ensure that the resulting participant id is - * valid (see {@link Util#checkIsValidProxyForId(String)} for more - * details). - * @return a shallow copy of this wavelet with the proxying information set. - */ - public Wavelet proxyFor(String proxyForId) { - Util.checkIsValidProxyForId(proxyForId); - addProxyingParticipant(proxyForId); - OperationQueue proxiedOperationQueue = operationQueue.proxyFor(proxyForId); - return new Wavelet(this, proxiedOperationQueue); - } - - /** - * Submit this wavelet when the given {@code other} wavelet is submitted. - * - * Wavelets constructed outside of the event callback need to - * be either explicitly submitted using {@code AbstractRobot.submit(Wavelet)} - * or be associated with a different wavelet that will be submitted or is part - * of the event callback. - * - * @param other the other wavelet whose operation queue will be joined with. - */ - public void submitWith(Wavelet other) { - operationQueue.submitWith(other.operationQueue); - } - - /** - * Replies to the conversation in this wavelet. - * - * @param initialContent the initial content of the reply. - * @return an instance of {@link Blip} that represents a transient version of - * the reply. - * - * @throws IllegalArgumentException if {@code initialContent} does not start - * with a newline character. - */ - public Blip reply(String initialContent) { - if (initialContent == null || !initialContent.startsWith("\n")) { - throw new IllegalArgumentException("Initial content should start with a newline character"); - } - return operationQueue.appendBlipToWavelet(this, initialContent); - } - - /** - * Removes a blip from this wavelet. - * - * @param blip the blip to be removed. - */ - public void delete(Blip blip) { - delete(blip.getBlipId()); - } - - /** - * Removes a blip from this wavelet. - * - * @param blipId the id of the blip to be removed. - */ - public void delete(String blipId) { - operationQueue.deleteBlip(this, blipId); - Blip removed = blips.remove(blipId); - - if (removed != null) { - // Remove the blip from the parent blip. - Blip parentBlip = removed.getParentBlip(); - if (parentBlip != null) { - parentBlip.deleteChildBlipId(blipId); - } - - // Remove the blip from the containing thread. - BlipThread thread = removed.getThread(); - if (thread != null) { - thread.removeBlip(removed); - } - - // If the containing thread is now empty, remove it from the parent blip - // and from the wavelet. - if (thread != null && parentBlip != null && thread.isEmpty()) { - parentBlip.removeThread(thread); - threads.remove(thread.getId()); - } - } - } - - /** - * Ads a proxying participant to the wave. - * - * Proxying participants are of the form {@code [email protected]}. This - * convenience method constructs this id and then calls - * {@code wavelet.addParticipant()} operation. - * - * @param proxyForId the id to proxy. - */ - private void addProxyingParticipant(String proxyForId) { - if (robotAddress == null || robotAddress.isEmpty()) { - throw new IllegalStateException("Need a robot address to add a proxying for participant."); - } - - // Parse the id and the domain. - int index = robotAddress.indexOf(ROBOT_ID_DOMAIN_DELIMITER); - String newId = robotAddress.substring(0, index); - String domain = robotAddress.substring(index + 1); - - // Parse the version. - String version = null; - index = newId.indexOf(ROBOT_ID_VERSION_DELIMITER); - if (index != -1) { - version = newId.substring(index + 1); - newId = newId.substring(0, index); - } - - // Remove the previous proxying id. - index = newId.indexOf(ROBOT_ID_PROXY_DELIMITER); - if (index != -1) { - newId = newId.substring(0, index); - } - - // Assemble the new id. - newId += ROBOT_ID_PROXY_DELIMITER + proxyForId; - if (version != null) { - newId += ROBOT_ID_VERSION_DELIMITER + version; - } - newId += ROBOT_ID_DOMAIN_DELIMITER + domain; - participants.add(newId); - } - - /** - * Serializes this {@link Wavelet} into a {@link WaveletData}. - * - * @return an instance of {@link WaveletData} that represents this wavelet. - */ - public WaveletData serialize() { - WaveletData waveletData = new WaveletData(); - - // Add primitive properties. - waveletData.setWaveId(ApiIdSerializer.instance().serialiseWaveId(waveId)); - waveletData.setWaveletId(ApiIdSerializer.instance().serialiseWaveletId(waveletId)); - waveletData.setCreator(creator); - waveletData.setCreationTime(creationTime); - waveletData.setLastModifiedTime(lastModifiedTime); - waveletData.setRootBlipId(rootBlipId); - waveletData.setRootThread(rootThread); - waveletData.setTitle(title); - - // Add tags. - List<String> tags = new ArrayList<String>(); - for (String tag : this.tags) { - tags.add(tag); - } - waveletData.setTags(tags); - - // Add participants. - List<String> participants = new ArrayList<String>(); - for (String participant : this.participants) { - participants.add(participant); - Role role = getParticipants().getParticipantRole(participant); - waveletData.setParticipantRole(participant, role.name()); - } - waveletData.setParticipants(participants); - - // Add data documents. - Map<String, String> dataDocuments = new HashMap<String, String>(); - for (Entry<String, String> entry : this.dataDocuments) { - dataDocuments.put(entry.getKey(), entry.getValue()); - } - waveletData.setDataDocuments(dataDocuments); - - return waveletData; - } - - /** - * Deserializes the given {@link WaveletData} object into an instance of - * {@link Wavelet}. - * - * @param operationQueue the operation queue. - * @param blips the map of blips that are in this wavelet. - * @param waveletData the wavelet data to be deserialized. - * @return an instance of {@link Wavelet}. - */ - public static Wavelet deserialize(OperationQueue operationQueue, Map<String, Blip> blips, - Map<String, BlipThread> threads, WaveletData waveletData) { - WaveId waveId; - WaveletId waveletId; - try { - waveId = ApiIdSerializer.instance().deserialiseWaveId(waveletData.getWaveId()); - waveletId = ApiIdSerializer.instance().deserialiseWaveletId(waveletData.getWaveletId()); - } catch (InvalidIdException e) { - throw new IllegalArgumentException(e); - } - String creator = waveletData.getCreator(); - long creationTime = waveletData.getCreationTime(); - long lastModifiedTime = waveletData.getLastModifiedTime(); - String rootBlipId = waveletData.getRootBlipId(); - - BlipThread originalRootThread = waveletData.getRootThread(); - List<String> rootThreadBlipIds = originalRootThread == null ? - new ArrayList<String>() : - new ArrayList<String>(originalRootThread.getBlipIds()); - BlipThread rootThread = new BlipThread("", -1, rootThreadBlipIds, blips); - - String title = waveletData.getTitle(); - Set<String> participants = new LinkedHashSet<String>(waveletData.getParticipants()); - Set<String> tags = new LinkedHashSet<String>(waveletData.getTags()); - Map<String, String> dataDocuments = waveletData.getDataDocuments(); - Map<String, String> roles = waveletData.getParticipantRoles(); - - return new Wavelet(waveId, waveletId, creator, creationTime, lastModifiedTime, title, - rootBlipId, rootThread, roles, participants, dataDocuments, tags, blips, threads, - operationQueue); - } - - private void writeObject(ObjectOutputStream out) throws IOException { - serializedWaveId = ApiIdSerializer.instance().serialiseWaveId(waveId); - serializedWaveletId = ApiIdSerializer.instance().serialiseWaveletId(waveletId); - out.defaultWriteObject(); - } - - private void readObject(ObjectInputStream in) throws IOException, InvalidIdException { - try { - in.defaultReadObject(); - } catch(ClassNotFoundException e) { - // Fatal. - throw new IOException("Incorrect serial versions" + e); - } - - waveId = ApiIdSerializer.instance().deserialiseWaveId(serializedWaveId); - waveletId = ApiIdSerializer.instance().deserialiseWaveletId(serializedWaveletId); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/com/google/wave/api/build.xml ---------------------------------------------------------------------- diff --git a/src/com/google/wave/api/build.xml b/src/com/google/wave/api/build.xml deleted file mode 100644 index 373cd6a..0000000 --- a/src/com/google/wave/api/build.xml +++ /dev/null @@ -1,25 +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. ---> -<project name="api"> - <import file="${build.common.path}"/> - <property name="libname" value="wave-api-${waveinabox.version}"/> - <patternset id="srcs"> - <include name="com/google/wave/api/**"/> - </patternset> -</project> http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/com/google/wave/api/data/ApiView.java ---------------------------------------------------------------------- diff --git a/src/com/google/wave/api/data/ApiView.java b/src/com/google/wave/api/data/ApiView.java deleted file mode 100644 index f3a9eb9..0000000 --- a/src/com/google/wave/api/data/ApiView.java +++ /dev/null @@ -1,419 +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.data; - -import com.google.common.base.Preconditions; -import com.google.common.base.Splitter; -import com.google.common.collect.Lists; -import com.google.wave.api.Element; -import com.google.wave.api.ElementType; -import com.google.wave.api.Gadget; -import com.google.wave.api.Line; - -import org.waveprotocol.wave.model.conversation.Blips; -import org.waveprotocol.wave.model.document.Doc; -import org.waveprotocol.wave.model.document.Doc.E; -import org.waveprotocol.wave.model.document.Doc.N; -import org.waveprotocol.wave.model.document.Doc.T; -import org.waveprotocol.wave.model.document.Document; -import org.waveprotocol.wave.model.document.util.Point; -import org.waveprotocol.wave.model.document.util.XmlStringBuilder; -import org.waveprotocol.wave.model.util.Pair; -import org.waveprotocol.wave.model.wave.Wavelet; - -import java.util.List; - -/** - * Class to represent a document in api view. - * - * - */ -public class ApiView { - - /** - * Simple class to export info about elements in the ApiView. - */ - public static class ElementInfo { - public final Element element; - public final int apiPosition; - public final int xmlPosition; - - public ElementInfo(Element element, int apiPosition, int xmlPosition) { - this.element = element; - this.apiPosition = apiPosition; - this.xmlPosition = xmlPosition; - } - } - - /** - * Storage class to store a bit of the view. It's more a struct than a class. - * Either the content or the element field is set. - */ - private static class Bit { - public String string; - public Element element; - private int xmlPos; - private int xmlSize; - - Bit(Element element, int xmlPos, int xmlSize) { - this.element = element; - this.string = null; - this.xmlPos = xmlPos; - this.xmlSize = xmlSize; - } - - Bit(String string, int xmlPos) { - this.element = null; - this.string = string; - this.xmlPos = xmlPos; - this.xmlSize = string.length(); - } - - /** - * @returns the length of the specified bit. 1 for an element, the string - * length for a string. - */ - public int size() { - if (string != null) { - return string.length(); - } - return 1; - } - } - - private final Document doc; - private final List<Bit> bits = Lists.newArrayList(); - private Wavelet wavelet; - - public ApiView(Document doc, Wavelet wavelet) { - this.doc = doc; - this.wavelet = wavelet; - parse(doc); - } - - private void parse(Document doc) { - E bodyElement = Blips.getBody(doc); - if (bodyElement != null) { - N child = doc.getFirstChild(bodyElement); - while (child != null) { - T asText = doc.asText(child); - int xmlPos = doc.getLocation(child); - if (asText != null) { - bits.add(new Bit(doc.getData(asText), xmlPos)); - } else { - E xmlElement = doc.asElement(child); - if (xmlElement != null) { - Element element = ElementSerializer.xmlToApiElement(doc, xmlElement, wavelet); - // element can be null, but we still want to note that there - // was something unknown. - N next = doc.getNextSibling(child); - int xmlSize; - if (next != null) { - xmlSize = doc.getLocation(next) - xmlPos; - } else { - // At the end of the document. XmlSize is the rest. - xmlSize = doc.size() - 1 - xmlPos; - } - bits.add(new Bit(element, xmlPos, xmlSize)); - } - } - child = doc.getNextSibling(child); - } - } - } - - /** - * Delete the stuff between start and end not including end. - */ - public void delete(int start, int end) { - int len = end - start; - Pair<Integer, Integer> where = locate(start); - int index = where.first; - if (index == bits.size()) { - // outside - return; - } - int offset = where.second; - int xmlStart = bits.get(index).xmlPos + offset; - int xmlEnd = xmlStart; - while (len > 0) { - Bit bit = bits.get(index); - if (bit.string == null) { - // deleting an element: - len -= 1; - shift(index + 1, -bit.xmlSize); - xmlEnd += bit.xmlSize; - bits.remove(index); - } else { - // deleting a string bit - int todelete = bit.string.length() - offset; - if (todelete > len) { - todelete = len; - } - shift(index + 1, -todelete); - xmlEnd += todelete; - len -= todelete; - if (offset > 0) { - bit.string = bit.string.substring(0, offset) + bit.string.substring(offset + todelete); - index += 1; - offset = 0; - } else { - if (todelete < bit.string.length()) { - bit.string = bit.string.substring(todelete); - } else { - bits.remove(index); - } - } - } - } - doc.deleteRange(xmlStart, xmlEnd); - } - - public void insert(int pos, Element element) { - XmlStringBuilder xml = ElementSerializer.apiElementToXml(element); - int beforeSize = doc.size(); - Pair<Integer, Integer> where = locate(pos); - int index = where.first; - if (index == bits.size()) { - // outside. append. - Bit last = bits.get(bits.size() - 1); - Point<Doc.N> point = doc.locate(last.xmlPos + last.xmlSize); - doc.insertXml(point, xml); - bits.add(new Bit(element, last.xmlPos + last.xmlSize, doc.size() - beforeSize)); - return; - } - int offset = where.second; - Bit bit = bits.get(index); - Point<Doc.N> point = doc.locate(bit.xmlPos + offset); - doc.insertXml(point, xml); - int xmlSize = doc.size() - beforeSize; - if (bit.string != null && offset > 0) { - shift(index + 1, xmlSize); - String leftOver = bit.string.substring(offset); - bit.string = bit.string.substring(0, offset); - bit.xmlSize = offset; - int nextIndex = bit.xmlPos + bit.xmlSize; - bits.add(index + 1, new Bit(element, nextIndex, xmlSize)); - nextIndex += xmlSize; - bits.add(index + 2, new Bit(leftOver, nextIndex)); - } else { - bits.add(index, new Bit(element, bits.get(index).xmlPos, xmlSize)); - shift(index + 1, xmlSize); - } - } - - public void insert(int pos, String content) { - boolean first = true; - for (String paragraph : Splitter.on("\n").split(content)) { - if (first) { - first = false; - } else { - insert(pos, new Line()); - pos++; - } - Pair<Integer, Integer> where = locate(pos); - int index = where.first; - if (index == bits.size()) { - // outside. append. - Bit last = bits.get(bits.size() - 1); - bits.add(new Bit(paragraph, last.xmlPos + last.xmlSize)); - doc.insertText(last.xmlPos + last.xmlSize, paragraph); - } else { - int offset = where.second; - Bit bit = bits.get(index); - doc.insertText(bit.xmlPos + offset, paragraph); - if (bit.string != null) { - // if it's a string, add to the existing node - bit.string = bit.string.substring(0, offset) + paragraph + bit.string.substring(offset); - bit.xmlSize += paragraph.length(); - } else { - // if it's an element, insert just before - bits.add(index, new Bit(paragraph, bits.get(index).xmlPos - paragraph.length())); - } - shift(index + 1, paragraph.length()); - } - pos += paragraph.length(); - } - } - - /** - * Increment the xmlPos of everything from bitIndex and up by delta - * - * @param bitIndex - * @param delta - */ - private void shift(int bitIndex, int delta) { - for (int i = bitIndex; i < bits.size(); i++) { - bits.get(i).xmlPos += delta; - } - } - - /** - * Find which bit contains offset. - * - * @param offset - * @return the index of the bit plus whatever was left over or null when - * offset is outside the document. - */ - private Pair<Integer, Integer> locate(int offset) { - int index = 0; - while (bits.size() > index && bits.get(index).size() <= offset) { - offset -= bits.get(index).size(); - index++; - } - return Pair.of(index, offset); - } - - /** - * @returns the api representation of the current contents - */ - public String apiContents() { - StringBuilder res = new StringBuilder(); - for (Bit bit : bits) { - if (bit.string != null) { - res.append(bit.string); - } else { - if (bit.element != null && bit.element.getType().equals(ElementType.LINE)) { - res.append('\n'); - } else { - res.append(' '); - } - } - } - return res.toString(); - } - - /** - * @returns a list of ElementInfo's describing the elements in view. - */ - public List<ElementInfo> getElements() { - List<ElementInfo> res = Lists.newArrayList(); - int index = 0; - for (Bit bit : bits) { - if (bit.element != null) { - res.add(new ElementInfo(bit.element, index, bit.xmlPos)); - } - index += bit.size(); - } - return res; - } - - /** - * Transforms the given {@code xmlOffset} into the text offset. - * - * @param xmlOffset the xml offset to transform. - * @returns the text offset corresponding to the given xml offset. - * - * @throws IllegalArgumentException if the given {@code xmlOffset} is out of - * range. - */ - public int transformToTextOffset(int xmlOffset) { - // Make sure that the offset is valid. - Preconditions.checkArgument(xmlOffset >= 0); - Preconditions.checkArgument(xmlOffset <= doc.size()); - - // Find the right bit that contains the xml offset. - int index = 0; - int textOffset = 0; - while (index < bits.size() - && bits.get(index).xmlPos + bits.get(index).xmlSize - 1 < xmlOffset) { - Bit bit = bits.get(index++); - textOffset += bit.string != null ? bit.string.length() : 1; - } - - // Check if it is beyond the last bit, which is the closing </body> tag. In - // this case, just return textOffset. - if (index == bits.size()) { - return textOffset; - } - - // Return the offset. - Bit bit = bits.get(index); - if (bit.element != null) { - return textOffset; - } - return textOffset + xmlOffset - bit.xmlPos; - } - - /** - * @returns the xml index corresponding to the passed apiIndex. - */ - public int transformToXmlOffset(int apiIndex) { - Pair<Integer, Integer> where = locate(apiIndex); - int index = where.first; - int offset = where.second; - if (index == bits.size()) { - // We're beyond the last bit. Return last bit + offset. - Bit last = bits.get(bits.size() - 1); - return last.xmlPos + last.xmlSize + offset; - } - return bits.get(index).xmlPos + offset; - } - - /** - * Legacy support method. Return the index of the element that looks like the - * one we passed for some value of looks like. - */ - public int locateElement(Element element) { - int index = 0; - for (Bit bit : bits) { - if (bit.element != null && bit.element.getType().equals(element.getType())) { - if (element.getType().equals(ElementType.GADGET)) { - if (propertyMatch(bit.element, element, Gadget.URL)) { - return index; - } - } else if (element.getType().equals(ElementType.LABEL)) { - if (propertyMatch(bit.element, element, "for")) { - return index; - } - } else if (elementMatch(element, bit.element)) { - return index; - } - } - index += bit.size(); - } - return -1; - } - - private boolean propertyMatch(Element element1, Element element2, String prop) { - String val1 = element1.getProperty(prop); - String val2 = element2.getProperty(prop); - return val1 != null && val1.equals(val2); - } - - private boolean elementMatch(Element element1, Element element2) { - // TODO(ljvderijk): Elements should define their own equals method for each - // different type, improvements to the ElementSerializer can also be made. - return element1.getProperties().equals(element2.getProperties()); - } - - /** - * Call reparse when modifications to the underlying documents have been made - * and the api view needs to be updated. - * - * <p> - * TODO(user): Remove this once everything useful can be done through - * ApiView. - */ - public void reparse() { - bits.clear(); - parse(doc); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/com/google/wave/api/data/Data.gwt.xml ---------------------------------------------------------------------- diff --git a/src/com/google/wave/api/data/Data.gwt.xml b/src/com/google/wave/api/data/Data.gwt.xml deleted file mode 100644 index 7b6b301..0000000 --- a/src/com/google/wave/api/data/Data.gwt.xml +++ /dev/null @@ -1,35 +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. - --> -<?xml version="1.0" encoding="utf-8"?> -<module> - <inherits name="com.google.gwt.user.User"/> - <inherits name="org.waveprotocol.wave.model.Model"/> - <inherits name="org.waveprotocol.wave.model.account.Account"/> - <inherits name="org.waveprotocol.wave.model.conversation.Conversation"/> - <inherits name="org.waveprotocol.wave.model.util.Util"/> - - <source path=""/> - - <source path="converter"/> - - <source path="converter/v21"/> - - <source path="converter/v22"/> - -</module>
