http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/box/server/robots/operations/DocumentModifyService.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/DocumentModifyService.java b/wave/src/main/java/org/waveprotocol/box/server/robots/operations/DocumentModifyService.java deleted file mode 100644 index 166c360..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/DocumentModifyService.java +++ /dev/null @@ -1,545 +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 org.waveprotocol.box.server.robots.operations; - -import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; -import com.google.wave.api.Element; -import com.google.wave.api.Gadget; -import com.google.wave.api.InvalidRequestException; -import com.google.wave.api.JsonRpcConstant.ParamsProperty; -import com.google.wave.api.OperationRequest; -import com.google.wave.api.Range; -import com.google.wave.api.data.ApiView; -import com.google.wave.api.data.DocumentHitIterator; -import com.google.wave.api.data.ElementSerializer; -import com.google.wave.api.impl.DocumentModifyAction; -import com.google.wave.api.impl.DocumentModifyAction.BundledAnnotation; -import com.google.wave.api.impl.DocumentModifyAction.ModifyHow; -import com.google.wave.api.impl.DocumentModifyQuery; - -import org.waveprotocol.box.server.robots.OperationContext; -import org.waveprotocol.box.server.robots.util.OperationUtil; -import org.waveprotocol.wave.model.conversation.ObservableConversation; -import org.waveprotocol.wave.model.document.Doc; -import org.waveprotocol.wave.model.document.Document; -import org.waveprotocol.wave.model.document.RangedAnnotation; -import org.waveprotocol.wave.model.document.util.LineContainers; -import org.waveprotocol.wave.model.document.util.Point; -import org.waveprotocol.wave.model.document.util.XmlStringBuilder; -import org.waveprotocol.wave.model.gadget.GadgetXmlUtil; -import org.waveprotocol.wave.model.wave.ParticipantId; -import org.waveprotocol.wave.model.wave.opbased.OpBasedWavelet; - -import java.util.Map; - -/** - * Implements the "document.modify" operations. - * - * <p> - * The documentModify operation has three bits: the where: where is the - * modification applied. a range, index, element or annotation can be specified. - * Any of these is the converted to a range. If nothing appropriate is - * specified, the entire document is taken. the how: do we insert (before), - * append or replace? the what: what is inserted/replaced. - * - * @author ljvder...@google.com (Lennard de Rijk) - */ -public class DocumentModifyService implements OperationService { - - @Override - public void execute( - OperationRequest operation, OperationContext context, ParticipantId participant) - throws InvalidRequestException { - String blipId = OperationUtil.getRequiredParameter(operation, ParamsProperty.BLIP_ID); - - DocumentModifyAction modifyAction = - OperationUtil.getRequiredParameter(operation, ParamsProperty.MODIFY_ACTION); - - OpBasedWavelet wavelet = context.openWavelet(operation, participant); - ObservableConversation conversation = - context.openConversation(operation, participant).getRoot(); - Document doc = context.getBlip(conversation, blipId).getContent(); - - ApiView view = new ApiView(doc, wavelet); - DocumentHitIterator hitIterator = getDocumentHitIterator(operation, view); - - switch (modifyAction.getModifyHow()) { - case ANNOTATE: - annotate(operation, doc, view, hitIterator, modifyAction); - break; - case CLEAR_ANNOTATION: - clearAnnotation(operation, doc, view, hitIterator, modifyAction); - break; - case DELETE: - delete(operation, view, hitIterator); - break; - case INSERT: - insert(operation, doc, view, hitIterator, modifyAction); - break; - case INSERT_AFTER: - insertAfter(operation, doc, view, hitIterator, modifyAction); - break; - case REPLACE: - replace(operation, doc, view, hitIterator, modifyAction); - break; - case UPDATE_ELEMENT: - updateElement(operation, doc, view, hitIterator, modifyAction); - break; - default: - throw new UnsupportedOperationException( - "Unsupported ModifyHow " + modifyAction.getModifyHow()); - } - } - - /** - * Returns the {@link DocumentHitIterator} for the area that needs to be - * modified as specified in the robot operation. - * - * @param operation the operation that specifies where the modifications need - * to be applied. - * @param view the {@link ApiView} of the document that needs to be modified. - * @throws InvalidRequestException if more than one "where" parameter is - * specified. - */ - private DocumentHitIterator getDocumentHitIterator(OperationRequest operation, ApiView view) - throws InvalidRequestException { - Range range = OperationUtil.getOptionalParameter(operation, ParamsProperty.RANGE); - Integer index = OperationUtil.getOptionalParameter(operation, ParamsProperty.INDEX); - DocumentModifyQuery query = - OperationUtil.getOptionalParameter(operation, ParamsProperty.MODIFY_QUERY); - - DocumentHitIterator hitIterator; - if (range != null) { - if (index != null || query != null) { - throw new InvalidRequestException( - "At most one parameter out of RANGE, INDEX and MODIFY_QUERY must be specified", - operation); - } - // Use the specified range - hitIterator = new DocumentHitIterator.Singleshot(range); - } else if (index != null) { - if (query != null) { // range is null. - throw new InvalidRequestException( - "At most one parameter out of RANGE, INDEX and MODIFY_QUERY must be specified", - operation); - } - // Use exactly the location of the index - hitIterator = new DocumentHitIterator.Singleshot(new Range(index, index + 1)); - } else if (query != null) { // range and index are both null. - // Use the query - hitIterator = new DocumentHitIterator.ElementMatcher( - view, query.getElementMatch(), query.getRestrictions(), query.getMaxRes()); - } else { - // Take entire document since nothing appropriate was specified - hitIterator = new DocumentHitIterator.Singleshot(new Range(0, view.apiContents().length())); - } - return hitIterator; - } - - /** - * Annotates the given ranges of the document as indicated by the - * {@link DocumentModifyAction}. - * - * @param operation the operation to execute. - * @param doc the document to annotate. - * @param view the view of the document. - * @param hitIterator iterates over the ranges to annotate, specified in - * {@link ApiView} offset. - * @param modifyAction the {@link DocumentModifyAction} specifying what the - * annotation is. - * @throws InvalidRequestException if the annotation could not be set. - */ - private void annotate(OperationRequest operation, Document doc, ApiView view, - DocumentHitIterator hitIterator, DocumentModifyAction modifyAction) - throws InvalidRequestException { - Preconditions.checkArgument( - modifyAction.getModifyHow() == ModifyHow.ANNOTATE, "This method only supports ANNOTATE"); - - String annotationKey = modifyAction.getAnnotationKey(); - - int valueIndex = 0; - Range range = hitIterator.next(); - while (range != null) { - int start = view.transformToXmlOffset(range.getStart()); - int end = view.transformToXmlOffset(range.getEnd()); - setDocumentAnnotation( - operation, doc, start, end, annotationKey, modifyAction.getValue(valueIndex)); - - valueIndex++; - range = hitIterator.next(); - } - } - - /** - * Clears the annotation for the given ranges of the document as indicated by - * the {@link DocumentModifyAction}. - * - * @param operation the operation to execute. - * @param doc the document to annotate. - * @param view the view of the document. - * @param hitIterator iterates over the ranges to remove the annotation from, - * specified in {@link ApiView} offset. - * @param modifyAction the {@link DocumentModifyAction} specifying what the - * key of the annotation is annotation is. - * @throws InvalidRequestException if the annotation could not be set. - */ - private void clearAnnotation(OperationRequest operation, Document doc, ApiView view, - DocumentHitIterator hitIterator, DocumentModifyAction modifyAction) - throws InvalidRequestException { - Preconditions.checkArgument(modifyAction.getModifyHow() == ModifyHow.CLEAR_ANNOTATION, - "This method only supports CLEAR_ANNOTATION"); - - String annotationKey = modifyAction.getAnnotationKey(); - - Range range = hitIterator.next(); - while (range != null) { - int start = view.transformToXmlOffset(range.getStart()); - int end = view.transformToXmlOffset(range.getEnd()); - setDocumentAnnotation(operation, doc, start, end, annotationKey, null); - - range = hitIterator.next(); - } - } - - /** - * Sets the annotation for a document. - * - * @param operation the operation requesting the annotation to be set. - * @param doc the document to change the annotation in. - * @param start where the annotation should start. - * @param end where the annotation should end. - * @param key the key of the annotation. - * @param value the value of the annotation. - * @throws InvalidRequestException if the annotation could not be set. - */ - private void setDocumentAnnotation( - OperationRequest operation, Document doc, int start, int end, String key, String value) - throws InvalidRequestException { - try { - doc.setAnnotation(start, end, key, value); - } catch (IndexOutOfBoundsException e) { - throw new InvalidRequestException( - "Can't set annotation for out of bounds indices " + e.getMessage(), operation, e); - } - } - - /** - * Deletes ranges of elements from a document as specified by the iterator. - * - * @param operation the operation to execute. - * @param view the view of the document. - * @param hitIterator iterates over the ranges of elements to delete. - * @throws InvalidRequestException if the specified range was invalid. - */ - private void delete(OperationRequest operation, ApiView view, DocumentHitIterator hitIterator) - throws InvalidRequestException { - Range range = hitIterator.next(); - while (range != null) { - int start = range.getStart(); - int end = range.getEnd(); - - if (start == 0) { - // Can't delete the first new line. - start = 1; - } - - if (start >= end) { - throw new InvalidRequestException( - "Invalid range specified, " + start + ">=" + end, operation); - } - - // Delete using the view. - view.delete(start, end); - // Shift the iterator to match the updated document. - hitIterator.shift(start, end - start); - - range = hitIterator.next(); - } - } - - /** - * Inserts elements at the position specified by the hitIterator. - * - * @param operation the operation that wants to insert elements. - * @param doc the document to insert elements in. - * @param view the {@link ApiView} of that document. - * @param hitIterator the iterator over the places where to insert. - * @param modifyAction the action that specifies what to insert. - * @throws InvalidRequestException if something goes wrong. - */ - private void insert(OperationRequest operation, Document doc, ApiView view, - DocumentHitIterator hitIterator, DocumentModifyAction modifyAction) - throws InvalidRequestException { - int valueIndex = 0; - Range range = hitIterator.next(); - while (range != null) { - int insertAt = range.getStart(); - - int inserted = insertInto(operation, doc, view, insertAt, modifyAction, valueIndex); - hitIterator.shift(insertAt, inserted); - - valueIndex++; - range = hitIterator.next(); - } - } - - /** - * Inserts elements after the position specified by the hitIterator. - * - * @param operation the operation that wants to insert elements. - * @param doc the document to insert elements in. - * @param view the {@link ApiView} of that document. - * @param hitIterator the iterator over the places where to insert. - * @param modifyAction the action that specifies what to insert. - * @throws InvalidRequestException if something goes wrong. - */ - private void insertAfter(OperationRequest operation, Document doc, ApiView view, - DocumentHitIterator hitIterator, DocumentModifyAction modifyAction) - throws InvalidRequestException { - int valueIndex = 0; - Range range = hitIterator.next(); - while (range != null) { - int insertAt = range.getEnd(); - - int inserted = insertInto(operation, doc, view, insertAt, modifyAction, valueIndex); - hitIterator.shift(insertAt, inserted); - - valueIndex++; - range = hitIterator.next(); - } - } - - /** - * Replaces elements at the position specified by the hitIterator with the - * elements specified in the {@link DocumentModifyAction}. - * - * @param operation the operation that wants to replace elements. - * @param doc the document to replace elements in. - * @param view the {@link ApiView} of that document. - * @param hitIterator the iterator over the places where to replace elements. - * @param modifyAction the action that specifies what to replace the elements - * with. - * @throws InvalidRequestException if something goes wrong. - */ - private void replace(OperationRequest operation, Document doc, ApiView view, - DocumentHitIterator hitIterator, DocumentModifyAction modifyAction) - throws InvalidRequestException { - int valueIndex = 0; - Range range = hitIterator.next(); - while (range != null) { - int replaceAt = range.getStart(); - - int numInserted = insertInto(operation, doc, view, replaceAt, modifyAction, valueIndex); - - // Remove the text after what was inserted (so it looks like it has been - // replaced). - view.delete(replaceAt + numInserted, range.getEnd() + numInserted); - - // Shift the iterator from the start of the replacement with the amount of - // characters that have been added. - int numRemoved = Math.min(0, range.getStart() - range.getEnd()); - hitIterator.shift(replaceAt, numInserted + numRemoved); - - valueIndex++; - range = hitIterator.next(); - } - } - - /** - * Inserts elements into the document at a specified location. - * - * @param operation the operation that wants to insert elements. - * @param doc the document to insert elements in. - * @param view the {@link ApiView} of that document. - * @param insertAt the {@link ApiView} value of where to insert elements. - * @param modifyAction the action that specifies what to insert. - * @param valueIndex the index to use for - * {@link DocumentModifyAction#getValue(int)}, to find out what to - * insert. - * @throws InvalidRequestException if something goes wrong. - */ - private int insertInto(OperationRequest operation, Document doc, ApiView view, int insertAt, - DocumentModifyAction modifyAction, int valueIndex) throws InvalidRequestException { - - if (modifyAction.hasTextAt(valueIndex)) { - String toInsert = modifyAction.getValue(valueIndex); - - if (insertAt == 0) { - // Make sure that we have a newline as first character. - if (!toInsert.isEmpty() && toInsert.charAt(0) != '\n') { - toInsert = '\n' + toInsert; - } - } - - // Insert text. - view.insert(insertAt, toInsert); - - // Do something with annotations? - if (modifyAction.getBundledAnnotations() != null) { - int annotationStart = view.transformToXmlOffset(insertAt); - int annotationEnd = view.transformToXmlOffset(insertAt + toInsert.length()); - - for (RangedAnnotation<String> annotation : - doc.rangedAnnotations(annotationStart, annotationEnd, null)) { - setDocumentAnnotation( - operation, doc, annotationStart, annotationEnd, annotation.key(), null); - } - - for (BundledAnnotation ia : modifyAction.getBundledAnnotations()) { - setDocumentAnnotation(operation, doc, annotationStart, annotationEnd, ia.key, ia.value); - } - } - return toInsert.length(); - } else { - Element element = modifyAction.getElement(valueIndex); - if (element != null) { - if (element.isGadget()) { - Gadget gadget = (Gadget) element; - XmlStringBuilder xml = - GadgetXmlUtil.constructXml(gadget.getUrl(), "", gadget.getAuthor(), null, - gadget.getProperties()); - // TODO (Yuri Z.) Make it possible to specify a location to insert the - // gadget and implement insertion at the specified location. - LineContainers.appendLine(doc, xml); - } else if (element.isFormElement()) { - XmlStringBuilder xml = ElementSerializer.apiElementToXml(element); - LineContainers.appendLine(doc, xml); - } else { - // TODO(ljvderijk): Inserting other elements. - throw new UnsupportedOperationException( - "Can't insert other elements than text and gadgets at the moment"); - } - } - // should return 1 since elements have a length of 1 in the ApiView; - return 1; - } - } - - /** - * Updates elements in the document. - * <b>Note</b>: Only gadget elements are supported, for now. - * - * @param operation the operation the operation that wants to update elements. - * @param doc the document to update elements in. - * @param view the {@link ApiView} of that document. - * @param hitIterator the iterator over the places where to update elements. - * @param modifyAction the action that specifies what to update. - * @throws InvalidRequestException if something goes wrong. - */ - private void updateElement(OperationRequest operation, Document doc, ApiView view, - DocumentHitIterator hitIterator, DocumentModifyAction modifyAction) - throws InvalidRequestException { - Range range = null; - for (int index = 0; ((range = hitIterator.next()) != null); ++index) { - Element element = modifyAction.getElement(index); - if (element != null) { - if (element.isGadget()) { - int xmlStart = view.transformToXmlOffset(range.getStart()); - Doc.E docElem = Point.elementAfter(doc, doc.locate(xmlStart)); - updateExistingGadgetElement(doc, docElem, element); - } else { - // TODO (Yuri Z.) Updating other elements. - throw new UnsupportedOperationException( - "Can't update other elements than gadgets at the moment"); - } - } - } - } - - /** - * Updates the existing gadget element properties. - * - * @param doc the document to update elements in. - * @param existingElement the gadget element to update. - * @param element the element that describes what existingElement should be - * updated with. - * @throws InvalidRequestException - */ - private void updateExistingGadgetElement(Document doc, Doc.E existingElement, - Element element) throws InvalidRequestException { - Preconditions.checkArgument(element.isGadget(), - "Called with non-gadget element type %s", element.getType()); - - String url = element.getProperty("url"); - if (url != null) { - doc.setElementAttribute(existingElement, "url", url); - } - Map<String, Doc.E> children = Maps.newHashMap(); - for (Doc.N child = doc.getFirstChild(existingElement); child != null; child = - doc.getNextSibling(child)) { - Doc.E childAsElement = doc.asElement(child); - if (childAsElement != null) { - String key = doc.getTagName(childAsElement); - if (key.equals("state")) { - key = key + " " + doc.getAttributes(childAsElement).get("name"); - } - children.put(key, childAsElement); - } - } - - for (Map.Entry<String, String> property : element.getProperties().entrySet()) { - // TODO (Yuri Z.) Support updating gadget metadata (author, title, thumbnail...) - // and user preferences. - String key = null; - String tag = null; - if (property.getKey().equals("title") || property.getKey().equals("thumbnail") - || property.getKey().equals("author")) { - key = property.getKey(); - tag = property.getKey(); - } else if (!property.getKey().equals("name") && !property.getKey().equals("pref") - && !property.getKey().equals("url")) { - // A state variable. - key = "state " + property.getKey(); - tag = "state"; - } else { - continue; - } - - String val = property.getValue(); - Doc.E child = children.get(key); - if (val == null) { - // Delete the property if value is null. - if (child == null) { - // Property does not exist, skipping. - continue; - } - doc.deleteNode(child); - } else { - if (child != null) { - if (tag.equals("state")) { - doc.setElementAttribute(child, "value", val); - } else { - doc.emptyElement(child); - Point<Doc.N> point = Point.<Doc.N> inElement(child, null); - doc.insertText(point, val); - } - } else { - XmlStringBuilder xml = GadgetXmlUtil.constructStateXml(property.getKey(), val); - doc.insertXml(Point.<Doc.N> inElement(existingElement, null), xml); - } - } - } - } - - public static DocumentModifyService create() { - return new DocumentModifyService(); - } -}
http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ExportAttachmentService.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ExportAttachmentService.java b/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ExportAttachmentService.java deleted file mode 100644 index 37ad048..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ExportAttachmentService.java +++ /dev/null @@ -1,96 +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 org.waveprotocol.box.server.robots.operations; - -import com.google.common.collect.ImmutableMap; -import com.google.inject.Inject; -import com.google.protobuf.ByteString; -import com.google.wave.api.InvalidRequestException; -import com.google.wave.api.JsonRpcConstant.ParamsProperty; -import com.google.wave.api.OperationRequest; -import com.google.wave.api.impl.RawAttachmentData; - -import org.waveprotocol.box.server.robots.OperationContext; -import org.waveprotocol.wave.model.id.InvalidIdException; -import org.waveprotocol.wave.model.wave.ParticipantId; -import org.waveprotocol.box.server.attachment.AttachmentService; -import org.waveprotocol.box.attachment.AttachmentMetadata; -import org.waveprotocol.wave.media.model.AttachmentId; -import org.waveprotocol.wave.util.logging.Log; -import org.waveprotocol.box.server.robots.util.OperationUtil; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; - -/** - * {@link OperationService} for the "exportAttachment" operation. - * - * @author akapla...@gmail.com (Andrew Kaplanov) - */ -public class ExportAttachmentService implements OperationService { - private static final Log LOG = Log.get(ExportAttachmentService.class); - - private final AttachmentService attachmentService; - - @Inject - private ExportAttachmentService(AttachmentService attachmentSerive) { - this.attachmentService = attachmentSerive; - } - - @Override - public void execute(OperationRequest operation, OperationContext context, ParticipantId participant) - throws InvalidRequestException { - AttachmentId attachmentId; - try { - attachmentId = AttachmentId.deserialise(OperationUtil.<String>getRequiredParameter(operation, - ParamsProperty.ATTACHMENT_ID)); - } catch (InvalidIdException ex) { - throw new InvalidRequestException("Invalid id", operation, ex); - } - AttachmentMetadata meta; - byte[] data; - try { - meta = attachmentService.getMetadata(attachmentId); - data = readInputStreamToBytes(attachmentService.getAttachment(attachmentId).getInputStream()); - } catch (IOException ex) { - LOG.info("Get attachment", ex); - context.constructErrorResponse(operation, ex.toString()); - return; - } - RawAttachmentData attachment = new RawAttachmentData(meta.getFileName(), meta.getCreator(), - data); - Map<ParamsProperty, Object> parameters = - ImmutableMap.<ParamsProperty, Object> of(ParamsProperty.ATTACHMENT_DATA, attachment); - context.constructResponse(operation, parameters); - } - - private static byte[] readInputStreamToBytes(InputStream in) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - byte[] buffer = new byte[256]; - int length; - while ((length = in.read(buffer)) != -1) { - out.write(buffer, 0, length); - } - return out.toByteArray(); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ExportDeltasService.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ExportDeltasService.java b/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ExportDeltasService.java deleted file mode 100644 index 3df5549..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ExportDeltasService.java +++ /dev/null @@ -1,135 +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 org.waveprotocol.box.server.robots.operations; - -import com.google.common.collect.ImmutableMap; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.wave.api.ApiIdSerializer; -import com.google.wave.api.InvalidRequestException; -import com.google.wave.api.JsonRpcConstant.ParamsProperty; -import com.google.wave.api.OperationRequest; -import com.google.wave.api.impl.RawDeltasListener; - -import org.waveprotocol.wave.model.id.InvalidIdException; -import org.waveprotocol.wave.model.wave.ParticipantId; -import org.waveprotocol.wave.util.logging.Log; -import org.waveprotocol.wave.model.id.WaveId; -import org.waveprotocol.wave.model.id.WaveletId; -import org.waveprotocol.wave.model.id.WaveletName; -import org.waveprotocol.wave.model.version.HashedVersion; -import org.waveprotocol.wave.federation.Proto.ProtocolWaveletDelta; -import org.waveprotocol.wave.model.operation.wave.TransformedWaveletDelta; -import org.waveprotocol.wave.federation.Proto.ProtocolHashedVersion; -import org.waveprotocol.box.server.robots.util.OperationUtil; -import org.waveprotocol.box.server.common.CoreWaveletOperationSerializer; -import org.waveprotocol.box.server.robots.OperationContext; -import org.waveprotocol.box.common.Receiver; - -import java.util.Map; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; - -/** - * {@link OperationService} for the "exportDeltas" operation. - * - * @author akapla...@gmail.com (Andrew Kaplanov) - */ -public class ExportDeltasService implements OperationService { - private static final Log LOG = Log.get(ExportDeltasService.class); - - private static final int GET_HISTORY_BYTES_LENGTH_LIMIT = 1000000; - - private ExportDeltasService() { - } - - public static ExportDeltasService create() { - return new ExportDeltasService(); - } - - @Override - public void execute(final OperationRequest operation, final OperationContext context, ParticipantId participant) - throws InvalidRequestException { - WaveId waveId; - WaveletId waveletId; - HashedVersion startVersion; - HashedVersion endVersion; - try { - waveId = ApiIdSerializer.instance().deserialiseWaveId( - OperationUtil.<String>getRequiredParameter(operation, ParamsProperty.WAVE_ID)); - waveletId = ApiIdSerializer.instance().deserialiseWaveletId( - OperationUtil.<String>getRequiredParameter(operation, ParamsProperty.WAVELET_ID)); - } catch (InvalidIdException ex) { - throw new InvalidRequestException("Invalid id", operation, ex); - } - startVersion = getVersionParameter(operation, ParamsProperty.FROM_VERSION); - endVersion = getVersionParameter(operation, ParamsProperty.TO_VERSION); - WaveletName waveletName = WaveletName.of(waveId, waveletId); - getDeltas(context, waveletName, participant, startVersion, endVersion, new RawDeltasListener() { - - @Override - public void onSuccess(List<byte[]> rawDeltas, byte[] rawTargetVersion) { - Map<ParamsProperty, Object> data = ImmutableMap.<ParamsProperty, Object> of( - ParamsProperty.RAW_DELTAS, rawDeltas, - ParamsProperty.TARGET_VERSION, rawTargetVersion); - context.constructResponse(operation, data); - } - - @Override - public void onFailire(String message) { - context.constructErrorResponse(operation, message); - } - }); - } - - private void getDeltas(OperationContext context, WaveletName waveletName, - ParticipantId participant, HashedVersion fromVersion, HashedVersion toVersion, - RawDeltasListener listener) throws InvalidRequestException { - final List<byte[]> deltaBytes = new LinkedList<byte[]>(); - final AtomicReference<HashedVersion> version = new AtomicReference<HashedVersion>(); - final AtomicInteger length = new AtomicInteger(0); - context.getDeltas(waveletName, participant, fromVersion, toVersion, new Receiver<TransformedWaveletDelta>() { - - @Override - public boolean put(TransformedWaveletDelta delta) { - ProtocolWaveletDelta protoDelta = CoreWaveletOperationSerializer.serialize(delta); - byte[] bytes = protoDelta.toByteArray(); - deltaBytes.add(bytes); - version.set(delta.getResultingVersion()); - return length.addAndGet(bytes.length) < GET_HISTORY_BYTES_LENGTH_LIMIT; - } - }); - listener.onSuccess(deltaBytes, CoreWaveletOperationSerializer.serialize(version.get()).toByteArray()); - } - - private HashedVersion getVersionParameter(OperationRequest operation, ParamsProperty parameter) - throws InvalidRequestException { - byte[] bytes = OperationUtil.<byte[]>getRequiredParameter( - operation, parameter); - ProtocolHashedVersion protoVersion; - try { - protoVersion = ProtocolHashedVersion.parseFrom(bytes); - } catch (InvalidProtocolBufferException ex) { - throw new InvalidRequestException("Invalid version " + parameter.key(), operation, ex); - } - return CoreWaveletOperationSerializer.deserialize(protoVersion); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ExportSnapshotService.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ExportSnapshotService.java b/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ExportSnapshotService.java deleted file mode 100644 index a65d69e..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ExportSnapshotService.java +++ /dev/null @@ -1,85 +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 org.waveprotocol.box.server.robots.operations; - -import com.google.common.collect.ImmutableMap; -import com.google.gson.Gson; - -import com.google.wave.api.ApiIdSerializer; -import com.google.wave.api.InvalidRequestException; -import com.google.wave.api.JsonRpcConstant.ParamsProperty; -import com.google.wave.api.OperationRequest; -import com.google.wave.api.impl.GsonFactory; - -import org.waveprotocol.box.common.comms.WaveClientRpc.WaveletSnapshot; -import org.waveprotocol.box.server.frontend.CommittedWaveletSnapshot; -import org.waveprotocol.box.server.robots.OperationContext; -import org.waveprotocol.wave.model.id.InvalidIdException; -import org.waveprotocol.wave.model.wave.ParticipantId; -import org.waveprotocol.wave.util.logging.Log; -import org.waveprotocol.wave.model.id.WaveId; -import org.waveprotocol.wave.model.id.WaveletId; -import org.waveprotocol.wave.model.id.WaveletName; -import org.waveprotocol.box.server.robots.util.OperationUtil; -import org.waveprotocol.box.server.common.SnapshotSerializer; -import org.waveprotocol.box.common.comms.proto.WaveletSnapshotProtoImpl; - -import java.util.Map; - -/** - * {@link OperationService} for the "exportSnapshot" operation. - * - * @author akapla...@gmail.com (Andrew Kaplanov) - */ -public class ExportSnapshotService implements OperationService { - private static final Log LOG = Log.get(ExportSnapshotService.class); - - private static final Gson gson = new GsonFactory().create(); - - private ExportSnapshotService() { - } - - @Override - public void execute(OperationRequest operation, OperationContext context, ParticipantId participant) - throws InvalidRequestException { - WaveId waveId; - WaveletId waveletId; - try { - waveId = ApiIdSerializer.instance().deserialiseWaveId( - OperationUtil.<String>getRequiredParameter(operation, ParamsProperty.WAVE_ID)); - waveletId = ApiIdSerializer.instance().deserialiseWaveletId( - OperationUtil.<String>getRequiredParameter(operation, ParamsProperty.WAVELET_ID)); - } catch (InvalidIdException ex) { - throw new InvalidRequestException("Invalid id", operation, ex); - } - WaveletName waveletName = WaveletName.of(waveId, waveletId); - CommittedWaveletSnapshot snapshot = context.getWaveletSnapshot(waveletName, participant); - WaveletSnapshot protoSnapshot = SnapshotSerializer.serializeWavelet(snapshot.snapshot, snapshot.snapshot.getHashedVersion()); - WaveletSnapshotProtoImpl protoSnapshotImpl = new WaveletSnapshotProtoImpl(protoSnapshot); - String jsonSnapshot = gson.toJson(protoSnapshotImpl.toGson(null, gson)); - Map<ParamsProperty, Object> data = - ImmutableMap.<ParamsProperty, Object> of(ParamsProperty.RAW_SNAPSHOT, jsonSnapshot); - context.constructResponse(operation, data); - } - - public static ExportSnapshotService create() { - return new ExportSnapshotService(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/box/server/robots/operations/FetchProfilesService.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/FetchProfilesService.java b/wave/src/main/java/org/waveprotocol/box/server/robots/operations/FetchProfilesService.java deleted file mode 100644 index 1079f98..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/FetchProfilesService.java +++ /dev/null @@ -1,120 +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 org.waveprotocol.box.server.robots.operations; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; -import com.google.inject.Inject; -import com.google.wave.api.FetchProfilesRequest; -import com.google.wave.api.FetchProfilesResult; -import com.google.wave.api.InvalidRequestException; -import com.google.wave.api.JsonRpcConstant.ParamsProperty; -import com.google.wave.api.OperationRequest; -import com.google.wave.api.ParticipantProfile; - -import org.waveprotocol.box.server.robots.OperationContext; -import org.waveprotocol.box.server.robots.util.OperationUtil; -import org.waveprotocol.wave.model.wave.ParticipantId; - -import java.util.List; -import java.util.Map; - -/** - * {@link OperationService} for the "fetchProfiles" operation. - * - * @author yur...@apache.org (Yuri Zelikov) - */ -public class FetchProfilesService implements OperationService { - - public interface ProfilesFetcher { - - public static final String UNKNOWN_IMAGE = "/static/images/unknown.jpg"; - public static final String UNKNOWN_PROFILE = ""; - - ParticipantProfile fetchProfile(String address); - - /** A simple profiles fetcher implementation. */ - static ProfilesFetcher SIMPLE_PROFILES_FETCHER = new ProfilesFetcher() { - - /** - * Attempts to create the fragments of the participant's name from their - * address, for example "john.sm...@example.com" into ["John", "Smith"]. - */ - private String buildNames(String address) { - // TODO (user) This code replicates ProfileImpl and should be refactored - // so the two classes can share the code properly. - String fullName; - List<String> names = Lists.newArrayList(); - String nameWithoutDomain = address.split("@")[0]; - if (nameWithoutDomain != null && !nameWithoutDomain.isEmpty()) { - // Include empty names from fragment, so split with a -ve. - for (String fragment : nameWithoutDomain.split("[._]", -1)) { - if (!fragment.isEmpty()) { - names.add(capitalize(fragment)); - } - } - // ParticipantId normalization implies names can not be empty. - assert !names.isEmpty(); - fullName = Joiner.on(' ').join(names); - return fullName; - } else { - // Name can be empty in case of shared domain participant which has - // the the form: @example.com. - return address; - } - } - - private String capitalize(String s) { - return s.isEmpty() ? s : (Character.toUpperCase(s.charAt(0))) + s.substring(1); - } - - @Override - public ParticipantProfile fetchProfile(String address) { - String name = buildNames(address); - return new ParticipantProfile(address, name, UNKNOWN_IMAGE, UNKNOWN_PROFILE); - } - }; - } - - private final ProfilesFetcher profilesFetcher; - - @Inject - public FetchProfilesService(ProfilesFetcher profilesFetcher) { - this.profilesFetcher = profilesFetcher; - } - - @Override - public void execute(OperationRequest operation, OperationContext context, - ParticipantId participant) throws InvalidRequestException { - FetchProfilesRequest request = - OperationUtil.getRequiredParameter(operation, ParamsProperty.FETCH_PROFILES_REQUEST); - List<String> requestAddresses = request.getParticipantIds(); - List<ParticipantProfile> profiles = Lists.newArrayListWithCapacity(requestAddresses.size()); - for (String address : requestAddresses) { - ParticipantProfile participantProfile = profilesFetcher.fetchProfile(address); - profiles.add(participantProfile); - } - FetchProfilesResult result = new FetchProfilesResult(profiles); - Map<ParamsProperty, Object> data = - ImmutableMap.<ParamsProperty, Object> of(ParamsProperty.FETCH_PROFILES_RESULT, result); - context.constructResponse(operation, data); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/box/server/robots/operations/FetchWaveService.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/FetchWaveService.java b/wave/src/main/java/org/waveprotocol/box/server/robots/operations/FetchWaveService.java deleted file mode 100644 index 48d8181..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/FetchWaveService.java +++ /dev/null @@ -1,106 +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 org.waveprotocol.box.server.robots.operations; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; - -import com.google.wave.api.InvalidRequestException; -import com.google.wave.api.JsonRpcConstant.ParamsProperty; -import com.google.wave.api.OperationRequest; -import com.google.wave.api.data.converter.ContextResolver; -import com.google.wave.api.data.converter.EventDataConverter; -import com.google.wave.api.event.WaveletFetchedEvent; -import com.google.wave.api.impl.EventMessageBundle; -import com.google.wave.api.impl.WaveletData; - -import org.waveprotocol.box.server.robots.OperationContext; -import org.waveprotocol.box.server.robots.util.ConversationUtil; -import org.waveprotocol.box.server.robots.util.OperationUtil; - -import org.waveprotocol.wave.model.conversation.Conversation; -import org.waveprotocol.wave.model.conversation.ObservableConversation; -import org.waveprotocol.wave.model.id.WaveletId; -import org.waveprotocol.wave.model.wave.ParticipantId; -import org.waveprotocol.wave.model.wave.Wavelet; -import org.waveprotocol.wave.model.wave.opbased.OpBasedWavelet; - -import java.util.Map; - -/** - * {@link OperationService} for the "fetchWave" operation. - * - * @author ljvder...@google.com (Lennard de Rijk) - * @author akapla...@gmail.com (Andrew Kaplanov) - */ -public class FetchWaveService implements OperationService { - - private FetchWaveService() { - } - - @Override - public void execute(OperationRequest operation, OperationContext context, ParticipantId participant) - throws InvalidRequestException { - if (OperationUtil.<Boolean>getOptionalParameter(operation, ParamsProperty.RETURN_WAVELET_IDS, false)) { - ImmutableSet<WaveletId> waveletIds = context.getVisibleWaveletIds(operation, participant); - Map<ParamsProperty, Object> data = - ImmutableMap.<ParamsProperty, Object>of(ParamsProperty.WAVELET_IDS, waveletIds); - context.constructResponse(operation, data); - } else { - OpBasedWavelet wavelet = context.openWavelet(operation, participant); - ObservableConversation conversation = - context.openConversation(operation, participant).getRoot(); - - EventMessageBundle messages = - mapWaveletToMessageBundle(context.getConverter(), participant, wavelet, conversation); - - String rootBlipId = ConversationUtil.getRootBlipId(conversation); - String message = OperationUtil.getOptionalParameter(operation, ParamsProperty.MESSAGE); - - WaveletFetchedEvent event = - new WaveletFetchedEvent(null, null, participant.getAddress(), System.currentTimeMillis(), - message, rootBlipId, messages.getWaveletData(), messages.getBlipData(), - messages.getThreads()); - - context.processEvent(operation, event); - } - } - - /** - * Maps a wavelet and its conversation to a new {@link EventMessageBundle}. - * - * @param converter to convert to API objects. - * @param participant the participant who the bundle is for. - * @param wavelet the wavelet to put in the bundle. - * @param conversation the conversation to put in the bundle. - */ - private EventMessageBundle mapWaveletToMessageBundle(EventDataConverter converter, - ParticipantId participant, Wavelet wavelet, Conversation conversation) { - EventMessageBundle messages = new EventMessageBundle(participant.getAddress(), ""); - WaveletData waveletData = converter.toWaveletData(wavelet, conversation, messages); - messages.setWaveletData(waveletData); - ContextResolver.addAllBlipsToEventMessages(messages, conversation, wavelet, converter); - return messages; - } - - public static FetchWaveService create() { - return new FetchWaveService(); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/box/server/robots/operations/FolderActionService.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/FolderActionService.java b/wave/src/main/java/org/waveprotocol/box/server/robots/operations/FolderActionService.java deleted file mode 100644 index 8f72a46..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/FolderActionService.java +++ /dev/null @@ -1,90 +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 org.waveprotocol.box.server.robots.operations; - -import static org.waveprotocol.box.server.robots.util.OperationUtil.buildSupplement; - -import com.google.common.collect.Maps; -import com.google.wave.api.InvalidRequestException; -import com.google.wave.api.JsonRpcConstant.ParamsProperty; -import com.google.wave.api.OperationRequest; - -import org.waveprotocol.box.server.robots.OperationContext; -import org.waveprotocol.box.server.robots.util.OperationUtil; -import org.waveprotocol.wave.model.conversation.ConversationBlip; -import org.waveprotocol.wave.model.conversation.ObservableConversation; -import org.waveprotocol.wave.model.supplement.SupplementedWave; -import org.waveprotocol.wave.model.wave.ParticipantId; - -import java.util.Map; - -/** - * Implements the "robot.folderAction" operations. - * - * @author yur...@apache.org (Yuri Zelikov) - */ -public class FolderActionService implements OperationService { - - public enum ModifyHowType { - MARK_AS_READ("markAsRead"), MARK_AS_UNREAD("markAsUnread"); - - private final String value; - - private ModifyHowType(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - } - - public static FolderActionService create() { - return new FolderActionService(); - } - - @Override - public void execute(OperationRequest operation, OperationContext context, - ParticipantId participant) throws InvalidRequestException { - - String modifyHow = OperationUtil.getRequiredParameter(operation, ParamsProperty.MODIFY_HOW); - String blipId = OperationUtil.getOptionalParameter(operation, ParamsProperty.BLIP_ID); - - SupplementedWave supplement = buildSupplement(operation, context, participant); - - if (modifyHow.equals(ModifyHowType.MARK_AS_READ.getValue())) { - if (blipId == null || blipId.isEmpty()) { - supplement.markAsRead(); - } else { - ObservableConversation conversation = - context.openConversation(operation, participant).getRoot(); - ConversationBlip blip = conversation.getBlip(blipId); - supplement.markAsRead(blip); - } - } else if (modifyHow.equals(ModifyHowType.MARK_AS_UNREAD.getValue())) { - supplement.markAsUnread(); - } else { - throw new UnsupportedOperationException("Unsupported folder action: " + modifyHow); - } - // Construct empty response. - Map<ParamsProperty, Object> data = Maps.newHashMap(); - context.constructResponse(operation, data); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/box/server/robots/operations/GravatarProfilesFetcher.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/GravatarProfilesFetcher.java b/wave/src/main/java/org/waveprotocol/box/server/robots/operations/GravatarProfilesFetcher.java deleted file mode 100644 index c698e2d..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/GravatarProfilesFetcher.java +++ /dev/null @@ -1,69 +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 org.waveprotocol.box.server.robots.operations; - -import com.google.inject.Inject; -import com.google.wave.api.ParticipantProfile; -import com.typesafe.config.Config; -import org.apache.commons.codec.digest.DigestUtils; -import org.waveprotocol.box.server.robots.operations.FetchProfilesService.ProfilesFetcher; - -/** - * A {@link ProfilesFetcher} implementation that assigns a Gravatar identicon - * image URL for the user avatar. Users can change the avatar image by going to - * gravatar.com and adding their wave address to the main profile. It is - * impossible to create a main profile with wave address since gravatar requires - * email address verification. -* - * @author yur...@apache.org (Yuri Zelikov) - */ -public class GravatarProfilesFetcher implements ProfilesFetcher { - - private final static String SECURE_GRAVATAR_URL = "https://secure.gravatar.com/avatar/"; - private final static String NON_SECURE_GRAVATAR_URL = "http://gravatar.com/avatar/"; - - private final String gravatarUrl; - - @Inject - public GravatarProfilesFetcher(Config config) { - if (config.getBoolean("security.enable_ssl")) { - gravatarUrl = SECURE_GRAVATAR_URL; - } else { - gravatarUrl = NON_SECURE_GRAVATAR_URL; - } - } - - /** - * Returns the Gravatar identicon URL for the given email address. - */ - public String getImageUrl(String email) { - // Hexadecimal MD5 hash of the requested user's lowercased email address - // with all whitespace trimmed. - String emailHash = DigestUtils.md5Hex(email.toLowerCase().trim()); - return gravatarUrl + emailHash + ".jpg?s=100&d=identicon"; - } - - @Override - public ParticipantProfile fetchProfile(String email) { - ParticipantProfile pTemp; - pTemp = ProfilesFetcher.SIMPLE_PROFILES_FETCHER.fetchProfile(email); - return new ParticipantProfile(email, pTemp.getName(), getImageUrl(email), pTemp.getProfileUrl()); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ImportAttachmentService.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ImportAttachmentService.java b/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ImportAttachmentService.java deleted file mode 100644 index 490b9f1..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ImportAttachmentService.java +++ /dev/null @@ -1,87 +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 org.waveprotocol.box.server.robots.operations; - -import com.google.common.collect.Maps; -import com.google.wave.api.InvalidRequestException; -import com.google.wave.api.OperationRequest; -import com.google.inject.Inject; -import com.google.wave.api.ApiIdSerializer; -import com.google.wave.api.JsonRpcConstant.ParamsProperty; -import com.google.wave.api.impl.RawAttachmentData; - -import org.waveprotocol.box.server.robots.OperationContext; -import org.waveprotocol.box.server.attachment.AttachmentService; -import org.waveprotocol.box.server.robots.util.OperationUtil; -import org.waveprotocol.wave.model.wave.InvalidParticipantAddress; -import org.waveprotocol.wave.util.logging.Log; -import org.waveprotocol.wave.media.model.AttachmentId; -import org.waveprotocol.wave.model.id.*; -import org.waveprotocol.wave.model.wave.ParticipantId; - -import java.io.IOException; -import java.io.ByteArrayInputStream; -import java.util.Map; - -/** - * {@link OperationService} for the "importAttachment" operation. - * @author akapla...@gmail.com (Andrew Kaplanov) - */ -public class ImportAttachmentService implements OperationService { - private static final Log LOG = Log.get(ImportAttachmentService.class); - private final AttachmentService attachmentService; - - @Inject - public ImportAttachmentService(AttachmentService attachmentService) { - this.attachmentService = attachmentService; - } - - @Override - public void execute(OperationRequest operation, OperationContext context, ParticipantId participant) - throws InvalidRequestException { - WaveId waveId; - WaveletId waveletId; - AttachmentId attachmentId; - RawAttachmentData attachmentData; - try { - waveId = ApiIdSerializer.instance().deserialiseWaveId( - OperationUtil.<String>getRequiredParameter(operation, ParamsProperty.WAVE_ID)); - waveletId = ApiIdSerializer.instance().deserialiseWaveletId( - OperationUtil.<String>getRequiredParameter(operation, ParamsProperty.WAVELET_ID)); - attachmentId = AttachmentId.deserialise(OperationUtil.<String>getRequiredParameter(operation, - ParamsProperty.ATTACHMENT_ID)); - attachmentData = OperationUtil.<RawAttachmentData>getRequiredParameter(operation, - ParamsProperty.ATTACHMENT_DATA); - } catch (InvalidIdException ex) { - throw new InvalidRequestException("Invalid id", operation, ex); - } - try { - attachmentService.storeAttachment(attachmentId, new ByteArrayInputStream(attachmentData.getData()), - WaveletName.of(waveId, waveletId), attachmentData.getFileName(), ParticipantId.of(attachmentData.getCreator())); - } catch (InvalidParticipantAddress ex) { - throw new InvalidRequestException("Invalid participant " + attachmentData.getCreator(), operation, ex); - } catch (IOException ex) { - LOG.severe("Store attachment", ex); - context.constructErrorResponse(operation, ex.toString()); - return; - } - Map<ParamsProperty, Object> response = Maps.<ParamsProperty, Object>newHashMap(); - context.constructResponse(operation, response); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ImportDeltasService.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ImportDeltasService.java b/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ImportDeltasService.java deleted file mode 100644 index e9024c1..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ImportDeltasService.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 org.waveprotocol.box.server.robots.operations; - -import com.google.common.collect.Maps; -import com.google.wave.api.InvalidRequestException; -import com.google.wave.api.OperationRequest; -import com.google.inject.Inject; -import com.google.inject.name.Named; -import com.google.protobuf.ByteString; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.wave.api.ApiIdSerializer; -import com.google.wave.api.JsonRpcConstant.ParamsProperty; - -import org.waveprotocol.box.server.CoreSettingsNames; -import org.waveprotocol.box.server.robots.OperationContext; -import org.waveprotocol.box.server.frontend.CommittedWaveletSnapshot; -import org.waveprotocol.box.server.waveserver.WaveServerException; -import org.waveprotocol.box.server.waveserver.WaveletProvider; -import org.waveprotocol.box.server.robots.util.OperationUtil; -import org.waveprotocol.wave.model.version.HashedVersion; -import org.waveprotocol.wave.model.wave.InvalidParticipantAddress; -import org.waveprotocol.wave.util.logging.Log; -import org.waveprotocol.wave.federation.Proto.ProtocolHashedVersion; -import org.waveprotocol.wave.federation.Proto.ProtocolWaveletDelta; -import org.waveprotocol.wave.model.id.*; -import org.waveprotocol.wave.model.version.HashedVersionFactory; -import org.waveprotocol.wave.model.version.HashedVersionFactoryImpl; -import org.waveprotocol.wave.model.wave.ParticipantId; -import org.waveprotocol.wave.util.escapers.jvm.JavaUrlCodec; - -import java.util.Map; -import java.util.List; - -/** - * {@link OperationService} for the "importDeltas" operation. - * @author akapla...@gmail.com (Andrew Kaplanov) - */ -public class ImportDeltasService implements OperationService { - private static final Log LOG = Log.get(ImportDeltasService.class); - private static final IdURIEncoderDecoder URI_CODEC = new IdURIEncoderDecoder(new JavaUrlCodec()); - private static final HashedVersionFactory HASH_FACTORY = new HashedVersionFactoryImpl(URI_CODEC); - private final WaveletProvider waveletProvider; - private final String waveDomain; - - @Inject - public ImportDeltasService(WaveletProvider waveletProvider, - @Named(CoreSettingsNames.WAVE_SERVER_DOMAIN) final String waveDomain) { - this.waveletProvider = waveletProvider; - this.waveDomain = waveDomain; - } - - @Override - public void execute(OperationRequest operation, OperationContext context, ParticipantId participant) - throws InvalidRequestException { - WaveId waveId; - WaveletId waveletId; - try { - waveId = ApiIdSerializer.instance().deserialiseWaveId( - OperationUtil.<String>getRequiredParameter(operation, ParamsProperty.WAVE_ID)); - waveletId = ApiIdSerializer.instance().deserialiseWaveletId( - OperationUtil.<String>getRequiredParameter(operation, ParamsProperty.WAVELET_ID)); - } catch (InvalidIdException ex) { - throw new InvalidRequestException("Invalid id", operation, ex); - } - waveId = WaveId.of(waveDomain, waveId.getId()); - waveletId = WaveletId.of(waveDomain, waveletId.getId()); - List<byte[]> history = - OperationUtil.getRequiredParameter(operation, ParamsProperty.RAW_DELTAS); - WaveletName waveletName = WaveletName.of(waveId, waveletId); - long importedFromVersion = -1; - if (!history.isEmpty()) { - CommittedWaveletSnapshot waveletSnapshot; - try { - waveletSnapshot = waveletProvider.getSnapshot(waveletName); - } catch (WaveServerException ex) { - LOG.info("Get wavelet snapshot", ex); - context.constructErrorResponse(operation, ex.toString()); - return; - } - for (byte[] deltaBytes : history) { - ProtocolWaveletDelta delta; - try { - delta = ProtocolWaveletDelta.parseFrom(deltaBytes); - } catch (InvalidProtocolBufferException ex) { - throw new InvalidRequestException("Parse delta", operation, ex); - } - long currentVersion = 0; - if (waveletSnapshot != null) { - currentVersion = waveletSnapshot.snapshot.getVersion(); - } - if (currentVersion == delta.getHashedVersion().getVersion()) { - if (importedFromVersion == -1) { - importedFromVersion = currentVersion; - } - ProtocolWaveletDelta newDelta; - try { - newDelta = setVersionHash(delta, waveletSnapshot, waveletName); - } catch (InvalidParticipantAddress ex) { - throw new InvalidRequestException("Convert delta", operation, ex); - } - final StringBuffer error = new StringBuffer(); - waveletProvider.submitRequest(waveletName, newDelta, - new WaveletProvider.SubmitRequestListener() { - - @Override - public void onSuccess(int operationsApplied, HashedVersion hashedVersionAfterApplication, - long applicationTimestamp) { - } - - @Override - public void onFailure(String errorMessage) { - error.append(errorMessage); - } - }); - if (error.length() != 0) { - context.constructErrorResponse(operation, error.toString()); - return; - } - if (waveletSnapshot == null) { - try { - waveletSnapshot = waveletProvider.getSnapshot(waveletName); - } catch (WaveServerException ex) { - LOG.info("Get wavelet snapshot", ex); - context.constructErrorResponse(operation, ex.toString()); - return; - } - } - } else if (importedFromVersion != -1) { - context.constructErrorResponse(operation, "Expected wavelet version " - + delta.getHashedVersion().getVersion() + ", but current version is " + currentVersion + "." - + "Possibly wavelet is modified during import."); - return; - } - } - } - Map<ParamsProperty, Object> response = Maps.<ParamsProperty, Object> newHashMap(); - response.put(ParamsProperty.IMPORTED_FROM_VERSION, importedFromVersion); - context.constructResponse(operation, response); - } - - /** - * Sets correct version hash to delta. - * - * @param delta the source delta. - * @param waveletSnapshot to append delta. - * @param waveletName name of wavelet. - * @return the delta to import. - * @throws InvalidParticipantAddress deserialize of participant error. - */ - ProtocolWaveletDelta setVersionHash(ProtocolWaveletDelta delta, - CommittedWaveletSnapshot waveletSnapshot, WaveletName waveletName) throws InvalidParticipantAddress { - ProtocolWaveletDelta.Builder newDelta = ProtocolWaveletDelta.newBuilder(delta); - if (waveletSnapshot == null) { - ProtocolHashedVersion ver = ProtocolHashedVersion.newBuilder(delta.getHashedVersion()). - setHistoryHash(ByteString.copyFrom(HASH_FACTORY.createVersionZero(waveletName).getHistoryHash())). - build(); - newDelta.setHashedVersion(ver); - } else { - ProtocolHashedVersion ver = ProtocolHashedVersion.newBuilder(delta.getHashedVersion()). - setHistoryHash(ByteString.copyFrom(waveletSnapshot.snapshot.getHashedVersion().getHistoryHash())). - build(); - newDelta.setHashedVersion(ver); - } - return newDelta.build(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/box/server/robots/operations/InitialsProfilesFetcher.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/InitialsProfilesFetcher.java b/wave/src/main/java/org/waveprotocol/box/server/robots/operations/InitialsProfilesFetcher.java deleted file mode 100644 index e14b792..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/InitialsProfilesFetcher.java +++ /dev/null @@ -1,49 +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 org.waveprotocol.box.server.robots.operations; - -import com.google.wave.api.ParticipantProfile; - -import org.waveprotocol.box.server.robots.operations.FetchProfilesService.ProfilesFetcher; - -/** - * A {@link ProfilesFetcher} implementation that assigns a default image URL for - * the user avatar using it's initial and a random color - * - * @author v...@apache.org (Vicente J. Ruiz Jurado) - */ -public class InitialsProfilesFetcher implements ProfilesFetcher { - - /** - * Returns the avatar URL for the given email address. - */ - public String getImageUrl(String email) { - return "/iniavatars/100x100/" + email; - } - - @Override - public ParticipantProfile fetchProfile(String email) { - ParticipantProfile pTemp = null; - pTemp = ProfilesFetcher.SIMPLE_PROFILES_FETCHER.fetchProfile(email); - ParticipantProfile profile = - new ParticipantProfile(email, pTemp.getName(), getImageUrl(email), pTemp.getProfileUrl()); - return profile; - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/box/server/robots/operations/NotifyOperationService.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/NotifyOperationService.java b/wave/src/main/java/org/waveprotocol/box/server/robots/operations/NotifyOperationService.java deleted file mode 100644 index 6812e37..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/NotifyOperationService.java +++ /dev/null @@ -1,110 +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 org.waveprotocol.box.server.robots.operations; - -import com.google.common.collect.Maps; -import com.google.inject.Inject; -import com.google.wave.api.InvalidRequestException; -import com.google.wave.api.OperationRequest; -import com.google.wave.api.JsonRpcConstant.ParamsProperty; -import com.google.wave.api.robot.CapabilityFetchException; -import com.google.wave.api.robot.RobotName; - -import org.waveprotocol.box.server.account.AccountData; -import org.waveprotocol.box.server.account.RobotAccountData; -import org.waveprotocol.box.server.persistence.AccountStore; -import org.waveprotocol.box.server.persistence.PersistenceException; -import org.waveprotocol.box.server.robots.OperationContext; -import org.waveprotocol.box.server.robots.RobotCapabilities; -import org.waveprotocol.box.server.robots.passive.RobotConnector; -import org.waveprotocol.box.server.robots.util.OperationUtil; -import org.waveprotocol.wave.model.wave.ParticipantId; -import org.waveprotocol.wave.util.logging.Log; - -/** - * Implementation of the robot.notify operation which might update the robot's - * capabilties. - * - * @author ljvder...@gmail.com (Lennard de Rijk) - */ -public class NotifyOperationService implements OperationService { - - private static final Log LOG = Log.get(NotifyOperationService.class); - - private final AccountStore accountStore; - private final RobotConnector connector; - - @Inject - public NotifyOperationService(AccountStore accountStore, RobotConnector connector) { - this.accountStore = accountStore; - this.connector = connector; - } - - @Override - public void execute(OperationRequest operation, OperationContext context, - ParticipantId participant) throws InvalidRequestException { - String capabilitiesHash = - OperationUtil.getRequiredParameter(operation, ParamsProperty.CAPABILITIES_HASH); - - RobotName robotName = RobotName.fromAddress(participant.getAddress()); - - ParticipantId robotAccountId = ParticipantId.ofUnsafe(robotName.toEmailAddress()); - AccountData account; - try { - account = accountStore.getAccount(robotAccountId); - } catch (PersistenceException e) { - LOG.severe("Failed to retreive account data for " + robotAccountId, e); - context.constructErrorResponse(operation, "Unable to retrieve account data"); - return; - } - - if (account == null || !account.isRobot()) { - throw new InvalidRequestException("Can't exectute robot.notify for unknown robot " - + robotAccountId); - } - - RobotAccountData robotAccountData = account.asRobot(); - RobotCapabilities capabilities = robotAccountData.getCapabilities(); - if (capabilities != null && capabilitiesHash.equals(capabilities.getCapabilitiesHash())) { - // No change in capabilities indicated - context.constructResponse(operation, Maps.<ParamsProperty, Object> newHashMap()); - return; - } - - try { - robotAccountData = connector.fetchCapabilities(robotAccountData, ""); - } catch (CapabilityFetchException e) { - LOG.fine("Unable to retrieve capabilities for " + account.getId(), e); - context.constructErrorResponse(operation, "Unable to retrieve new capabilities"); - return; - } - - try { - accountStore.putAccount(robotAccountData); - } catch (PersistenceException e) { - LOG.severe("Failed to update account data for " + robotAccountId, e); - context.constructErrorResponse(operation, "Unable to update account data"); - return; - } - - // Set empty response to indicate success - context.constructResponse(operation, Maps.<ParamsProperty, Object> newHashMap()); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/box/server/robots/operations/OperationService.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/OperationService.java b/wave/src/main/java/org/waveprotocol/box/server/robots/operations/OperationService.java deleted file mode 100644 index 95512e9..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/OperationService.java +++ /dev/null @@ -1,45 +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 org.waveprotocol.box.server.robots.operations; - -import com.google.wave.api.InvalidRequestException; -import com.google.wave.api.OperationRequest; - -import org.waveprotocol.box.server.robots.OperationContext; -import org.waveprotocol.wave.model.wave.ParticipantId; - -/** - * Executor of robot operations. - * - * @author ljvder...@google.com (Lennard de Rijk) - */ -public interface OperationService { - - /** - * Tries to execute the operation in the given context. - * - * @param operation the operation to execute. - * @param context the context of the operation. - * @param participant the participant performing this operation. - * @throws InvalidRequestException if the operation fails to perform. - */ - void execute(OperationRequest operation, OperationContext context, ParticipantId participant) - throws InvalidRequestException; -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ParticipantServices.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ParticipantServices.java b/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ParticipantServices.java deleted file mode 100644 index 962c58f..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/ParticipantServices.java +++ /dev/null @@ -1,143 +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 org.waveprotocol.box.server.robots.operations; - -import com.google.common.collect.Lists; -import com.google.wave.api.InvalidRequestException; -import com.google.wave.api.JsonRpcConstant.ParamsProperty; -import com.google.wave.api.OperationRequest; -import com.google.wave.api.OperationType; -import com.google.wave.api.event.Event; -import com.google.wave.api.event.WaveletParticipantsChangedEvent; - -import org.waveprotocol.box.server.robots.OperationContext; -import org.waveprotocol.box.server.robots.util.ConversationUtil; -import org.waveprotocol.box.server.robots.util.OperationUtil; -import org.waveprotocol.wave.model.conversation.ObservableConversation; -import org.waveprotocol.wave.model.wave.InvalidParticipantAddress; -import org.waveprotocol.wave.model.wave.ParticipantId; -import org.waveprotocol.wave.util.logging.Log; - -import java.util.List; - -/** - * {@link OperationService} for operations that add or remove a participant. - * - * <p> - * These operations are: - * <li>{@link OperationType#WAVELET_ADD_PARTICIPANT_NEWSYNTAX}</li> - * <li>{@link OperationType#WAVELET_REMOVE_PARTICIPANT_NEWSYNTAX}</li>. - * - * @author anthony dot watkins at sesi dot com (Anthony Watkins) - */ -public class ParticipantServices implements OperationService { - - private static final Log LOG = Log.get(ParticipantServices.class); - - private ParticipantServices() { - } - - /** - * Adds or Removes a Participant on a Wavelet. - * - * @param operation the operation to execute. - * @param context the context of the operation. - * @param participant the participant performing this operation. - * @throws InvalidRequestException if the operation fails to perform. - */ - @Override - public void execute(OperationRequest operation, OperationContext context, - ParticipantId participant) throws InvalidRequestException { - - // Get the conversation wavelet. If participant performing operation is not - // a member of wavelet, InvalidRequestException is thrown by this method. - ObservableConversation conversation = - context.openConversation(operation, participant).getRoot(); - - // Get participant operation is being performed on. - String paramParticipant = - OperationUtil.getRequiredParameter(operation, ParamsProperty.PARTICIPANT_ID); - - ParticipantId targetParticipant; - try { - targetParticipant = ParticipantId.of(paramParticipant); - } catch (InvalidParticipantAddress e) { - String message = "Target ParticipantId " + paramParticipant + " is not " + "valid"; - LOG.info(message); - throw new InvalidRequestException(message); - } - - String rootBlipId = ConversationUtil.getRootBlipId(conversation); - - // Create generic event (defined by operation type) that will be processed - // by the context. - Event event; - - // Set up participant containers. - List<String> participantsAdded = Lists.newArrayList(); - List<String> participantsRemoved = Lists.newArrayList(); - - OperationType type = OperationUtil.getOperationType(operation); - switch (type) { - case WAVELET_ADD_PARTICIPANT_NEWSYNTAX: - // Make sure targetParticipant is not already member. - if (conversation.getParticipantIds().contains(targetParticipant)) { - String message = targetParticipant.getAddress() + " is already a " + "member of wavelet"; - LOG.info(message); - throw new InvalidRequestException(message, operation); - } - - // Add participant to conversation and send event. - conversation.addParticipant(targetParticipant); - participantsAdded.add(targetParticipant.getAddress()); - event = - new WaveletParticipantsChangedEvent(null, null, participant.getAddress(), - System.currentTimeMillis(), rootBlipId, participantsAdded, participantsRemoved); - break; - case WAVELET_REMOVE_PARTICIPANT_NEWSYNTAX: - // Make sure targetParticipant is already member. - if (!conversation.getParticipantIds().contains(targetParticipant)) { - // Not a member, throw invalid request. - String message = targetParticipant.getAddress() + " is not a " + "member of wavelet"; - LOG.info(message); - throw new InvalidRequestException(message, operation); - } - - // Remove participant and send event. - conversation.removeParticipant(targetParticipant); - participantsRemoved.add(targetParticipant.getAddress()); - - event = - new WaveletParticipantsChangedEvent(null, null, participant.getAddress(), - System.currentTimeMillis(), rootBlipId, participantsAdded, participantsRemoved); - break; - default: - throw new UnsupportedOperationException( - "This OperationService does not implement operation of type " + type.method()); - } - - // Process the participant event. - context.processEvent(operation, event); - } - - public static ParticipantServices create() { - return new ParticipantServices(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/box/server/robots/operations/SearchService.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/SearchService.java b/wave/src/main/java/org/waveprotocol/box/server/robots/operations/SearchService.java deleted file mode 100644 index e8eeedd..0000000 --- a/wave/src/main/java/org/waveprotocol/box/server/robots/operations/SearchService.java +++ /dev/null @@ -1,76 +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 org.waveprotocol.box.server.robots.operations; - -import com.google.common.collect.ImmutableMap; -import com.google.inject.Inject; -import com.google.wave.api.InvalidRequestException; -import com.google.wave.api.JsonRpcConstant.ParamsProperty; -import com.google.wave.api.OperationRequest; -import com.google.wave.api.SearchResult; -import org.waveprotocol.box.server.robots.OperationContext; -import org.waveprotocol.box.server.robots.util.OperationUtil; -import org.waveprotocol.box.server.waveserver.SearchProvider; -import org.waveprotocol.wave.model.wave.ParticipantId; -import java.util.Map; - -/** - * {@link OperationService} for the "search" operation. - * - * @author ljvder...@google.com (Lennard de Rijk) - * @author jose...@gmail.com (Joseph Gentle) - */ -public class SearchService implements OperationService { - - /** - * The number of search results to return if not defined in the request. - * Defined in the spec. - */ - private static final int DEFAULT_NUMBER_SEARCH_RESULTS = 10; - - private final SearchProvider searchProvider; - - @Inject - public SearchService(SearchProvider searchProvider) { - this.searchProvider = searchProvider; - } - - @Override - public void execute( - OperationRequest operation, OperationContext context, ParticipantId participant) - throws InvalidRequestException { - String query = OperationUtil.getRequiredParameter(operation, ParamsProperty.QUERY); - int index = OperationUtil.getOptionalParameter(operation, ParamsProperty.INDEX, 0); - int numResults = OperationUtil.getOptionalParameter( - operation, ParamsProperty.NUM_RESULTS, DEFAULT_NUMBER_SEARCH_RESULTS); - - SearchResult result = search(participant, query, index, numResults); - - Map<ParamsProperty, Object> data = - ImmutableMap.<ParamsProperty, Object> of(ParamsProperty.SEARCH_RESULTS, result); - context.constructResponse(operation, data); - } - - // Note that this search implementation is only of prototype quality. - private SearchResult search( - ParticipantId participant, String query, int startAt, int numResults) { - return searchProvider.search(participant, query, startAt, numResults); - } -}