49
Apache Wave (incubating) Developer Documentation Release 0.4 The Apache Wave Foundation August 22, 2015

Apache Wave (incubating) Developer Documentational/wave_docs/ApacheWave...Apache Wave (incubating) Developer Documentation, Release 0.4 1.2Protocol & Data Models 1.2.1How do I define

  • Upload
    others

  • View
    10

  • Download
    0

Embed Size (px)

Citation preview

  • Apache Wave (incubating) DeveloperDocumentation

    Release 0.4

    The Apache Wave Foundation

    August 22, 2015

  • CONTENTS

    1 FAQ’s 11.1 Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Protocol & Data Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

    2 Contributing 52.1 Release Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.2 Client Development Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82.3 Gadget Server Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

    3 Wave Model Code Walk 133.1 Under construction! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133.2 Let’s explore the code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

    4 Tutorials 174.1 Navigating the Codebase and Making the First Change . . . . . . . . . . . . . . . . . . . . . . . . . 174.2 Writing a DooDad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

    5 Social Media GuideLines 315.1 Access to Social Media Accounts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315.2 Do’s and Don’ts for Social Media . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

    6 Wave Logo Usage 33

    7 Presentations 357.1 Talks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357.2 2010 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367.3 2009 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

    8 Further Readings 378.1 Anthony Watkins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378.2 Bryce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

    9 OverView of Design Structure 399.1 Source Code Organization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399.2 Client Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399.3 Repository Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419.4 Wave Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429.5 WaveMap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439.6 Wavelet cache and factories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439.7 Wave Bus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449.8 Wave Bus Subscribers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

    i

  • ii

  • CHAPTER

    ONE

    FAQ’S

    1.1 Code

    1.1.1 Where are the binaries?

    The design of the server is moving very quickly with almost daily updates to the source code in the repository soany binaries would be very quickly out of date. We’ve worked hard to make the server have as few dependencies aspossible, you should only need to install Ant above and beyond the required Java 6 SDK.

    1.1.2 Does it run on App Engine? TODO: is this still true?

    It’s not in our medium-term plan to have Wave in a Box run on App Engine.

    1.1.3 Does it support the embed API?

    There is no plan to support embedding in the open source plan, but it should be fairly straightforward for a developerto modify the code so that there is an output of the client that includes only the wave panel. (The Google Wave embedAPI basically did that– just hid all the other panels).

    You can see a basic Embed API JS here: http://wave-api.appspot.com/public/embed.js

    1.1.4 How similar will robots be to robots suitable for Google Wave?

    We hope to have the protocols be quite similar, and if there are changes, they will be made to improve the protocol forthe better. If you plan on running Wave-in-a-Box when available and want to develop robots in preparation for that,then we’d recommend developing them according to the current specification.

    1.1.5 Does it include the spell-checking or linking agent?

    The code does not include the spell-checking agent (“Spelly”) and will probably not include the linking agent(“Linky”).

    1

    http://wave-api.appspot.com/public/embed.js

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    1.2 Protocol & Data Models

    1.2.1 How do I define ACLs for a Wave?

    As of right now the Access Control to a wavelet is simply boolean, that is, you either have full read-write access toa wavelet, or you have no access to a wavelet. There have been recurring questions about finer grained controls, andwhile ACLs are currently under discussion, at this point we don’t have anything solid enough to put forward as aproposal.

    1.2.2 What is the client-server protocol?

    The focus of our open source and protocol work at this point is on the federation protocol, which is critical for gettinginter-operable server implementations, that is, for allowing many other people to build Wave servers and have theminterop with each other and with the Google Wave server. We have definitely heard the requests for defining a client-server protocol, but at this time the team doesn’t have the time to put into such an effort.

    If you are interested in working on the client-server protocol we are happy to host that discussion here, and the client-server protocol as implemented in the open source server would be a fine place to start.

    1.2.3 What’s the XML schema for waves? Why isn’t it HTML5?

    Wave documents differ from XML in two ways:

    • they have a much smaller set of allowed node types, only elements and text

    • they include stand-off key/value annotations, which are not part of XML

    The primary reason we don’t use a highly structured format like HTML is that such a format does not have desir-able properties under operational transformation, when multiple clients edit the same document concurrently. WhileHTML attempts to separate semantic content from presentation, waves also need to be concerned with the opera-tional transformation layer underneath, and HTML makes OT (Operational Transforms) difficult if not impossible.Wave documents do have schemas, however. These are currently defined in the org.waveprotocol.wave.model.schemapackage.

    1.2.4 What about attachments?

    Attachments will eventually be rolled into the federation specification. The current whitepaper describes the design ofexisting non-federated attachment system and is a good place to start learning about attachments.

    1.2.5 What is the difference between an Agent and a Robot?

    This diagram shows the relationship between agents and robots:

    2 Chapter 1. FAQ’s

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    An agent runs on the server and performs services there. A robot proxy is just an agent that delegates out actionsto robot servers over HTTP and acts on the robot servers behalf. The example code contains a simple agent calledEchoey.

    1.2. Protocol & Data Models 3

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    4 Chapter 1. FAQ’s

  • CHAPTER

    TWO

    CONTRIBUTING

    2.1 Release Procedure

    2.1.1 Introduction

    This is an attempt to document the release procedure used for Wave whilst under incubation. These notesare not complete, so you will probably want to refer to the following documents:

    • https://incubator.apache.org/guides/releasemanagement.html

    • https://incubator.apache.org/guides/release-java.html

    • https://www.apache.org/dev/release.html

    A good guide (used as the basis for this one) is produced by the Apache Commons project:

    • https://commons.apache.org/releases/prepare.html

    • https://commons.apache.org/releases/release.html

    2.1.2 Build Environment

    The release procedure documented has been/is being carried out on a 64-bit Linux machine using Ant and OpenJDK1.6

    2.1.3 Preparation

    Make a release branch

    This depends on how active the tree is at the time.

    git checkout -b wave-X.X.X-release

    Then check out this branch, to do any release work needed.

    Check Licensing

    Ensure that all source files have the Apache License attached, and any dependencies licenses are correctlynoted in NOTICE. Run the license audit tool and inspect the output:

    ant audit-licenses

    Check export status of any cryptographic dependencies.

    5

    https://incubator.apache.org/guides/releasemanagement.htmlhttps://incubator.apache.org/guides/release-java.htmlhttps://www.apache.org/dev/release.htmlhttps://commons.apache.org/releases/prepare.htmlhttps://commons.apache.org/releases/release.html

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    2.1.4 Set version number in file

    The version number is currently stored in build.properties in the waveinabox.version string. Whilst the project is stillincubating, the word ‘incubating’ must appear in the version string.

    The version number should be in the form described at: http://semver.org/

    Given a version number MAJOR . MINOR . PATCH , increment the:

    1. MAJOR version when you make incompatible API changes,

    2. MINOR version when you add functionality in a backwards-compatible manner, and

    3. PATCH version when you make backwards-compatible bug fixes.

    Additional labels for pre-release and build metadata are available as extensions to the MAJOR . MINOR . PATCHformat. For example: 0.4.0-rc.6-incubating Every release should usually increase the MINOR version and reset thePATCH version.

    2.1.5 Create CHANGES

    I suggest using the following git log, to produce a one-line-per-change list of all commits. (An alternative, would beto use the JIRA id’s)

    git log --pretty-medium

    Put this the ‘Full log’ section. I suggest hand-writing the ‘Summary since X’ at the start of the file.

    2.1.6 Create RELEASE-NOTES

    TODO: decide on a format

    Refer to the notes used in the previous release for the format of how to write them. Break at 80 chars as is conventional.Include:

    • Description of the project

    • Any major changes (otherwise see CHANGES) Is this really needed given the summary in CHANGES?

    • Any compatibility issues (and mention if none)

    • Any upgrading procedures needed

    • Make another note of the required Java version

    2.1.7 Tag the RC

    2.1.8 Make the RC

    There are two ways to create the artefacts. The preferred way is to use the artefacts createdby Jenkins. Download zip with all artefacts from https://builds.apache.org/view/S-Z/view/Wave/job/wave-artifacts/lastSuccessfulBuild/artifact/zip/archive.zip

    wget https://builds.apache.org/view/S-Z/view/Wave/job/wave-artifacts/lastSuccessfulBuild/artifact/*zip*/archive.zipunzip archive.zip

    Or, create the artefacts manually. Make sure to run the unit tests first. Run

    6 Chapter 2. Contributing

    http://semver.org/https://builds.apache.org/view/S-Z/view/Wave/job/wave-artifacts/lastSuccessfulBuild/artifact/https://builds.apache.org/view/S-Z/view/Wave/job/wave-artifacts/lastSuccessfulBuild/artifact/

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    ant release

    Check that the produced code still works! Check that source packages don’t include any binaries. Sign the releaseusing your GPG key, and record SHA512 checksums for the files.

    Listing 2.1: Sign artefact’s#!/bin/zsh#Assumes it is being run in the folder with artefact's.

    PRE="apache-wave-"for f in $PRE*; dogpg --armor --output $f.asc --detach-sig $fgpg --print-md SHA512 $f > $f.shadone

    You need to append you signature/public key to the KEYS file, look there for instructions.

    2.1.9 Upload the Artefacts.

    Upload the src+bin tar+zip somewhere so that it can be found. The release candidate should be uploaded to the “dev”folder first to allow inspection and voting.

    Listing 2.2: Commit new rcsvn checkout https://dist.apache.org/repos/dist/dev/incubator/wave/

    Create a new folder under dist/dev/incubator/wave for the new release candidate and copy there the signed artefactsand then commit.

    2.1.10 Vote for release

    Send a vote mail for RC

    Send a message with subject ‘VOTE Release Wave 0.3 based on RC1’ email to [email protected]. Postlinks to the RC artefacts, the subversion tag it is based upon, RELEASE-NOTES so that the artefact doesn’t have tobe downloaded to see them. Ensure that KEYS is available somewhere with the artefacts. Check the voting guide formore information on how to count votes etc. When posting the RESULT, note that (currently) all committers are alsoPPMC, so to prevent confusion list as PPMC in the result email.

    (Incubator only) Vote for RC

    Whilst Wave is still an incubating project, send a VOTE email to [email protected] to get PMC votes.Handle in the same way as the internal vote.

    2.1.11 Publish accepted RC

    To publish copy the artefacts into https://dist.apache.org/repos/dist/release/incubator/wave/ from thedist/dev/incubator/wave/ (delete old artefacts if needed, they were automatically archived already) and commit.

    2.1. Release Procedure 7

    mailto:[email protected]:[email protected]://dist.apache.org/repos/dist/release/incubator/wave/

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    2.2 Client Development Setup

    TODO: project still called wave-protocol?

    Note: Mac Users ensure your jsdk is set to 1.7 and you’re running Safari 5+.

    2.2.1 Before you start

    For developing and debugging code in an isolated wave panel environment, use the Wave Panel Harness setup. Thisis the preferred development environment, because there is no need to run a wave server. For developing anddebugging code in the full client with end-to-end server communication, use the Full Client setup.

    2.2.2 Setting up Eclipse project (optional)

    Eclipse is the recommended development environment, in order to maintain consistent code formatting. However,since the debugging processes are all contained in the ant build file, you can use whichever development environmentyou like.

    1. Follow WIAB build instructions

    • Start the server if you want to start debugging/changing code

    2. Generate some code required for the Eclipse project to compile.

    • ant eclipse

    3. In Eclipse, Import the wave-protocol project into your workspace.

    • File -> Import -> Existing Projects Into Workspace

    • Navigate to the wave-protocol project

    • The ‘wave-protocol’ project should then appear and be selected in the Projects: list

    • Click Finish.

    2.2.3 Wave Panel Harness

    GWT Hosted mode

    1. Run the wave panel harness using the GWT code server (called OOPHM).

    • $ ant waveharness-hosted

    2. Using a supported browser 1, preferably running on the same machine as the GWT code server, open the URLthat the hosted mode server names. The wave panel harness is a page with a wave panel displaying a fake,in-memory wave. There is no communication with a wave server.

    3. Attach a debugger to the hosted mode server.

    • In Eclipse, create a launch configuration using Run -> Debug Configuration -> Remote Java Application,and use port 8001. Click Debug.

    1 The GWT code server requires a plugin to be installed in the browser that you use. The first time you use the GWT code server in a particularbrowser, you will be prompted to install this plugin. Not all browser/OS combinations that Wave-In-A-Box supports can be used for debugging: thisis limited by the browser/OS combinations for which a GWT code server plugin is available. At the time or writing, this set is: Linux x {Firefox},Windows x {Chrome, Firefox, IE}, Mac x {Safari, Firefox}. For the wave panel harness, the full set of combinations is available. For the full client,the only debugging setups that work out of the box are Safari on Mac, and Chrome on Windows (i.e., webkit browsers).

    8 Chapter 2. Contributing

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    4. Profit.

    • Set breakpoints, interact in the browser, step through code etc.

    • In Eclipse, code changes you make do not always take effect in the browser immediately (HotCode).However, refreshing the browser will reload the application through the GWT code server, including allyour changes.

    GWT Superdev mode

    1. Run the wave panel using the GWT superdev mode.

    • $ ant waveharness-superdev

    2. Open and add the bookmarks in: http://localhost:9876/ to your browser.

    3. Open the wave panel in http://localhost:9876/waveharness/UndercurrentHarness.html

    4. Do some code changes (for instance in UndercurrentHarness.java), click in “Dev mode on” in the bookmarksand recompile the module to see the changes.

    Superdev debuging

    In Google Chrome, for debugging and logs:

    • Launch Chrome Developer Tools (F12)

    • For debugging, you need to Enable JS Source Maps in Chrome Developer Tools preferences.

    • Open the Source tab and observe the files, or the Console tab to see the logs.

    More info about Superdev mode (also a screenshot): http://stackoverflow.com/questions/18330001/super-dev-mode-in-gwt

    2.2.4 Editor Test Harness

    GWT Hosted mode

    1. Run the wave panel harness using the GWT code server (called OOPHM).

    • $ ant editor-hosted

    2. Using a supported browser*, preferably running on the same machine as the GWT code server, open the URLthat the hosted mode server names. The editor harness is a page with an div for the local editor and another divfor the remote editor. There is no communication to the server.

    3. Attach a debugger to the hosted mode server.

    • In Eclipse, create a launch configuration using Run -> Debug Configuration -> Remote Java Application,and use port 8001. Click Debug.

    4. Profit.

    • Set breakpoints, interact in the browser, step through code etc.

    • In Eclipse, code changes you make do not always take effect in the browser immediately (HotCode).However, refreshing the browser will reload the application through the GWT code server, including allyour changes.

    2.2. Client Development Setup 9

    http://localhost:9876/http://localhost:9876/waveharness/UndercurrentHarness.htmlhttp://stackoverflow.com/questions/18330001/super-dev-mode-in-gwthttp://stackoverflow.com/questions/18330001/super-dev-mode-in-gwt

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    GWT Superdev mode

    1. Run the wave panel using the GWT superdev mode

    • $ ant editor-superdev

    2. Open and add the bookmarks in: http://localhost:9876/ to your browser.

    3. Open the wave panel in http://localhost:9876/org.waveprotocol.wave.client.editor.harness.EditorTest/EditorTest.html

    4. Do some code changes, click in “Dev mode on” in the bookmarks and recompile the module to see the changes.See waveharness superdev mode section for debuging tips.

    2.2.5 Full Client

    GWT Hosted mode

    1. Start the server following the instructions at Starting WIAB

    • Remember to restart the server after any change that would affect the server. In general, this is requiredfor any change outside the box/webclient package.

    2. Start the GWT code server (called OOPHM)

    • $ ant hosted-gwt

    3. Set up an Eclipse debug target to attach to the GWT code server (this only needs to be done once, after thatreuse the same target to start debugging)

    (a) Run -> Debug Configuration

    (b) Select Remote Java Application

    (c) Change the port from 8000 to 8001 (this port number should match the console output when ‘anthosted_gwt’ was run)

    (d) Click Debug

    4. Using a supported browser*, preferably running on the same machine as the GWT code server,

    (a) Go to http://:9898

    • Sign in. This only needs to be done once per server restart, in order to get a session cookie. Ignoreany popups about the client needing to be GWT compiled.

    (b) Go to http://:9898/?gwt.codesvr=:9997

    • In order to communicate with the GWT code server, your browser needs a plugin. If you do notalready have it installed, you will be directed to install it.

    5. You should now be able to make any change to the client code in wave-protocol and see the effects by refreshingthe browser

    • You may need to restart “ant hosted_gwt” periodically once the GWT code server runs out of memory(after ~10-20 refreshes).

    GWT Superdev mode

    In development.

    10 Chapter 2. Contributing

    http://localhost:9876/http://localhost:9876/org.waveprotocol.wave.client.editor.harness.EditorTest/EditorTest.htmlhttp:/http:/

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    2.3 Gadget Server Setup

    This is the instructions for running your WIAB as well as your own gadget server (Shindig). These instructions usesthe Apache Tomcat version of Shindig.

    Note: Currently gadgets does not work on Firefox 3.x

    1. Download Shindig distribution from https://shindig.apache.org/download.html - make sure do download the warfile and not jars.

    wget http://www.apache.org/dist/shindig/2.5.2/shindig-server-2.5.2.war

    2. Extract the war and edit the file WEB-INF/classes/containers/default/container.js - add “wave” to “gad-gets.container” property. “gadgets.container” : “default”, “accel”, “wave”,

    3. The easiest way to run shindig is by using jetty-runner.

    wget http://repo2.maven.org/maven2/org/mortbay/jetty/jetty-runner/8.1.9.v20130131/jetty-runner-8.1.9.v20130131.jar

    4. Run the Shindig application war with:

    java -jar jetty-runner-8.1.9.v20130131.jar shindig-server-2.5.2

    Please note that you can specify either folder of extracted war or the war file itself. The gadget serverwill start on localhost:8080

    5. Get WIAB (See Installing)

    Edit server.config and add the following:

    gadget_server_hostname=gadget_server_port=8080

    6. Start WIAB

    The following pages are useful if you’re starting out with Apache Wave, and detail how to get a development environ-ment setup.

    Contributing Process

    In order to develop and release software contributions you must follow these steps:

    1. Create or assign a JIRA issue for the contribution you want to work in. Any contribution must have an associatedJIRA issue.

    2. Create a patch per logical set of issues/features. (Create a patch in Eclipse /Intellij)

    3. Submit the patch to the Review Board with assigned to the “wave” project, and mentioning the JIRA issuenumber that it is related to.

    4. Inform the Mailing List and/or IRC about the request.

    5. Fix the patch according to the suggestions in the Review Board until it has gotten approval.

    6. Push the patch to git if a committer otherwise one of the reviewers will push the change.

    7. Close issues and review board request.

    2.3. Gadget Server Setup 11

    https://shindig.apache.org/download.htmlhttps://issues.apache.org/jira/browse/WAVEhttp://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.platform.doc.user%2Ftasks%2Ftasks-68c.htmhttps://www.jetbrains.com/idea/help/using-patches.htmlhttps://reviews.apache.org/r/

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    12 Chapter 2. Contributing

  • CHAPTER

    THREE

    WAVE MODEL CODE WALK

    This doument provides an informal overview of the code providing the wave model. The wave model describes thebasic building blocks of a wave application: what a wave is and how it can change. It also provides application modelswhich implement more abstract data structures on top of waves. The most familiar is the conversation model whichimplements the conversational structure of waves presented in, for example, the Google Wave client.

    This walkthrough describes the major modules comprising the wave model in a bottom-up fashion.

    The wave model code lives under the src/org/waveprotocol/wave/model directory

    3.1 Under construction!

    The wave model code is under active development. The code structure may differ from that described here, thoughwe’ll try to keep it up to date. The code as initially released also contains a few pieces of legacy from Google Wave’sinfancy, pieces of code we’ve learnt should be done differently. We intend to clean these up over time.

    3.2 Let’s explore the code

    Operations: model.operation.* These modules implement operations, which are the fundamental unit of statechange. The model.operation package describes purely generic operations simply as things which apply to sometarget. Sub-packages contain specific operation implementations and their transformation.

    • model.operation.core: operations which apply to the data objects in model.wave.data.core.

    • model.operation.wave: operations applying to the extended data interfaces in model.wave.data.

    Legacy note: The operations in model.operation.core represent our ideal minimum set of operations. Themodel.operation.wave package contains some legacy operations and concepts. In particular, the concept of a “blip” (aconversational message) and the operations targeting it do not belong at this low level of abstraction.

    Starting points:

    • model.operation.Operation

    • model.operation.core.WaveletOperation

    Documents: model.document.* These modules implement wave documents, which contain almost all the state ofa wavelet. A wave document is an XML-like sequence of elements and text nodes plus a set of stand-off key/valueannotations.

    • model.document.bootstrap: a very simple demonstration document implementation.

    • model.document.raw: a raw DOM-style document substrate.

    13

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    • model.document.operation: operations applying to documents and their transformation, along with utilities in-cluding composition and normalization. Also an automaton for generating random operations for testing.

    • model.document.indexed: an indexed tree structure providing fast random access to nodes in a document. Anindexed document is mutated by accepting operations.

    • model.document: mutable and observable document implementations based on a indexed documents.

    Starting points:

    • model.document.Document: the high-level mutable document interface

    • model.document.ObservableDocument: extends Document to provide events

    Waves: model.wave.* This modules implement waves and wavelets. A wavelet comprises a set of documents and aset of participant identifiers.

    • model.wave.data: simple, “dumb” ADTs, which are the targets of operations. The core sub-package containspure, metadata-free implementations sufficient for servers. Also a number of document factories for use withthe data objects.

    • model.wave: the abstract wave view, wavelet, blip and participant id interfaces which define the semantics ofthese types.

    • model.wave.opbased: operation-based implementation of a wavelet which performs mutations by generatingand applying operations to an underlying wavelet data

    • model.wave.undo: utilities for reversing wavelet operations

    Note that there is a clear separation between the semantic free data types in model.wave.data, which implement pure“dumb” data containers, and the abstract objects in {{model.wav}}e. This separation of data from semantics is re-peated in other high-level packages.

    Legacy note: The interfaces in these packages conflate wave metadata, such as timestamps and version numbers, withthe pure wave data. Themodel.wave.data.core contains our ideals of the data interfaces. The metadata does not behavein the same way as the data and we intend to separate it to reduce confusion. The inclusion of the blip concept herealso is a legacy which doesn’t belong.

    Starting points:

    • model.wave.Wavelet

    • model.wave.opbased.OpBasedWavelet

    Identifiers: model.id and model.waveref These modules contain implementations of wave identifiers and referencesplus utility classes for working with them. Wave and wavelet ids uniquely identify their objects. Waverefs extendwave and wavelet ids to refer to points within a wave. At present this extends just to documents but will soon includelocations and versions within those documents.

    Legacy note: The code in model.id does not yet implement the draft specification for identifiers and includes aninelegant serialization scheme. Waverefs implement a superior serialization.

    Starting points:

    • model.id.WaveId and model.id.WaveletId

    • model.waveref.WaveRef

    Abstract data types: model.adt.* These modules implement abstract concurrent data types on wave documents,including lists, sets, maps and monotonic values. These data types are safe for use with wave’s optimistic concur-rency model, guaranteeing convergence when used correctly. These data types are the foundation for all concurrentapplication models built on waves.

    Starting points:

    14 Chapter 3. Wave Model Code Walk

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    • model.adt.BasicValue and model.adt.docbased.DocumentBasedBasicValue

    • model.adt.BasicSet and model.adt.docbased.DocumentBasedBasicSet

    Document schemas: model.schema.* This module implements schema constraints for wave documents. Schemasconstrain the content of wave documents so they may be safely interpreted by clients, including as abstract data types.Document schemas are compatible with operational transform such that a change which is valid at a client remainsvalid at the server and all other clients, regardless of the concurrent operations against which the change is transformed.

    Legacy note: The current hard-coded schema implementation has a number of shortcomings and there are plans tomove to a more powerful and flexible implementation.

    The conversation model: model.conversation This package implements the abstract conversation model which de-scribes the threaded conversational waves you commonly interact with in the Google Wave client.

    Starting points:

    • model.conversation.Conversation

    • model.conversation.WaveletBasedConversation

    Testing support: model.testing This package contains support classes for testing the wave model and code interactingwith the wave model.

    3.2. Let’s explore the code 15

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    16 Chapter 3. Wave Model Code Walk

  • CHAPTER

    FOUR

    TUTORIALS

    TODO: flesh out tutorials from the community, develop a structure here

    4.1 Navigating the Codebase and Making the First Change

    The following is a description on how to figure out how to implement a tiny feature without know much about the code.The actual feature is trivial to implement. The main learning of this starter project is to set up the dev environment,how to navigate the code base and make a change. In this spirit, the instructions below does not go directly to thefeature, rather it includes lots of investigative steps.

    1. Follow the instructions at Client Development Setup to set up the dev environment

    2. In windows or linux, start the browser with OOPHM plugin installed and navigate to the WIAB server as in theabove instruction. This lets you debug the client code.

    3. Let’s try to see if there are any classes to do with undo.

    (a) In eclipse hit ctrl+shift+t (class search), and type “Undo”.

    (b) Notice there is a class called UndoManagerImpl. Notice there is a method called undoPlus() in this class.

    (c) Let’s look up where it’s called, by putting the cursor over the method and hit ctrl+shft+g, which looks upcall references should take you to EditorUndoManagerImpl.undo().

    (d) Repeat call reference look up again on EditorUndoMangerImpl.undo(), should take you to Edi-torImpl:handleCommand(). Notice on line 764 if (event.isUndoCombo()) {. Bingo

    (e) Putting cursor over isUndoCombo() and hit ctrl+t, which looks up implementations of the method. Thiswill take you to SignalEventImpl.isUndoCombo()

    4. Looks like it currently uses “Z” for undo. Let’s change it to “0”.

    5. Refresh the browser with OOPHM and try the feature. The code now works in debug.

    6. Compile the WIAB (slow) to see it works outside of debug

    (a) In the wave-protocol directory run ant

    (b) Restart WIAB server

    7. Open WIAB in a browser without using OOPHM by directly visiting http://localhost:9898 and check the featureworks.

    (a) Open WIAB client.

    (b) Create a new wave

    (c) Type some text

    17

    http://localhost:9898

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    (d) ctrl+0

    4.2 Writing a DooDad

    TODO: Add images to help

    TODO: High level overview of what doodads are and how they work, conceptually (wave editor presentation containsa lot of this)

    In this tutorial we will build up a simple Image doodad, similar to the image thumbnails we are familiar with. We’llcover many editor features as we move through various versions of our doodad. We’ll build up the code that can befound in org.waveprotocol.wave.client.editor.examples.img, if you’d like to follow along from scratch, simply replacethat package in the examples with whatever package you’re working in.

    4.2.1 Set up the environment

    Follow the instructions on setting up “Editor Test Harness” in Client Development Setup

    4.2.2 Create a new Test Harness

    In the package of your choosing, add the following files. The examples below will assumethis has been done in org.waveprotocol.wave.client.editor.tutorial The complete solution is atorg.waveprotocol.wave.client.editor.examples.img

    TestModule.java:

    Note: Use Ctrl+Shift+O to get the required import statements in eclipse. In later examples, some import statementsthat are ambiguous will be explicitly listed for clarification

    To get up and running, you need is this code:

    public class TestModule implements EntryPoint {

    @Overridepublic void onModuleLoad() {

    final EditorHarness harness = new EditorHarness();harness.run();

    }}

    TestModule.gwt.xml: And of course a GWT module definition. Just declare the entry point, and a dependency on theEditorHarness.

    Launch

    1. Edit build.xml

    • Copy and paste ...

    • Rename

    18 Chapter 4. Tutorials

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    – editor_hosted -> img_hosted

    – org.waveprotocol.wave.client.editor.harness.EditorTest -> org.waveprotocol.wave.client.editor.harness.tutorial.TestModule

    • The result looks like:

    2. Start oophm

    • ant img_hosted

    • Open a browser and connect eclipse debugging session to oophm. See Client Development Setup

    – e.g. browser url click meh

    Get Going

    Let’s see what happens when we try to create one of our doodads before doing anything.

    • In the “set content” area, type

    • You should see an error: test (1289350503.948): That content does not conform to the schema: [more details....

    The reason is, we haven’t permitted our new element in the schema. To fix this, let’s define the schema for our element.Override EditorHarness’s getSchema() method like so:

    // Anonymous subclass of EditorHarness.final EditorHarness harness = new EditorHarness() {/*** Extend the schema with our experimental new doodad.

    ** Note that this is only necessary for new element types that are not

    * already in the main document schema.

    */@Overridepublic DocumentSchema getSchema() {

    return new DefaultDocumentSchema() {{

    // Permit our doodad to appear inside the elementaddChildren("body", "mydoodad");

    }};

    }};

    4.2. Writing a DooDad 19

    http://127.0.0.1:8888/org.waveprotocol.wave.client.editor.tutorial.TestModule/EditorTest.html?gwt.codesvr=127.0.0.1:9997

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    Now refresh and try again.

    This time it should not give any error, instead we should get a grey box that looks like this . That’s thedefault renderer we get when we haven’t registered one for that element type. So let’s go and do that...

    4.2.3 Create a Simple Renderer

    Let’s create a class MyDoodad. We’ll put our renderer as an inner class for now, since we’ll be adding a few moresmall classes later to do other things, and it’s convenient to group them together.

    // Listing import statements when they might be ambiguous.// For the rest, Ctrl+Shift+O in eclipse does the trick.//import com.google.gwt.dom.client.Document;import com.google.gwt.dom.client.Element;

    public class MyDoodad {public static String TAGNAME = "mydoodad";public static String REF_ATTR = "ref";

    /*** A trivial renderer that keeps the image's src attribute up-to-date with the

    * model's ref attribute.

    */static class SimpleRenderer extends RenderingMutationHandler {

    @Overridepublic Element createDomImpl(Renderable element) {

    Element imgTag = Document.get().createImageElement();DomHelper.setContentEditable(imgTag, false, false);return imgTag;

    }

    @Overridepublic void onActivatedSubtree(ContentElement element) {

    fanoutAttrs(element);}

    @Overridepublic void onAttributeModified(

    ContentElement element, String name, String oldValue, String newValue) {if (REF_ATTR.equals(name)) {

    element.getImplNodelet().setAttribute("src", newValue);}

    }}

    }

    Explanation: there’s two parts to the methods we add to our handler here:

    1. The createDomImpl method is called to provide the skeleton DOM of our doodad, i.e. DOM that would be thesame for all instances, regardless of the actual state of the XML (attributes, child nodes).

    Note: We use the setContentEditable method to stop the browser from putting fancy resize 9-boxes on our poorimage.

    2. The onXYZ methods are part of the NodeMutationHandler interface, that gets called when changes actuallyhappen.

    20 Chapter 4. Tutorials

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    • onAttributeModified gets called whenever an attribute changes. In this case, we’ll introduce asimple “ref” attribute that will refer to the image URL we want to display. The code simplychecks the name, and then updates the HTML DOM accordingly.

    Note: the term “nodelet” is a convention used to refer to HTML nodes, as an abbreviated way todisambiguate between our XML model nodes and our HTML rendering nodes.

    • However, we also want to update the rendering for an initial state as well, since our handler willget attached to the document after it has been created. It could also be added or removed at anytime. So we override onActivatedSubtree(), which will get called whenever our handler getsapplied to an element.

    – We use a convenience utility “fanoutAttrs” which will simulate attribute-modifiedevents for all existing attributes. For most simple doodads, this trick is sufficient, andlets us reuse code.

    Note: there is also an onActivationStart() method we could choose to override. Theonly difference is that onActivationStart() gets called before these methods get calledfor child nodes, and onSubtreeActivated() gets called after. If in doubt, it’s usuallybetter to override onSubtreeActivated().

    OK, now we want to register our renderer with the mydoodad tag name, so it getsapplied to elements matching that name.

    Let’s head back to TestModule.java

    First thing’s first, we’ve introduced a ‘ref’ attribute, so let’s go and add that to the schema:

    // Permit a 'ref' attribute on the element. We'll use this in the next step.// e.g. permit content like addAttrs(MyDoodad.TAGNAME, MyDoodad.REF_ATTR);

    Now, let’s register our renderer. It’s convention to create a static “register” method inside the doodad class, in this case,MyDoodad, and put all the registration in there. It’s a good convention because it means less boilerplate for callers;also, the register method acts as a sort of manifest, and declares all the dependencies of the doodad (just add morearguments to the register method if there are other things your doodad handlers need to be set up). Currently there’sjust one line of code in it, but we’re going to add a few more later, and this makes it easier. So, in MyDoodad.java:

    public static void register(ElementHandlerRegistry registry) {registry.register(Renderer.class, TAGNAME, new SimpleRenderer());

    }

    And then, to actually hook it up, back in TestModule.java we override a new method from EditorHarness, the extend()method, like so:

    @Overridepublic void extend(Registries registries) {

    MyDoodad.register(registries.getElementHandlerRegistry());}

    Done. Refresh, and try for content. You should see a nice wave logo.

    4.2.4 Adding a simple UI event handler

    Let’s add something to let users change the image, which will also exercise the onAttributeModified() code in adifferent way. Add this code to MyDoodad.java:

    4.2. Writing a DooDad 21

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    import com.google.gwt.user.client.Event;

    static class SimpleEventHandler extends NodeEventHandlerImpl {

    @Overridepublic void onActivated(final ContentElement element) {

    Helper.registerJsHandler(element, element.getImplNodelet(), "click", new JavaScriptEventListener() {

    @Overridepublic void onJavaScriptEvent(String name, Event event) {promptNewRef(element);

    }});

    }

    @Overridepublic void onDeactivated(ContentElement element) {

    // CleanupHelper.removeJsHandlers(element);

    }}

    static void promptNewRef(ContentElement element) {String newRef = Window.prompt("New Ref", element.getAttribute(REF_ATTR));if (newRef != null) {

    // Get the document view for mutating the persistent state, then update itelement.getMutableDoc().setElementAttribute(element, REF_ATTR, newRef);

    }}

    Now we simply need to register this class for the mydoodad tag name against NodeEventHandler.class. Let’s addanother line to our register method. So, in MyDoodad.java, it should look like this:

    public static void register(ElementHandlerRegistry registry) {registry.register(Renderer.class, TAGNAME, new SimpleRenderer());registry.register(NodeEventHandler.class, TAGNAME, new SimpleEventHandler());

    }

    Done. Refresh, and try for content. Now, clicking the doodad should let us changeits image. Try changing it to pics/yosemite-sm.jpg

    4.2.5 Canned content for debugging

    To save us some typing so we don’t have to type in the content we want to test each time, we can set up some cannedcontent for the suggest box. To do this, simply override this method for EditorHarness:

    @Overridepublic String[] extendSampleContent() {

    return new String[] {"","","Howdy",

    };}

    (Run it, and start typing in the content box as you would, and auto-complete suggestions will popup). I’ve also addedan example with a caption there that won’t work yet, but we’ll use it in the next example.

    22 Chapter 4. Tutorials

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    4.2.6 Using a full-blown GWT widget, and adding an editable sub-region

    Let’s spruce things up a bit. We want to add support for adding captions, and put a bit of nice chrome around ourdoodad. Instead of just using a plain image element, we can use a GWT widget. Elements with manual event handlersare good because they are lightweight, but in this case we’ve decided we want to use a widget.

    Write our vanilla GWT widget

    Create a file CaptionedImageWidget.ui.xml:

    .top {

    margin-left: 2px;margin-right: 1px;border-left: 1px solid #ccf;border-top: 1px solid #ccf;border-right: 2px solid #88a;border-bottom: 2px solid #88a;background: #eee;padding: 4px;

    /* NOTE(danilatos): More rules are needed to get this to work in IE.

    * See ImageThumbnail */display: inline-block;position: relative;

    }

    /** For some reason, the programmatic fixing of whitespace doesn't work for

    * FF, need to figure out why...

    */@if user.agent gecko1_8 {

    .top {white-space: normal;

    }}

    /* Apply the style to immediate children, i.e. the caption, not to the container

    * itself. This way we don't get ugly artifacts when there is no caption. */.container > * {margin-top: 4px;border: 1px solid #aac;border-left: 2px solid #88a;border-top: 2px solid #88a;text-align: center;background: white;

    }

    4.2. Writing a DooDad 23

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    And it’s widget class, CaptionedImageWidget.java:

    public class CaptionedImageWidget extends Composite {

    public interface Listener {void onClickImage();

    }

    /** UiBinder */interface Binder extends UiBinder {}private static final Binder BINDER = GWT.create(Binder.class);

    @UiField Element container;@UiField Image image;

    private Listener listener;

    public CaptionedImageWidget() {initWidget(BINDER.createAndBindUi(this));

    }

    public void setListener(Listener listener) {this.listener = listener;

    }

    public Element getContainer() {return container;

    }

    public void setImageSrc(String src) {image.setUrl(src);

    }

    @UiHandler("image")void handleClick(ClickEvent e) {

    if (listener != null) {listener.onClickImage();

    }}

    }

    Note that there is nothing special about these two files, this is a stock-standard ui-binder widget.

    4.2.7 Write the renderer and handler for the new widget

    The code is basically the same as before, the only thing to note is: For GWT widgets, we subclass GwtRenderingMu-tationHandler, which takes care of all the GWT widget logical attach/detach behavior for us. Event handling will thenbe hooked up correctly when the widget is placed in the editor (or other interactive context), and will not work whenit’s in read-only render mode. We also haven’t added support for captions yet, we’ll do that in a minute.

    Add this class inside MyDoodad:

    static class CaptionedRenderer extends GwtRenderingMutationHandler {

    public CaptionedRenderer() {

    24 Chapter 4. Tutorials

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    super(Flow.INLINE);}

    /** Gwt renderer equivalent of {@link #createDomImpl(Renderable)} */@Overrideprotected CaptionedImageWidget createGwtWidget(Renderable element) {

    return new CaptionedImageWidget();}

    @Overridepublic void onActivatedSubtree(ContentElement element) {

    super.onActivatedSubtree(element);fanoutAttrs(element);

    }

    @Overridepublic void onAttributeModified(

    ContentElement element, String name, String oldValue, String newValue) {super.onAttributeModified(element, name, oldValue, newValue);

    if (MyDoodad.REF_ATTR.equals(name)) {getWidget(element).setImageSrc(newValue);

    }}

    /** Convenience getter */CaptionedImageWidget getWidget(ContentElement e) {

    return ((CaptionedImageWidget) getGwtWidget(e));}

    }

    static class GwtEventHandler extends ChunkyElementHandler {private final CaptionedRenderer renderer;

    GwtEventHandler(CaptionedRenderer renderer) {this.renderer = renderer;

    }

    @Overridepublic void onActivated(final ContentElement element) {

    renderer.getWidget(element).setListener(new CaptionedImageWidget.Listener() {@Override public void onClickImage() {

    MyDoodad.promptNewRef(element);}

    });}

    }

    And update MyDoodad’s register method:

    public static void register(ElementHandlerRegistry registry) {CaptionedRenderer renderer = new CaptionedRenderer();registry.register(Renderer.class, TAGNAME, renderer);registry.register(NodeEventHandler.class, TAGNAME, new GwtEventHandler(renderer));

    }

    Now reload and try it!

    4.2. Writing a DooDad 25

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    4.2.8 Supporting captions

    First, in MyDoodad, create a constant:

    public static String CAPTION_TAGNAME = "mycaption";

    And add the following to the end our schema definition (in TestModule):

    // Permit our caption element to appear inside our doodad's main element// // text permitted here// addChildren(MyDoodad.TAGNAME, MyDoodad.CAPTION_TAGNAME);containsBlipText(MyDoodad.CAPTION_TAGNAME);

    This will allow us to add captions with editable text in them. If we try this now however, the caption won’t show up.There are two reasons: We haven’t defined a renderer for our tag Even if we had, the rendering corewouldn’t know where to put it.

    To address #1, we will use a paragraph renderer, using a div element for its HTML, to handle all the edit-abilitybehaviours we need. Simply add this line to our register() method:

    registry.register(Renderer.class, CAPTION_TAGNAME, ParagraphRenderer.create("div"));

    We want our caption to be editable when we’re in edit mode, and not editable when we’re out of edit mode. Here’show we do it:

    /*** Event handler for our caption. Demonstrates two things:

    * 1. Subclassing LinoTextEventHandler, which provides sane behavior for,

    * well, a line-of-text. (See its code for details)

    * 2. Use of utility to synchronise editability of caption region with main

    * editor region.

    */static class CaptionEventHandler extends LinoTextEventHandler {

    @Overridepublic void onActivated(ContentElement element) {super.onActivated(element);

    // Add a listener to edit mode changes.// We use an existing one that does exactly what we want: updates the editability// of our element's container as a result.DisplayEditModeHandler.setEditModeListener(element, UpdateContentEditable.get());

    }}

    And don’t forget:

    registry.register(NodeEventHandler.class, CAPTION_TAGNAME, new CaptionEventHandler());

    Now, address #2. Options:

    • We can override methods like onChildAdded/onChildRemoved (not shown in this tutorial, but similar to onAt-tributeModified), and handle things explicitly by putting the caption child’s HTML inside our caption containerwhenever the caption child shows up.

    • For our use case, which is by far the most common, where we simply want the html rendering of our childrento magically go into a container html nodelet, in the correct order, we can define a “container nodelet”, like so:(add this method to CaptionedRenderer)

    26 Chapter 4. Tutorials

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    /*** Specify where the HTML DOM of child XML elements goes. Our widget's

    * getContainer() method returns the inner 'div' where we would like to put

    * the caption. We use this as the "container nodelet" so that when the

    * 'mycaption' element gets added to 'mydoodad' (in the model XML), the

    * caption's main 'div' nodelet automatically gets added to our doodad's

    * inner container nodelet (in the render HTML).

    ** So our DOM will end up looking like this:

    ** {@literal

    **

    *

    *

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    ContentElement caption = getCaption(element);

    if (caption != null) {// If we have a caption, move the selection into the captionelement.getSelectionHelper().setCaret(

    Point. end(getCaption(element)));return true;

    } else {// If we don't have a caption, use the default behaviorreturn super.handleLeftAfterNode(element, event);

    }}

    /*** Similar to {@link #handleLeftAfterNode(ContentElement, EditorEvent)}

    */@Overridepublic boolean handleRightBeforeNode(ContentElement element, EditorEvent event) {ContentElement caption = getCaption(element);

    if (caption != null) {// If we have a caption, move the selection into the captionelement.getSelectionHelper().setCaret(

    Point.start(element.getRenderedContentView(), caption));return true;

    } else {// If we don't have a caption, use the default behaviorreturn super.handleRightBeforeNode(element, event);

    }}

    /*** Handles a left arrow at the beginning of the caption, moving the

    * selection out of the whole doodad. We receive this event because the

    * caption doesn't handle it and it bubbles outwards to our handler here.

    */@Overridepublic boolean handleLeftAtBeginning(ContentElement element, EditorEvent event) {// NOTE: The use of location mapper will normalise into text nodes.element.getSelectionHelper().setCaret(element.getLocationMapper().getLocation(

    Point.before(element.getRenderedContentView(), element)));return true;

    }

    /*** Similar to {@link #handleLeftAtBeginning(ContentElement, EditorEvent)}

    */@Overridepublic boolean handleRightAtEnd(ContentElement element, EditorEvent event) {// NOTE: The use of location mapper will normalise into text nodes.element.getSelectionHelper().setCaret(element.getLocationMapper().getLocation(

    Point.after(element.getRenderedContentView(), element)));return true;

    }

    private ContentElement getCaption(ContentElement element) {return (ContentElement) element.getFirstChild();

    }

    28 Chapter 4. Tutorials

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    }

    Don’t forget to update the register method, it should now look like this in its entirety:

    public static void register(ElementHandlerRegistry registry) {CaptionedRenderer renderer = new CaptionedRenderer();

    registry.register(Renderer.class, TAGNAME, renderer);registry.register(NodeEventHandler.class, TAGNAME,

    new CaptionedEventHandler(renderer));

    registry.register(Renderer.class, CAPTION_TAGNAME,ParagraphRenderer.create("div"));registry.register(NodeEventHandler.class, CAPTION_TAGNAME,

    new CaptionEventHandler());}

    4.2. Writing a DooDad 29

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    30 Chapter 4. Tutorials

  • CHAPTER

    FIVE

    SOCIAL MEDIA GUIDELINES

    The Apache Wave project may establish one or more social media accounts (Twitter, Facebook, Google+, YouTube,etc.) that it can use to spread news about the project and promote the project. Apache Wave Social Media Guidelines

    5.1 Access to Social Media Accounts

    Access to the social media accounts can be granted to any committer or PMC member who would like to participate.When possible, access will be through tools that do not require disseminating the login credentials.

    5.2 Do’s and Don’ts for Social Media

    Before posting anything, you’ll want to familiarize yourself with Apache’s Media and Analyst Relations page andbrand management page.

    Whether you’re posting from a personal account about Apache Wave or posting from one of the official accounts, thereare a few things you want to keep in mind.

    • Anything said in public is fair game for press.

    – Never post anything via social media you wouldn’t want to see reported on news sites.

    • Make sure what you’re saying/sharing is appropriate for all audiences, and reflects well on Apache Wave.

    – Be polite when talking about Wave and responding to questions.

    – Informal voice is OK, unprofessional is not.

    – Absolutely no use of NSFW language, images, or scenarios when using official Apache Wave accounts –and avoid associating Apache Wave with anything that is likely to be considered offensive.

    • Share relevant, positive information.

    – Feel free to share stories about Apache Wave, whether they come from the Apache Wave community, techpress, or folks outside of the press and community.

    – Avoid sharing negative stories about “competing” projects.

    – Keep posts/reposts relevant. Everybody loves LOLCats, but it’s probably best not to share them from theofficial Apache Wave social media accounts.

    – Please share event information so long as it’s Apache Wave-related. e.g. Promoting an event where thereare talks about Apache Wave is spot-on. Promoting an event only because a vendor that has an interest inApache Wave is participating would be outside the scope of Apache Wave social media accounts.

    • Be sure information is public

    31

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    – Companies sometimes discuss plans/ideas informally at events. It’s often a good idea to ask before sharinginformation on social media if it might be considered non-public. (For example, information presentedduring a talk should be fair game. Information shared over dinner may not be for public dissemination.)

    • Apache Wave does not have “sponsors”, events and activities have sponsors.

    – Avoid language like $foo_company is sponsoring the Apache Wave project.

    – Companies can sponsor events and activities. For example, $foo_company is hosting a Apache Wavemeetup in Atlanta this weekend.

    – When using group video chat tools, identify yourself in captions and “lower third” tools in relationship toyour Apache Wave participation, unless a person is an invited guest with other affiliations.

    • Don’t use Apache Apache Wave social media accounts to promote unrelated commercial activities.

    • When in doubt, ask

    – If you’re unclear on whether a post or item is OK, ask on the Apache-dev list, preferably with a draftof what you’d like to post. Consider no response or a majority of committers not dissenting after 24hours consent to publish; however, dissenting opinions should be considered respectfully prior to posting.Apache PMC members have a right of veto for Apache Wave-branded postings. The other contributors onthe list will always be happy to discuss and guide other contributors on what is and isn’t appropriate forour social media activities.

    32 Chapter 5. Social Media GuideLines

  • CHAPTER

    SIX

    WAVE LOGO USAGE

    The following Wave Logo can be used, reproduced, and modified freely in accordance with the Creative CommonsAttribution (CC-BY) license. When using the Wave Logo or any modification of it, proper attribution is required underthe terms of the Creative Commons Attribution license.

    33

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    34 Chapter 6. Wave Logo Usage

  • CHAPTER

    SEVEN

    PRESENTATIONS

    7.1 Talks

    7.1.1 Wave Summit Talks

    Day 1:

    Presenter/Topic Slides VideoWIAB system architecture (Alex North) slide1 video1Robot and Data APIs (Lennard de Rijk) slide2 video2Building, and running the code (Joseph Gentle) Talk: Setting up wave in a boX video3Wave model deep dive (Alex North) slide4 video4Development practises (Lennard de Rijk) slide5 video5Wave Project Governance slide6 video6

    Day 2:

    Presenter/Topic Slides VideoWave Server & Store slide7 video7Wave Export Options slide8 video8Demo: Novell demo video9socket.io (Tad Glines) video10Client authentication (Joseph Gentle) video11Local Gov’t & Wave (James Purser) slide12 video12Oracle (Grant Emeny-Smith) video13Outlook (Matt T) video14Federation protocol (Soren Lassen) slide15 video15Authentication performance (Scott Crosby) video16Wave panel and rendering (Dave Hearnden) slide17 video17

    Day 3:

    Presenter/Topic Slides VideoConcurrent Data & OT Alternatives slide18a slide18b video18Client/server protocol (Alex North) slide19 video19Real-time editor & Doodads (Dave Hearnden) slide20a slide20b video20Wave API Future (Pamela Fox) slide21 video21

    35

    https://docs.google.com/present/view?id=dggjrx3s_386gn37nngvhttp://www.youtube.com/watch?v=pDPBnmRDkaghttps://docs.google.com/present/view?id=dggjrx3s_387fmpsrvd4http://www.youtube.com/watch?v=Vs4cfvh2Ghghttp://www.youtube.com/watch?v=AyvQYCv6j34https://docs.google.com/present/view?id=dggjrx3s_388kz759bffhttp://www.youtube.com/watch?v=6ZqpeFydq4Ahttps://docs.google.com/present/view?id=dggjrx3s_389cxmgvgfghttp://www.youtube.com/watch?v=WpBrNUbB4sEhttps://docs.google.com/present/view?id=dggjrx3s_399c9t4k8d9http://www.youtube.com/watch?v=dBwakZjE76Mhttps://docs.google.com/present/view?id=dggjrx3s_390d4665cfdhttp://www.youtube.com/watch?v=7dbDhmX2v6Ehttps://docs.google.com/present/view?id=dggjrx3s_392d5v4rgc7http://www.youtube.com/watch?v=PKIHAIV_zPUhttp://www.youtube.com/watch?v=ICbBdAciwl0http://www.youtube.com/watch?v=X6lTwwzdR9ohttp://www.youtube.com/watch?v=xx0qbXC_uyshttps://docs.google.com/present/view?id=0AZFPDiThSCjmZG50ZnZuNl84OWdwd3JrNGQ2http://www.youtube.com/watch?v=AHG21gGWgmshttp://www.youtube.com/watch?v=Yhsi6mHvqZEhttp://www.youtube.com/watch?v=qvv-YlYcnAEhttps://docs.google.com/present/view?id=dggjrx3s_393hhvjstfwhttp://www.youtube.com/watch?v=z1VBdU38zlkhttp://www.youtube.com/watch?v=b4Xx4zdzniohttps://docs.google.com/present/view?id=dggjrx3s_394dgzq4kfhhttp://www.youtube.com/watch?v=76lmWFgnsgkhttps://docs.google.com/present/view?id=dggjrx3s_395fh6mckfbhttps://docs.google.com/present/view?id=dggjrx3s_401jmxbs2dghttp://www.youtube.com/watch?v=zo8uGlqQaCohttps://docs.google.com/present/view?id=dggjrx3s_396d4qmhmgphttp://www.youtube.com/watch?v=LOdOweJzqlMhttps://docs.google.com/present/view?id=dggjrx3s_397f4m5hhg7https://docs.google.com/present/view?id=dggjrx3s_398cms8qgc7http://www.youtube.com/watch?v=EuXApEulIzchttp://prezi.com/nhuvwmwsv0nj/wave-apis-now-beyond/http://www.youtube.com/watch?v=pnQ54V1OP6g

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    Day 5:

    Presenter/Topic Slides VideoWave UI Talk (Scott Peterson) video22

    7.2 2010

    Wave Protocol Summit (November 8-12) 23 presentations, demos and discussion

    Google Wave talks at Google IO 2010 (May 19-20) http://www.google.com/events/io/2010/sessions.html#Wave

    7.3 2009

    Google Wave Federation Jochen Beckmann (August) Overview of Wave, OT, data model, and details about Wavefederation. Slides (http://www.waveprotocol.org/presentations/wave_federation_pub.pdf?attredirects=0)

    Operational Transforms Alex Mah (July 30) In-depth discussion of operational transforms. Slides(http://docs.google.com/present/view?id=dggjrx3s_1573xdhxprd)

    Google Wave Federation Day Intro Dan Peterson (July 21) Announcement of open-sourcing of components, dis-cussion of roadmap for open-sourcing Slides (http://docs.google.com/present/view?id=dggjrx3s_112gfkbmsg3)| Youtube (http://www.youtube.com/watch?v=9hDZBieh5zg)

    Google Wave Federation Architecture Overview Soren Lassen (July 21) Discussion of the recently open-sourcedcomponents of the Google Wave - including the data model, operation transforms, various protocolbuffers, a simple text client. Slides (http://docs.google.com/present/view?id=dggjrx3s_113d5nv3cfr) | Youtube(http://www.youtube.com/watch?v=CRZbHpYhZrA)

    Google Wave: Under the Hood Casey Whitelaw, Dan Danilatos, Alex Mah, David Wang (May 29) Exploresvarious aspects of the technology powering Google Wave, including operational transforms, data model,and AJAX editor. Slides (http://dl.google.com/io/2009/pres/T_0115_Google_Wave_Under_the_Hood.pdf) |Youtube (http://www.youtube.com/watch?v=uOFzWZrsPV0)

    36 Chapter 7. Presentations

    http://www.youtube.com/watch?v=pfqThLudfEghttp://www.google.com/events/io/2010/sessions.html#Wavehttp://www.waveprotocol.org/presentations/wave_federation_pub.pdf?attredirects=0http://docs.google.com/present/view?id=dggjrx3s_1573xdhxprdhttp://docs.google.com/present/view?id=dggjrx3s_112gfkbmsg3http://www.youtube.com/watch?v=9hDZBieh5zghttp://docs.google.com/present/view?id=dggjrx3s_113d5nv3cfrhttp://www.youtube.com/watch?v=CRZbHpYhZrAhttp://dl.google.com/io/2009/pres/T_0115_Google_Wave_Under_the_Hood.pdfhttp://www.youtube.com/watch?v=uOFzWZrsPV0

  • CHAPTER

    EIGHT

    FURTHER READINGS

    8.1 Anthony Watkins

    Anthony Watkins has written a 5 part series going over the architecture of the example code:

    http://www.angleofsight.com/2010/02/google-wave-federation-part-1/ http://www.angleofsight.com/2010/02/google-wave-federation-part-2/ http://www.angleofsight.com/2010/02/google-wave-federation-part-3/ http://www.angleofsight.com/2010/02/google-wave-federation-part-4/http://www.angleofsight.com/2010/02/google-wave-federation-part-5/

    8.2 Bryce

    http://blog.wavenz.com/2009/07/introduction-to-operational.html http://blog.wavenz.com/2009/07/operational-transformation-algorithm.html http://blog.wavenz.com/2009/07/operational-transformation-and.htmlhttp://blog.wavenz.com/2009/07/operational-transformation-and_19.html

    37

    http://www.angleofsight.com/2010/02/google-wave-federation-part-1/http://www.angleofsight.com/2010/02/google-wave-federation-part-2/http://www.angleofsight.com/2010/02/google-wave-federation-part-2/http://www.angleofsight.com/2010/02/google-wave-federation-part-3/http://www.angleofsight.com/2010/02/google-wave-federation-part-3/http://www.angleofsight.com/2010/02/google-wave-federation-part-4/http://www.angleofsight.com/2010/02/google-wave-federation-part-5/http://blog.wavenz.com/2009/07/introduction-to-operational.htmlhttp://blog.wavenz.com/2009/07/operational-transformation-algorithm.htmlhttp://blog.wavenz.com/2009/07/operational-transformation-algorithm.htmlhttp://blog.wavenz.com/2009/07/operational-transformation-and.htmlhttp://blog.wavenz.com/2009/07/operational-transformation-and_19.html

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    38 Chapter 8. Further Readings

  • CHAPTER

    NINE

    OVERVIEW OF DESIGN STRUCTURE

    9.1 Source Code Organization

    9.2 Client Design

    This page aim to keep track of the technical and user experience design goals for Wave in a Box. It is likely thatdiscussions will be held in mailing lists and waves. This page will be updated with the current thinking and outcomesof those discussions.

    9.2.1 Current Collaboration Models

    There are a few well established collaboration models that currently exists in the electronic frontier. We list them herenot because WiaB intends to support all of them, replicate them, or replace them. They are discussed here because it isimportant to understand the current communication models that users are familiar with, why they work, and why theydon’t.

    39

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    9.2.2 Instant Messaging / Chat

    How it Works

    • Typically involves users communicating in near-real time.

    • Users have presence state (i.e. they are online or offline).

    • Users communicated and send messages typically when they are both online.

    • Communication is linear in that messages are always added to the end of the conversation.

    • Historical record of the conversation is typically managed by the client.

    • Once a message is sent it is usually not editable (some protocols support this, but it is rare).

    • Some protocols allow you to see that another user is actively typing, but generally don’t deliver the messageuntil the other user “sends” it.

    • Multi-User Chat Rooms are supported.

    • Private chats between sub groups happens “out of band” in side chat rooms or point to point messages.

    • Typically allow sending files between users in the conversation.

    • Limited ability to display files inline.

    • Files are not stored in the chat for future retrieval.

    Why It’s Useful

    The primary alternative to chat was email. With email, users had no expectation of when their messages would bereceived or responded to. Chat’s use of presence information let users know when another user was available toparticipate in a live conversation. With this there was an expectation that if another user responded to your chat youwould then engage in a near realtime discussion. The social aspects of chat dictated to a degree that conversationswould have a well defined start and end (i.e. it was rude to walk away from your computer and terminate a chat withoutsaying goodbye).

    What It’s Good At

    The linear nature of the conversation makes it very simple to understand for one on one conversations that have areasonable flow. There is a sense of active communication between parties that provides instant gratification com-munication. User’s are generally online and available or not. This lets other users know what to expect in terms ofresponsiveness before they initiate the communication.

    The chat service does not typically log conversations and chat clients generally only have rudimentary history func-tionality. Users generally don’t have an easy way to search for conversations that took place several weeks ago to findinformation. This is a limitation of the clients but has lead to the perception that chat conversations are ephemeral,much like a face to face conversation. This leads to a much more informal style of communication. Email tends to bemore formal since there is a perception that emails are forever. Part of the success of chat depends on users feelingfree to “type without thinking”. The type, then proof, then edit, then send process often used in email would take awayfrom the liveliness of the chat conversation.

    What It’s Bad At

    Chat is not so great at multi user conversations, or even conversations between two parties that are multi-topic orrapidly changing. The linear nature of chat makes it very difficult to respond to an earlier topic in the chat. Forexample if a remote user sends you two yes or no questions in back to back messages and you simply reply “no”, it isnot clear if you were referring to the first question or the second. This problem gets worse in multi user chat where sideconversations are likely to pop up. Going back through the linear history and attempting to decipher the conversationthreads is difficult.

    40 Chapter 9. OverView of Design Structure

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    Typical chat clients do not have sophisticated history and search functionality to allow users to pick up conversationsthat happened in the past. Additionally, once a chat message is sent it is usually not possible to edit that message.These two together make chat less than ideal for formal conversations and / or decision making.

    9.2.3 Email / Mailing Lists

    9.2.4 Collaborative Document Editing

    9.3 Repository Structure

    The official Apache Wave repository can be browsed here: https://svn.apache.org/repos/asf/incubator/wave/ . Its struc-ture is as follows:

    Wave In A Box code:

    • /trunk: Holds the most up-to-date code.

    • /branches/wave--release: Public Apache releases. E.g. wave-0.4-release

    • /branches/-: Development branches. E.g. stenyak-email_bot or alown-federation_fixes

    • /tags/wave-: E.g. wave-0.4-rc2

    Experiments code:

    • /experiments/: projects independent from Wave In A Box but related to wave concept. E.g.p2p

    Documentation:

    • /site/: contents of the Apache Wave website

    • /whitepapers/: additional documentation about Wave in general (protocols, etc).

    This is an overview of WiaB’s server structure, provided by Dave in the mailing list, and which may not be 100%accurate:

    9.3. Repository Structure 41

    https://svn.apache.org/repos/asf/incubator/wave/

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    9.4 Wave Server

    This is a high level view of some classes which make up the Wave Server component of WIAB. It isn’t a fully detaileddiagram.

    42 Chapter 9. OverView of Design Structure

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    Classes are grouped in funtional areas:

    • Server: classes orchestrating wavelets operations.

    • Wave and Wavelet management: classes representing wave and wavelet entities and also the entry point forwave/wavelet storage, the WaveMap class.

    • Wavelet persistence: classes providing persistence for wavelets.

    • Wave Bus: the gateway to WIAB clients.

    9.5 WaveMap

    It’s the component which provides access to wave/wavelet entities, renote and local ones. Its only client is theWaveServerImpl component. There is only one instance and it has a reference to a WaveletStore implementationin order to use the wavelet persistence.

    In general, the WIAB server works at wavelet level, almost all interfaces use wavelet as basic abstraction for parametersand return values. E.g. WaveMap allows to retrieve wavelets by name, but not the whole Wave, which is just an internalentity of the Wave class.

    9.6 Wavelet cache and factories

    At WaveMap creation, references to all wavelets are got from persistence and then put in a caché (seeWaveMap.waves:LoadingCache). So, when a Wave is requested from the waves map, the underlyingWave object is created and then remote and local wavelets are cached.

    A wave object has again cache maps for both remote and local wavelets. These cache’s rely on factories implementedand injected from the WaveServerModule class to load the right wavelets.

    9.5. WaveMap 43

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    9.7 Wave Bus

    The Wave Bus is the componet which dispatchs wavelet change notifications to its subscribers or clients. The WaveBusinterface it’s implemented by the WaveletNotificationDispatcher. Wavelet’s notifications are fired from the waveletcontainers (WaveletContainerImpl) via the WaveletNotificationSubscriber interface which is also implemented by therealization WaveBus class WaveletNotificationDispatcher. Clients are those implementing the WaveBus.Subscriberinterface:

    • ClientFrontendImpl

    • PerUserWaveViewDispatcher

    • RobotsGateway

    9.8 Wave Bus Subscribers

    Client Frontend

    The ClientFrontendImpl uses the server injected as a WaveletProvider for:

    • submit deltas to a wavelet

    • get wavelet’s history of deltas

    • get wavelets Ids from a wave

    • get a wavelet snapshot

    44 Chapter 9. OverView of Design Structure

  • Apache Wave (incubating) Developer Documentation, Release 0.4

    The ClientFrontend is a proxy between UI clients and the Wave server. UI Clients sent RPC requests to open acommunication channels for each Wave-Partincipant pair. This happens when the WaveClientRpcImpl componentcalls the method openRequest(). Then, a listener object (of type ClientFronted.OpenListener) is created in order toreceive asyncronous updates for that Wave’s wavelets.

    First call to the channel listener: it’s performed by ClientFrontend.openRequest() method and it provides a snapshot ofthe Wave. This is the only time when a full snapshot of a wave is retrieved from the server. Second and rest calls to thechannel listener: After channel is opened, listener is called anytime an update for the wave happens. This is performedby the WaveViewSubscription object for that channel. It manages the wave state using WaveletChannelState objects,a caché (or queue) of deltas to be submitted in a specifc wavelet. The WaveViewSubscription will call the channellistener in the method sendUpdate(), where only deltas are sent -no snapshots-.

    9.8. Wave Bus Subscribers 45

    FAQ'sCodeProtocol & Data Models

    ContributingRelease ProcedureClient Development SetupGadget Server Setup

    Wave Model Code WalkUnder construction!Let's explore the code

    TutorialsNavigating the Codebase and Making the First ChangeWriting a DooDad

    Social Media GuideLinesAccess to Social Media AccountsDo's and Don'ts for Social Media

    Wave Logo UsagePresentationsTalks20102009

    Further ReadingsAnthony WatkinsBryce

    OverView of Design StructureSource Code OrganizationClient DesignRepository StructureWave ServerWaveMapWavelet cache and factoriesWave BusWave Bus Subscribers