Documentation : Java Simple Tutorial

In tutorial we will create simple web application to add new task entities into mobeelizer cloud. You can use application created here with titanium tutorial, because it base on the same application definition. 

In this document we assumes that you are familiar with:

  • JAVA language
  • Basic of Spring roo (see)
  • Key concepts of Mobeelizer platform (see)

Design Your app

Start working with the Mobeelizer. Create your FREE account.

Open the Mobeelizer App Designer and login with your account. Then, press CREATE NEW APPLICATION button and insert it's name Todo.

In your applications designer panel enter Models section on the left. Then create new model Task.

Now we have to create new fields for Task model.

Name
Required property
Type
Default value property
Additional properties
titleyestext--
descriptionnotext--
contextyesinteger0min: 0 max: 4
completedyesbooleanfalse-

For all fields credentials for role: users-mobile should be:

  • READ - all
  • CREATE - own
  • UPDATE - own

Next section to configure is Groups & Roles, by default there is one group called users and one device category mobile and this two together create role users-mobile. This default configuration is not enough for us, we need to create new device category called 'web', in consequence of it new role 'users-web' was created. 

When everything is done in Create mode, deploy our application to test environment, and create two users with passwords:

  • a - usera
  • b - userb

We have to also create administrator user for our web application. This user is required  to configurate mobeelizer in Java SDK. 

login: webAppAdmin

password: pass

Finally, download application definition - Todo.xml. 

Create Spring MVC application

Create new folder in your working directory for your new project. Open console and navigate to just  created directory, open roo shell in there and type 

project --topLevelPackage 'name.of.your.toplevel.package'

We will start with creating our model class. To do this type this command in Roo Shell:

class --class ~.model.Task --rooAnnotations 

You can see that new package with class inside was created. Let's create fields in our class, using Roo Shell.

field string --fieldName guid
field string --fieldName owner
field boolean --fieldName modified --primitive true
field boolean --fieldName conflicted --primitive true
field boolean --fieldName deleted --primitive true
field string --fieldName title
field string --fieldName description
field number --type int --fieldName context
field boolean --fieldName completed --primitive true

Ok, our model class is created now. 

Because we are developing Spring MVC application we will setup web mvc now. 

web mvc setup

And create controller for Task model. 

web mvc controller --class ~.controller.TaskController

When controller is ready it is time for service which will perform all business logic.

service --interface ~.services.TaskService --entity ~.model.Task

Nice, spring roo will create almost all work for us, last thing created by Roo will be spring security.

security setup

We will use eclipse to write a code, to create eclipse project on just created application type in roo shell this command:

perform eclipse

 

Setup mobeelizer

Ok, our project is ready, it is time for mobeelizer now. Firstly we have to tell maven to download Java SDK and add it into the project. Open pom.xml file in xml editor and add new repository and then new dependency.

pom.xml
    <repositories>
	    <repository>        
	        <id>qcadoo-releases-repository</id>        
	        <url>http://nexus.qcadoo.org/content/repositories/releases</url>
	    </repository>        
    </repositories>
pom.xml
    <dependencies>
        <dependency>        
	        <groupId>com.mobeelizer</groupId>        
	        <artifactId>java-sdk</artifactId>        
	        <version>1.5.0</version>    
	    </dependency>
    </dependencies>

Next think to do is adding application definition file into project resources. To do this download definition from App Designer (Get XML button in Create section), rename it to 'application.xml' and put into src/main/resources folder. 

For our example we will create singleton class which will be responsible for creating Mobeelizer class object, we will call this class "MobeelizerSetup" and create it in "~.utils" package. 

class --class ~.utils.MobeelizerSetup

When class was created let's implement it like this:

MobeelizerSetup.java
public class MobeelizerSetup {
	
	private static MobeelizerSetup instance;
	
	private Mobeelizer mobeelizer;
	
	private MobeelizerSetup(){
		MobeelizerConfiguration conf = new MobeelizerConfiguration();
		conf.setDefinition(getClass().getResourceAsStream("/application.xml")); // stream to the application definition file
		conf.setDevice("web"); // device category name specified in app designer
		conf.setDeviceIdentifier("web_346234547"); //unique device identifier - it can be ip address of the server or other unique value
		conf.setPackageName("com.mobeelizer.todo.model"); // package with model classes - be sure it indicates yor package
		conf.setUser("webAppAdmin"); // admin user credentials
		conf.setPassword("pass");
		mobeelizer = new Mobeelizer(conf);
	}
	
