RhoConnect-Java
===
RhoConnect-Java library is designed for the [RhoConnect](http://rhomobile.com/products/rhoconnect/) Application Integration Server.
Using the RhoConnect-Java plugin, your [Spring 3 MVC](http://www.springsource.org/) application's data will transparently synchronize with a mobile application built on the [Rhodes framework](http://rhomobile.com/products/rhodes), or any of the available [RhoConnect clients](http://rhomobile.com/products/rhoconnect/).
## Prerequisites
* Java (1.6)
* Maven2 (2.2.1)
* Git
* [Rhoconncect-java](https://github.com/downloads/rhomobile/rhoconnect-java/rhoconnect-java-1.0.1.jar) plugin jar file
## Getting started
We assume that you have a complete java end-to-end application using Spring 3.0 MVC as the front end technology and Hibernate as backend ORM. For this application we will also use Maven2 for build and dependency management and some database to persist the data. The database is accessed by a Data Access (DAO) layer.
Copy [Rhoconncect-java](https://github.com/downloads/rhomobile/rhoconnect-java/rhoconnect-java-1.0.1.jar) plugin jar file to your PC.
You can also create target rhoconnect-java plugin jar from sources by cloning rhoconnect-java repository
:::term
$ git clone https://github.com/rhomobile/rhoconnect-java.git
and executing in cloned project directory the following commands:
:::term
$ mvn clean
$ mvn compile
$ mvn jar:jar
The archived rhoconnect-java-x.y.z.jar file will be created in the project target/ directory.
For testing and evaluation purposes you can use [RhoconnectJavaSample](https://github.com/shurab/RhoconnectJavaSample) application as a starting point before continuing with the following steps.
### Adding Dependencies to Your Maven 2 Project
Add dependencies to your Apache Maven 2 project object model (POM): log4j, Apache common beanutils, and Jackson JSON mapper. In the RhoconnectJavaSample application, this code is in the pom.xml file.
:::xml
log4j
log4j
1.2.9
jar
false
commons-beanutils
commons-beanutils
1.8.3
org.codehaus.jackson
jackson-mapper-asl
1.9.0
jar
false
You must also add the rhoconnect-java jar to your Maven 2 project. At this moment rhoconnect-plugin jar is not available in Maven public repositories and you need install the jar manually into your Maven's local repository.
Download the `rhoconnect-java-1.0-SNAPSHOT.jar` jar file and put it into your hard drive, and issue the following Maven's command:
:::term
$ mvn install:install-file -Dfile=/path-to-jar/rhoconnect-java-1.0.1.jar -DgroupId=com.rhomobile.rhoconnect -DartifactId=rhoconnect-java -Dversion=1.0.1 -Dpackaging=jar
Now, the `rhoconnect-java` jar library is included into your Maven local repository.
In the RhoconnectJavaSample application, you would add this code to the pom.xml file.
:::xml
com.rhomobile.rhoconnect
rhoconnect-java
1.0.1
jar
### Updating Your Servlet XML Configuration File
Update your servlet xml configuration file to include rhoconnect-java metadata: the packages, converters, and beans. In the RhoconnectJavaSample, the following code is added to src/main/webapp/WEB-INF/spring-servlet.xml file.
:::xml
The `setAppEndpoint` method in the `rhoconnectClient` bean in the above code sample is a main point in establishing the communication
link between the `Rhoconnect` server and the Spring 3 MVC application. It has the following properties that you need to configure.
endpointUrl |
rhoconnect server's url, for example http://localhost:9292 |
appEndpoint |
your Spring 3 MVC app url, for example http://localhost:8080/contacts |
apiToken |
rhoconnect server's api_token, for example sometokenforme |
The `authenticate` bean will be called by rhoconnect server to authenticate users, and has to implement `Rhoconnect` interface provided by rhoconnect-java plugin:
:::java
package com.rhomobile.rhoconnect;
import java.util.Map;
public interface Rhoconnect {
String authenticate(String userName, String password, Map attributes);
}
For example:
:::java
package com.rhomobile.contact;
import java.util.Map;
import org.apache.log4j.Logger;
import com.rhomobile.rhoconnect.Rhoconnect;
public class ContactAuthenticate implements Rhoconnect {
private static final Logger logger = Logger.getLogger(ContactAuthenticate.class);
@Override
public String authenticate(String login, String password, Map attributes) {
logger.debug("ContactAuthenticate#authenticate: implement your authentication code!");
// TODO: your authentication code goes here ...
// Return null value if authentication fails.
// Otherwise, returned value is data partitioning: i.e. user name for filtering data on per user basis
//return login;
// But if you want your data to be partitioned by 'app' (i.e. the data will be shared among all users),
// you should return string "app": it will instruct Rhoconnect to partition the data accordingly.
return "app";
}
}
### Establishing communication from the RhoConnect server to java back-end application
You need to establish communication from the RhoConnect instance to your java back-end application by mixing RhoconnectResource interface in your data access (DAO) service class:
:::java
package com.rhomobile.rhoconnect;
import java.util.Map;
public interface RhoconnectResource {
Map rhoconnectQuery(String partition);
Integer rhoconnectCreate(String partition, Map attributes);
Integer rhoconnectUpdate(String partition, Map attributes);
Integer rhoconnetDelete(String partition, Map attributes);
}
To help rhoconnect-java plugin correctly do mapping of model name to service bean you should take into account the following conventions:
* Name of the DAO service bean (class) should be model name followed by `ServiceImpl` suffix (i. e. `ContactServiceImpl` for model `Contact`)
* Service bean should be auto-wired into corresponding controller via @Autowired annotation
Data partitioning in your code should be based on filtering data for unique user (i.e. your user name) or per application (shared dataset for all users).
For more information about RhoConnect partitions, please refer to the [RhoConnect docs](http://docs.rhomobile.com/rhosync/source-adapters#data-partitioning).
### Establishing communication from java back-end application to the RhoConnect server
You also must to establish the communication from your java back-end application to the RhoConnect instance by auto-wiring `RhoconnectClient` bean into your DAO service class and inserting notifications hooks into data access (create/update/delete) methods.
`RhoconnectClient` bean is provided by rhoconnect-java plugin and responds to the following methods you have to call:
* boolean notifyOnCreate(String sourceName, Object objId, Object object)
* boolean notifyOnUpdate(String sourceName, Object objId, Object object)
* boolean notifyOnDelete(String sourceName, Object objId)
Example for `RhoconnectJavaSample` application:
:::java
package com.rhomobile.contact.service;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.rhomobile.contact.dao.ContactDAO;
import com.rhomobile.contact.form.Contact;
import com.rhomobile.rhoconnect.RhoconnectClient;
import com.rhomobile.rhoconnect.RhoconnectResource;
@Service
public class ContactServiceImpl implements ContactService, RhoconnectResource {
//private static final Logger logger = Logger.getLogger(ContactServiceImpl.class);
@Autowired
private ContactDAO contactDAO;
@Autowired
private RhoconnectClient client;
private static final String sourceName = "Contact"; // name of DAO model
@Transactional
public int addContact(Contact contact) {
int id = contactDAO.addContact(contact);
client.notifyOnCreate(sourceName, Integer.toString(id), contact);
return id;
}
@Transactional
public void updateContact(Contact contact) {
contactDAO.updateContact(contact);
client.notifyOnUpdate(sourceName, Integer.toString(contact.getId()), contact);
}
@Transactional
public void removeContact(Integer id) {
contactDAO.removeContact(id);
client.notifyOnDelete(sourceName, Integer.toString(id));
}
@Transactional
public List listContact() {
return contactDAO.listContact();
}
@Transactional
public Contact getContact(Integer id) {
return contactDAO.getContact(id);
}
@Override
@Transactional
public Map rhoconnectQuery(String partition) {
Map h = new HashMap();
List contacts = listContact();
Iterator it = contacts.iterator( );
while(it.hasNext()) {
Contact c =(Contact)it.next();
h.put(c.getId().toString(), c);
}
return h;
}
@Override
@Transactional
public Integer rhoconnectCreate(String partition, Map attributes) {
Contact contact = new Contact();
try {
BeanUtils.populate(contact, attributes);
int id = addContact(contact);
return id;
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
@Override
@Transactional
public Integer rhoconnectUpdate(String partition, Map attributes) {
Integer id = Integer.parseInt((String)attributes.get("id"));
Contact contact = getContact(id);
try {
BeanUtils.populate(contact, attributes);
updateContact(contact);
return id;
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
@Override
@Transactional
public Integer rhoconnetDelete(String partition, Map attributes) {
String objId = (String)attributes.get("id");
Integer id = Integer.parseInt(objId);
removeContact(id);
return id;
}
}
Click [here](https://github.com/shurab/RhoconnectJavaPluginDemo) to download full source code of Contact manager application with rhoconnect-java plugin.
## Meta
Created and maintained by Alexander Babichev.
Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php).