Add-Robot

    A robot which can stores user favorite robots using the JDO data store and add them automatically to the wavelet when it was added as participant.

The basic features of this are to add, delete and view. When the user enter the command “#add.robots.save”
it’s save all the current robots in the wavelet and automatically list the current favorite robots. And when users enter “#add.robots.delete<space><robotname>” it will delete that specific robot in the favorite.

Add Robots Samples

 

This Is How We Do It

    First Create an app engine project name AddRobot and setup the environment for JDO and Robots

    It is easier if you’re going to use eclipse with Google plug-in cause some configuration there is auto generated.

To set up Wave Robots refer to:

http://code.google.com/apis/wave/extensions/robots/java-tutorial.html

To set up JDO refer to:

http://code.google.com/appengine/docs/java/gettingstarted/usingdatastore.html

    Now we are ready, after setting up the environment. We have to create a datastore where we can save our favorite robots. Be sure that you already have PersistenceManagerFactory (Refer to JDO site above). Now let’s Create a new class named Robots with properties id, username and robotname with a private identifier and should be annotated with @Persistent to tell DataNucleus to store them as properties of objects in the App Engine datastore. And id should be annotated with @PrimaryKey to set id as primary key. It should be look like this:

package com.google.addrobots.jdo;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Robots{
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Long id;
    @Persistent
    private String userName;
    @Persistent
    private String robotsName;
    public Robots(String userName, String robotsName) {
        this.userName = userName;
        this.robotsName = robotsName;    
    }
    public Long getId() {
        return id;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getRobotsname() {
        return robotsName;
    }
    public void setRobotsname(String robotsName) {
        this.robotsName = robotsName;
    }
}

    Now let’s begin with the robot, create a servlet let say” AddRobbotServlet that extends the AbstractRobotServlet class (from the com.google.wave.api package) and implement the method processEvents() which accepts a RobotMessageBundle object. As the first functionality of add-robot is to add automatically all the favorite robot to the wavelet, so we need to implement the condition if bundle.wasSelfAdded(). If that returns true it will automatically add all favorite robots as participants of the wavelet, it should be like this:

package com.google.addrobots;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import com.google.addrobots.jdo.PMF;
import com.google.addrobots.jdo.Robots;
import com.google.wave.api.*;

@SuppressWarnings("serial")
public void processEvents(RobotMessageBundle bundle) {
    Wavelet wavelet = bundle.getWavelet();
    String creator = wavelet.getCreator();
 if(bundle.wasSelfAdded()) {           
    //Search if theres existing favorites robots and add it to participants
    PersistenceManager pm = PMF.get().getPersistenceManager();
    Query query = pm.newQuery(Robots.class,"userName == userNameParam");
     query.declareParameters("String userNameParam");
     List<Robots> bots=(List<Robots>) query.execute(creator);
     if(!bots.isEmpty()){
             for (Robots r : bots) {
                wavelet.addParticipant(r.getRobotsname());
        }
}
    pm.close();
Blip blip = wavelet.appendBlip();
                TextView textView = blip.getDocument();        
                //append new string to blip for confirmation
                textView.append("Favorite Robots has been added as participant");                  
             }
    }

    Then for the other adding and deleting command, we need to get what the users input in the blip so we need to use the event type blip submitted. Now we need to compare that words that the user enters on the blip. So were going to create again a condition filtering if the user input if #add-robots.save or #add-robots.delete in the blip. If the user enter #add-robots.save all the robots in the wavelet will be save as favorite that would be look like this:

for (Event e : bundle.getEvents()) {
    if (e.getType() == EventType.BLIP_SUBMITTED) {
    //get event blip
    Blip blip = e.getBlip();           
    TextView textView = blip.getDocument();
    //get blip text
    String strBlip = e.getBlip().getDocument().getText();
    String delimiter = " ";
    String[] temp = strBlip.split(delimiter);  
//#add-robots.save ivoked
    if(temp[0].trim().equals("#add-robots.save")|| temp[0].trim()=="#add-robots.save"){
    //delete existing robot first before adding new list
    //query to search robots
PersistenceManager pm = PMF.get().getPersistenceManager();
    Query query = pm.newQuery(Robots.class,"userName == userNameParam");
    query.declareParameters("String userNameParam");
    List<Robots> bots=(List<Robots>) query.execute(creator);
    if(!bots.isEmpty()){
        for (Robots g : bots) {
        //delete robots
        pm.deletePersistent(g);
        }
        }
//get all participant
List participant = wavelet.getParticipants();
    //get robot from participant check if with a host of appspot.com
    List<String> appspot = getAllAppspot(participant);
    textView.delete();
//save List to JDO
textView.append("All Robots here has been Saved To Favorites \n");
        for(String bot : appspot)
            {
Robots rob = new Robots(creator,bot);
        pm.makePersistent(rob);
            textView.append(bot+"\n");
            }
        pm.close();
        }

    Notice that we use Java String method split to get what the input we need from the blip. And notice also that we delete first all existing favorite robot before we add a new favorite, you can create other logic for that but for me that is much easier. Now for deleting our unwanted robot, we will again get the user input and compare if the input #add.robots.delete<space><robotname> then that specific robot with that name will be deleted. Now let’s continue with the code:

else if(temp[0].trim().equals("#add-robots.delete")|| temp[0].trim()=="#add-robots.delete"){
PersistenceManager pm = PMF.get().getPersistenceManager();
    Query query = pm.newQuery(Robots.class,"userName=='"+creator+"' && robotsName=='"+temp[1]+"'");
    List<Robots> bots=(List<Robots>) query.execute(wavelet.getCreator());
        if(!bots.isEmpty()){
            for (Robots g : bots) {
 //delete robots
pm.deletePersistent(g);
            wavelet.removeParticipant(temp[1]);
            }
            }
    textView.delete();
    textView.append(temp[1]+" Has Been Deleted");
    }else{   //some additional code here for other function
}  
    }
    }  
}