	public static MobeelizerSetup getInstance(){
		if(instance == null){
			instance = new MobeelizerSetup();
		}
		
		return instance;
	}
	
	public Mobeelizer getMobelizer(){
		return mobeelizer;
	}
}

In constructor we are creating MobeelizerConfiguration object and then base on it we are creating Mobeelizer object which provide all needed operations on mobeelizer cloud for example authorization, synchonization etc.

Integrate spring security with mobeelizer

In our example we want to authenticate users using mobeelizer, this functionality is necessary to specify new entities owner. To implement it we have to create new class called MobeelizerAuthenticationProvider extending AbstractUserDetailsAuthenticationProvider class and then specify it as authentication provider in spring security configuration xml.

class --class ~.provider.MobeelizerAuthenticationProvider --extends  AbstractUserDetailsAuthenticationProvider

Class extending AbstractUserDetailsAuthenticationProvider have to override two methods - additionalAuthenticationChecks and retrieveUser.

MobeelizerAuthenticationProvider.java
public class MobeelizerAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
	@Override
	protected void additionalAuthenticationChecks(UserDetails userDetails,
			UsernamePasswordAuthenticationToken authentication)
			throws AuthenticationException {
	
	}
	@Override
	protected UserDetails retrieveUser(String username,
			UsernamePasswordAuthenticationToken authentication)
			throws AuthenticationException {
		String password = (String) authentication.getCredentials();
		List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
		
		try{
		
			String userRole = MobeelizerSetup.getInstance().getMobelizer().authenticate(username, password);
			authorities.add(new SimpleGrantedAuthority(userRole));
		}
		catch(IllegalStateException e){
			throw new BadCredentialsException(e.getMessage());	
		}
		
		return new org.springframework.security.core.userdetails.User(username,
				password, true, true, 
				true, 
				true, authorities);
	}
}

Let's give you some extra description - in retriveUser method we are using MobeelizerSetup singleton class to retrive Mobeelizer object and then we are authenticating user using it methods.

When provider is ready, we have to open applicationContext-security.xml file. (Placed in src/main/resources/META-INF/spring/ folder) In opened file we have to create new object of just implemented class and then replace generated authentication provider with our solution. 

applicationContext-security.xml
<beans:beans ...>
    ...
    <beans:bean class="com.mobeelizer.todo.provider.MobeelizerAuthenticationProvider" id="mobeelizerProvider"> 
    </beans:bean>
    <authentication-manager alias="authenticationManager">
        <authentication-provider ref="mobeelizerProvider">
        </authentication-provider>
    </authentication-manager>
</beans:beans>

Note that class attribute value in bean node contains class name with package path. Be sure that it is correct. 

Last think to configure in xml file is secure URI of task page. 

applicationContext-security.xml
<intercept-url pattern="/task/**" access="hasRole('users-web')" /> 

'users-web' is role of mobeelizer user who belongs to 'users' group and is logged in on 'web' device category.

Logging in is completed, you can test it now. Run our project on the server, open web page (in default configuration it should be available on localhost:8080/Todo url) and select Task controller in the menu. You should be asked to authenticate your self. Type mobeelizer user credentials to do that.

Add entity into mobeelizer cloud

To add new entity we will use already generated page. Open index.jspx view file of task controller. (src/main/webapp/WEB-INF/views/task/index.jspx) and change it content to this:

views/task/index.jspx
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div  >
	<form method="POST" action="create">
		<label for="title_input">Title</label>
		<INPUT type="text" id="title_input" name="title"/>
		<br />
		<br />
		<label for="description_input">Description</label>
		<TEXTAREA  id="description_input" name="description" title="Description" >Type description...
		</TEXTAREA>
		<br />
		<br />
		<label for="context_input">Context</label>
		<INPUT type="number" min="0" max="4" id="context_input" name="context"/>
		<br />
		<br />
		<label for="completed_select">Is completed</label>
		<SELECT name="completed" id="completed_select"> 
			<OPTION label="Yes" value="true" />
			<OPTION label="No" value="false" />
		</SELECT>
		<br />
		<br />
		<input type="submit" value="Create"/>
	</form>
</div>

It is standard html form which contains 4 fields to input title, description, context and completed values of new task. Http request method is set to POST and action to create it means it will send http post request to task controller create method.

We also have to create another page to show result of add operation. Create success.jspx file in task folder and implement it like in code below:

views/task/success.jspx
<div>
    <h2>${title }</h2>
    <p>${message }</p>
</div>

It is also necessarily to define this new view in views.xml file placed in task folder. 

views/task/views.xml
...
<tiles-definitions>
    ...
    <definition extends="default" name="task/success">
        <put-attribute name="body" value="/WEB-INF/views/task/success.jspx"/>
    </definition>
</tiles-definitions>

Ok, our view is ready we have to create controller methods to handle http requests from it. 

TaskController.java
@RequestMapping("/task/**")
@Controller
public class TaskController {
	@Autowired
	private TaskService taskService;
	
    @RequestMapping
    public String index() {
        return "task/index";  
    }
    
    @RequestMapping(method = RequestMethod.POST, value="create")
    public String create(@Validated Task task, ModelMap modelMap){
        // TODO: invoke service method and fill modelMap to show add operation result.
    	return "task/success";
    }
}

Before we implement create method we have to define method provied be our service. Open TaskService interface and look at code below:

TaskService.java
@RooService(domainTypes = { com.mobeelizer.todo.model.Task.class })
public interface TaskService {
	boolean addEntityAndSynchronize(String user, Task task);
}

Our service contains only one method that add entity into mobeelizer cloud and returns boolean result. We can come back now to controller and implement create method.

TaskController.java
    @RequestMapping(method = RequestMethod.POST, value="create")
    public String create(@Validated Task task, ModelMap modelMap){
    	User user = (org.springframework.security.core.userdetails.User) SecurityContextHolder
				.getContext().getAuthentication().getPrincipal();
    	if(taskService.addEntityAndSynchronize(user.getUsername(),task)){
    		modelMap.addAttribute("title", "Success");
        	modelMap.addAttribute("message", "Task added into mobeelizer cloud successfully.");	
    	}
    	else{
    		modelMap.addAttribute("title", "Failure");
        	modelMap.addAttribute("message", "Unable to perform synchronization.");
    	}
    	return "task/success";
    }

It is pretty easy, we are getting current user from SecurityContextHolder and invoking service method. If method result is true we are adding success message attributes into model map, otherwise we are adding failure message.

Last thing to do in this example is implementing our service. 

TaskServiceImpl.java
@Service
public class TaskServiceImpl implements TaskService {
	
	private boolean result = false;
	
	@Override
	public boolean addEntityAndSynchronize(String user, Task task) {
		List<Object> entities = new ArrayList<Object>();
		task.setConflicted(false);
		task.setDeleted(false);
		task.setGuid(UUID.randomUUID().toString());
		task.setModified(true);
		task.setOwner(user);
		entities.add(task);
		
		MobeelizerSetup.getInstance().getMobelizer().syncAndWait(entities, null, new MobeelizerSyncCallback() {	
			@Override
			public void onSyncFinishedWithSuccess(Iterable<Object> arg0,
					Iterable<MobeelizerFile> arg1, Iterable<String> arg2,
					MobeelizerConfirmSyncCallback confirmCallback) {
				TaskServiceImpl.this.result = true;
		        confirmCallback.confirm();
			}
			
			@Override
			public void onSyncFinishedWithError(MobeelizerErrors arg0) {
				for(MobeelizerError error : arg0.getGlobalErrors()){
					System.out.println(error.getMessage());
				}
				TaskServiceImpl.this.result = false;
			}
			
			@Override
			public void onSyncFinishedWithError(MobeelizerOperationError error) {
				System.out.println(error.getMessage());
				TaskServiceImpl.this.result = false;
			}
		});
		return result;
	}
}

Mobeelizer object provides two types of sync methods, synchronous called syncAndWait and asynchronouse called sync. We are calling synchronous method because we want to call it in the same thread and wait for result. When synchronization finish with success it is really important to confirm it calling confirm method from confirm callback.

One the begining of this method we are setting owner of our new entity and then we are just invoking Mobeelizer sync method. And actually that is all. 

Conclusion

In this example we are learn how work with Mobeelizer java SDK, how to setup it and how easy synchronization and authorization could be. 

Attachments:

webAppAdmin.png (image/png)