Now that’s it, we are finish with the robot servlet. Just read the code comments for its purpose. So it’s time to create a Servlet Mapping, you have to map this servlet to the URL path /_wave/robot/jsonrpc, edit the file war/WEB-INF/web.xml so that it looks like this:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
  <!-- Servlets -->
      <servlet>
        <servlet-name>AddRobots</servlet-name>
        <servlet-class>com.google.addrobots.AddRobbotServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>AddRobots</servlet-name>
        <url-pattern>/_wave/robot/jsonrpc</url-pattern>
    </servlet-mapping>
</web-app>

    And finally This robot needs a configuration file where we can configure the robot capability . From the Package Explorer, create a new folder named war/_wave/, then inside this folder create a file named capabilities.xml with the following contents:

<?xml version="1.0" encoding="utf-8"?>
<w:robot xmlns:w="http://wave.google.com/extensions/robots/1.0">
  <w:capabilities>
    <w:capability name="BLIP_SUBMITTED"/>
  </w:capabilities>
  <w:version>2</w:version>
</w:robot>

    As you can see, we use special event BLIP_SUBMITTED. This work whenever a blip is submitted so our robot can respond to this wave events. Now were done we can test now our robot, you can test your new robot by deploying it to App Engine, then adding it to a wave. Please refer again to the site above.

Bookmark and Share

8 thoughts on “Add-Robot”

  1. Looks like a great and short tutorial.
    Will try it in about 10 min. First i have to implement
    your forgotten getAllAppspot() methode ^^.
    Greats

  2. Thanks Jonas, that method should be like this:

        public List getAllAppspot(List<String> participant) {
            List appspot = new ArrayList();
            for(String bot : participant){
                int mid= bot.lastIndexOf("@");
                String ext=bot.substring(mid+1,bot.length());
                    if(ext.equals("appspot.com")){             
                        appspot.add(bot);
                        System.out.println(bot);
                    }
                    }
            return appspot;
            }
  3. Thanks a lot for this nice example, this is exactly what I was looking for! Works perfectly!

    PS: Just noticed a minor typo in the first paragraph #add.robots.save should be #add-robots.save or it won’t work 😉

  4. Hello!
    I’m, trying to remove robot from wave with removeParticipant(“robot name”), but its never removed. But i’m not using any DB part of code. Could it be the reason why bot is not removed? I’m writing bot for wave preview version.

  5. @vetalic,

    it doesn’t matter if you are using a DB part or not. That should be working even your not using any DB.

    @hiperion

    Yes, we have a SVN repository for that but i don’t know if we can give it to you.. But you are free to copy our code here instead.

  6. It’s my first robot and I need source code for test it because I’ve never programming a robot before. Can you help me? Perhaps Can I help you doing test? or perhaps Can you send me the source code?
    Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *