Friday, May 30, 2014

REST API development with JAVA

As we all know java is a powerful programming language. It offers almost everything for web development and REST API development.

There are many ways through which you can develop REST API, but here i am going to share knowledge about most common and easy to use jersey web service APIs.

Jersey is a framework specially designed to develop REST APIs by Oracle.
In this tutorial i am using jersey 2.0 API, which is the latest release of jersey. While there are some API level changes from jersey 1.0 to 2.0 which offers some more functionality in 2.0 but a major change which blocks all the beginner to start their 1st REST API project is the web.xml changes.

Basically jersey servlet container class has been changed in 2.0. In 1.0 jersey jars the servlet container
class was "com.sun.jersey.spi.container.servlet.ServletContainer" while in 2.0 it has been changed to
"org.glassfish.jersey.servlet.ServletContainer".

Many tutorial available online are old enough and generally uses 1.0 jersey version which creates confusion for the new comer.

so if you are using jersey 1.0 jars then your web.xml should look like this(Basic configuration):
"web.xml if using jersey jars version 1.0"
xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>com.ashish.nigam.lovechat</display-name>
  <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>com.sun.jersey.config.property.packages</param-name>
      <param-value>com.ashish.nigam.lovechat</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>
</web-app> 
and if you are using jersey 2.0 jars then your web.xml should look like below(Basic configuration):
"Web.xml" when using jersey jars version 2.0"
xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>lovechat</display-name>
  <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>  
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>com.nigam.ashish.lovechat</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet> 
  <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>
</web-app> 

So lets start with step by step guide to write your first REST API:

1: Create a Dynamic Web Project.
2: Copy all the downloaded jersey jars in WEB-INF folder inside WebContent folder.
3: Edit web.xml file as described above.
4: Go inside your package directory and open .java file, edit it with most common code shared below.
package com.nigam.ashish.lovechat; // replace it with your package name import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; // Plain old Java Object it does not extend as class or implements // an interface // The class registers its methods for the HTTP GET request using the @GET annotation. // Using the @Produces annotation, it defines that it can deliver several MIME types, // text, XML and HTML. // The browser requests per default the HTML MIME type. //Sets the path to base URL + /hello @Path("/hello") public class Hello { // This method is called if TEXT_PLAIN is request @GET @Produces(MediaType.TEXT_PLAIN) public String sayPlainTextHello() { return "Hello Jersey, this is plan text"; } // This method is called if XML is request @GET @Produces(MediaType.TEXT_XML) public String sayXMLHello() { return "" + " Hello Jersey, good to have xlm reply" + ""; } //This method is called if XML is request @GET @Produces(MediaType.APPLICATION_JSON) public String sayJSONHello() { return "Hello Jersey, good to have json reply"; } }


5: Now configure your eclipse with tomcat 6 or 7. (preferred is 7).
6: right click on your project and go to RUN AS--> then RUN ON SERVER.

When it launches on eclipse browser or external browser, at the end add /rest/hello to get string returned
as per API request.
/rest/hello is basically two component. one mentioned in web.xml under "url-pattern" and another as class path in your .java class "@Path("/hello")".


Project configuration image:


Sample Screen for REST API testing:



Reference Links:

(Jersey Java Related)

  1. https://jersey.java.net/documentation/latest/deployment.html
  2. http://stackoverflow.com/questions/22022114/org-glassfish-jersey-servlet-servletcontainer-classnotfoundexception
  3. https://jersey.java.net/apidocs/2.0/jersey/org/glassfish/jersey/servlet/ServletContainer.html
  4. https://blogs.oracle.com/japod/entry/jersey_2_0_integrated_into
  5. https://jersey.java.net/download.html
  6. https://jersey.java.net/
  7. http://www.vogella.com/tutorials/REST/article.html
  8. http://www.9lessons.info/2012/09/restful-web-services-api-using-java-and.html
Complete Source Code used in Blog:
  1. https://app.box.com/s/e2szc0crsbayffejbg2a // source code link
Feel free to ask any question regarding this, and subscribe to my blogs for more new coming blogs and deep dive for existing one.


Thank you

Wednesday, May 28, 2014

Building your Own Titanium SDK with Java Script Core

Building your Own Titanium SDK with Java Script Core


Pre-requisite: You are aware of iOS basics and familiar with iOS app development process.

Q.- How does Appcelerator Titanium Work?
A.- Basically is has modified Java Script Core open source framework and created ticore library,
      Which gets added to your build Xcode project when you build your Titanium App for iOS.

So you can use Java Script Core framework directly and create your own SDK, which will work as your want.
Appcelerator has customised this to make a cross platform SDK, because similar JS functionality is provided in android side by V8 JS engine.
So we can use Java Script Core in iOS and V8 in android app development and provide common functionality to create Titanium Like SDK.

Let me show with an example:

Create a Xcode Project, as we create in Xcode. for example say single window application.

My single window Xcode Project:



In the above picture, i have added ANMakePoint and MyButton classes along with all the .js files.

Now the open the project in Xcode:

Add Java Script Core framework

Steps:

  1. After adding the Java Script Core framework, go to your view controller and import the necessary header: "#import ".
  2. After than you need to add one Java Script file, like i did as test.js.
  3. Write your java script function there and save the file.
  4. now come to viewController.m and in viewdidload() function, initialise your JS context and evaluate your Java Script code.
  5. Then you need to get the function form evalauted script using context.
  6. After that you need to call the JS function from Objc code.
  7. Sample Code:

              NSString *myJSPath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"js"];
              NSString *Script = [NSString stringWithContentsOfFile:myJSPath encoding:NSUTF8StringEncoding error:nil];

              JSContext *context = [[JSContext alloc] init];
              JSValue *value = [context evaluateScript:Script];
             // OBJC-->JS calling example
             JSValue *result = [function callWithArguments:@[@5]];


            This is very basic example code for Objc to JS calling.

Now Deep diving a little:

What is bonding between JS and Objc:
Actually Java Script Core framework is designed in  such a way to take care the differences required by two different languages to execute their code.

For Example Objc is a compiled language and code is compiled before execution, while JS is interpreted language and to run JS with Objc we require a VM(virtual machine) to provided interpreted 
environment.

Now This VM and context to execute code is provided by Java Script Core.
Note: VM:- Provide environment.
          Context:- is kind of global java script object for your js file. In web world its Window object.
          JSValue: is java script object or function or any value on which we work upon.

We can have multiple virtual machine and within one virtual machine we can have multiple context as well.
Image:


We can transfer information (object and value exchange) between two context of same virtual machine.

But we can not transfer information (object and value exchange) between two context of two different virtual machine.

Allowed:


Not Allowed: (No information exchange allowed between two context or different VM).


Part1:
Now Objc to Java Script communication happen with the following sequence:
(calling java script function from objective c)
  1. We create a Context. (until required one VM is created by default)
  2. We get our java script code from js file.
  3. Evaluate java script code. (this will return the value of any self executing function -- java script notation.)
  4. From context we get our JS value.(any JSfunction or JSObject).
  5. Call the JS function from Objc using java script core function calling mechanism.
  6. Get the return value from JS function as JSvalue.
Part2:
Now Java Script to Objc communication: (calling Objc method from Java Script)
  1. There are two possible way.
  • Blocks (Objc block can work as a medium to provide functionality of OBJC code to JS).
  • JSExport protocol. (A protocol will work as a class to JS code).
Blocks:
context[@"makeNSColor"] = ^(NSDictionary *rgb){
        float red = [rgb[@"red"] floatValue];
        float green = [rgb[@"green"] floatValue];
        float blue = [rgb[@"blue"] floatValue];
        float alpha = 1.0f;
        
        UIColor *colorReturn = [UIColor colorWithRed:red/255.0f green:green/255.0f blue:blue/255.0f alpha:alpha];
        return colorReturn;
    };

Here makeNSColor  will be directly available to java script code as i have added to context(global object).
can be directly called from java script.

var rgb = {
        red:255.0,
        green:67.0,
        blue:70.0
        };
var colorVal = makeNSColor(rgb);

JSExport Protocol:
JSExport protocol works just like normal protocol but provide easy access to Objc code from Java Script.
Sample:

#import <UIKit/UIKit.h>

#import <JavaScriptCore/JavaScriptCore.h>

@protocol MyButtonExports <JSExport>

@property (readwrite,nonatomic) NSString* name;
@property double top;
@property double left;
@property double bottom;
@property double right;

-(id)onClick:(JSValue*)handler;
+(double)makeMyPointWithX:(double)x;
@end

@interface MyButton : UIButton <MyButtonExports>

-(void)clickHappened:(id)args;
@end

Using this approach, property values will be used as a java script getter and setter, while instance method will be used with class instance object and class method will be accessed using class object contained within global context object.

Things to take care: Threading and Memory Management is trivial task in this as java script is a garbage collected language and Objc uses ARC.

Apple has also shared one video in WWDC2013 regarding this communication:
(You need to have Safari and developer account.)

My JSCore sample link: https://app.box.com/s/5d7lfqh7l9o8j23pgt57 (Old code, check new code)
(Note: Its quite unstructured yet, but working. Will update soon with a nice well behaved code.)

Online view: https://app.box.com/s/sgbg3xzrj2idtw5svw1g

(New Code Sample)
Updated Code (Much structured and understandable)
Link: https://app.box.com/s/trr1glmd0dfx9y5hoa4a 

A working well behaved code is available in github under my github repo.
Link: https://github.com/ashishnigam/Team_Dev_Work

(Code is available now, as promised)

Direct Code Link: https://github.com/ashishnigam/Team_Dev_Work/tree/master/iOS_Native/JScoreDemo

JS functions exposed to java script in my sample.

1: createButton();
2: makeNSColor();
3: alert("Happy");
4: button.onClick(callback) {};  
is the instance method exposed. used for binding call backs to JS button object.
5: var callback = function(args){
        alert(args);
        button.tintColor = colorVal;
    };
this the call back exposed which is called on button click.
6: Button.createButton({}); is the Class method exposed, used in "testGeometry.js" which can be tested by commenting JSCoreExport feature and thus commenting the "JSCoreFundamental" method call and uncommenting the "JSCoreExports" method call as below viewdidload call in ANViewController.
- (void)viewDidLoad
{
    [super viewDidLoad];
    [self JSCoreFundamental:nil];
    //  [self JSCoreExports:nil];   
}
7: button.removeButton();
Much more functionality is available, best understood with the help of updated code sample. Checkout from github and test on your own system. Let me know for any clarification.
In sample i have created colours in JS and button object with its click event binding callback function.
Overloaded JS alert function as titanium sdk did.
Changed the label text colour using JS code with its background colour.
The only thing you may need to do it shuffling of commented and uncommented code in viewdidload().

Feel free to ask any query or any suggestions are most welcome. 
This code structure and sample shared is just for conceptual understanding.

Appcelerator Titanium Module for iOS Using Hyperloop JS

Appcelerator Titanium Module for iOS Using Hyperloop JS 

Hyperloop JS provided a unique solution for Module development and good part is these modules are compatible with current Titanium SDK. So module build using hyperjs will work as a native module.

To use Hyperloop code in a Ti.Current SDK such as 3.x.x, you should follow these steps below. NOTE: this will only work for iOS since other platforms use V8 which won't be supported in Ti.Next.
First, create a module.
Image
Inside the newly created module directory, create a directory named js. This is where we'll place our Hyperloop HJS files.
Let's do something simple. Create a file in the js directory named app.hjs with the following code:
Hyperloop module directory structure after build, we just need .zip file to use in Titanium App as Module.

 Hyperloop module directory structure, These are required directories and files.Rest can be deleted from the normal module directory structure.


@import("Foundation");
@import("UIKit");

/*
 Utility.
 */
String.prototype.toUTF8 = function() {
    return NSString.stringWithUTF8String('' + this);
};

/** 
 * because Ti.Next and Ti.Current have different threading architectures,
 * you can use the module.dispatch async to bridge the differences when doing
 * UI work or anything that requires you to use the main UI thread.  If you're 
 * using Titanium APIs, this isn't necessary since those APIs always work on the
 * right thread. However, if you want to use native APIs directly, you must wrap
 * your calls in the dispatch async.  This method is safe to use on both
 * Ti.Next and Ti.Current.  On Ti.Next, this simply executes the function as-is
 * when called since Ti.Next is already on the UI thread.  However, in Ti.Current,
 * this will execute the function on the main UI thread.
 */
module.dispatch_async(function(){
    var win = UIApplication.sharedApplication().keyWindow,
        label = new UILabel();
    label.textColor = UIColor.darkTextColor();
    label.frame = CGRectMake(20, 20, 280, 230);
    label.font = UIFont.systemFontOfSize(24);
    label.textAlignment = NSTextAlignmentCenter;
    label.lineBreakMode = NSLineBreakByWordWrapping;
    label.numberOfLines = 0;
    label.text = 'Hello world'.toUTF8();
    win.addSubview(label);
});

exports.foo = function(){
    return 'bar';
};
NOTE: Hyperloop compiled Ti.Current modules will use it's own Objective-C source code as part of packaging. Any code located in your Classes directory will not be used or compiled. You can safely ignore code in this file.
Now, compile your module using Hyperloop. For example, if my module was created in my directory located at ~/Documents/Appcelerator_Studio_Workspace/hyperloop_test_module, the command would be:
hyperloop package module --platform=ios --src=~/Documents/Appcelerator_Studio_Workspace/hyperloop_test_module --dest=build
After running the command, you should have your module zip distribution in the build directory.
Example Command i used on my system:
hyperloop package module --platform=ios --src=/Users/ashish.nigam/Documents/Titanium_Studio_Workspace/hjsmodule2/ --dest=/Users/ashish.nigam/Documents/Titanium_Studio_Workspace/hjsmodule2/hyperloopbuild
terminal output:
[INFO]  Compiling 822 source files
[INFO]  Generated universal library file at /Users/ashish.nigam/Documents/Titanium_Studio_Workspace/hjsmodule2/hyperloopbuild/libhjsmodule2.a
[INFO]  Compiling 6 source files
[INFO]  Creating module zip distribution
[INFO]  Created module distribution: /Users/ashish.nigam/Documents/Titanium_Studio_Workspace/hjsmodule2/hyperloopbuild/com.mhjs.module-iphone-1.0.zip
Deploy this file into your app using normal iOS module deployment instructions.
To load your Hyperloop code, just require the module as normal, substituting the module id for theYOUR_MODULE_ID string below.
var keyWindow = Ti.UI.createWindow({backgroundColor:"white"});
keyWindow.open();
var module = require("YOUR_MODULE_ID");
alert(module.foo());
Issues listed in: https://github.com/appcelerator/hyperloop/wiki/Using-Hyperloop-code-in-Ti.Current-SDK
feel free to ask any query related to module development, either Hyperloop JS module or Native Module.

Appcelerator Titanium App using Hyperloop JS

Appcelerator Titanium App using Hyperloop JS

There are very simple steps to setup hyperloop in your system.

There are two way to setup hyperloop in your system.
1: User specific and local to user directory access.
2: Global and accessible to all user through environment variable.(will require admin access)
(Search for "Global and accessible to all user" to reach there.)

1: User specific:
1: Clone the hyperloop JS directory onto your system from link: https://github.com/ashishnigam/hyperloop
2: goto the cloned directory and go into the hyperloop bin directory.



3: use the hyperloop command and install any dependency which is missing and pointed by hyperloop.
Command Example:
./hyperloop compile --platform=ios --src="/Users/ashish.nigam/GitHub/Appcelerator/hyperloop/examples/ios/helloworld/app.hjs" --dest="/Users/ashish.nigam/GitHub/Appcelerator/hyperloop/examples/ios/helloworld /build"

4: It will ask you for number dependency like:
  • colors
  • underscore
  • uglify-js
  • node-appc
  • ejs
  • node-uuid
  • wrench
  • async
  • semver
  • byline
  • stream-buffers

5: you have to install them as well before you can run hyperloop compiler, which can be done using following command.

  1. sudo npm install colors
  2. sudo npm install underscore
  3. sudo npm install uglify-js
  4. sudo npm install node-appc
  5. sudo npm install ejs
  6. sudo npm install node-uuid
  7. sudo npm install wrench
  8. sudo npm install async
  9. sudo npm install semver
  10. sudo npm install byline
  11. sudo npm install stream-buffers

6: you can also make a piped call to execute one after another or write a script to make it automated.

7: Once installed then you can go to example directory to see the possible examples of hyperJS and test any for iOS or Windows environment.

Global and accessible to all user
1: Simple use the command in terminal and will install all the dependencies and setup hyperloop environment.
sudo npm install -g git://github.com/appcelerator/hyperloop.git

Then all set now you can use the below mentioned command.

Final Command to use for application build and testing:

hyperloop package --platform=ios --src=/Users/ashish.nigam/GitHub/Appcelerator/hyperloop/examples/ios/physics --dest=/Users/ashish.nigam/GitHub/Appcelerator/hyperloop/examples/ios/physics/build/physics --name=physics --appid=com.physics --launch --jsengine=jsc --clean --debug --hl-small 

It will create a build iOS project and launch the app in simulator.

In the Above command "/Users/ashish.nigam/GitHub/Appcelerator/hyperloop/examples/ios/physics" is the path of my hyperloop JS file.

You can find couple of example in the example directory with in cloned directory.


Sample app.hjs file code:

/**
 * simple example showing off the new iOS7 physics capabilities
 */
@import('Foundation');
@import('UIKit');
@class('DynamicBehaviorDelegate',NSObject,[],[
{
name: 'tapped',
returnType:'void',
arguments: [{name:'gesture',type:'UITapGestureRecognizer *'}],
action: tapped
}
]);
String.prototype.toUTF8 = function() {
return NSString.stringWithUTF8String('' + this);
};
var win = UIApplication.sharedApplication().keyWindow;
win.backgroundColor = UIColor.redColor();
var view = new UIView();
view.frame = win.frame;
win.addSubview(view);
var label = new UILabel();
label.textColor = UIColor.darkTextColor();
label.frame = CGRectMake(20, 20, 280, 50);
label.font = UIFont.systemFontOfSize(18);
label.textAlignment = NSTextAlignmentCenter;
label.text = 'Click to drop...'.toUTF8();
label.lineBreakMode = NSLineBreakByTruncatingTail;
label.numberOfLinesMode = 2;
view.addSubview(label);
var delegate = new DynamicBehaviorDelegate();
var gesture = UITapGestureRecognizer.alloc().initWithTarget(delegate,NSSelectorFromString('tapped:'));
view.addGestureRecognizer(gesture);
var animator = UIDynamicAnimator.alloc().initWithReferenceView(view);
var gravityBehavior = UIGravityBehavior.alloc().initWithItems(null);
var collisionBehavior = UICollisionBehavior.alloc().initWithItems(null);
collisionBehavior.translatesReferenceBoundsIntoBoundary = true;
var itemBehavior = UIDynamicItemBehavior.alloc().initWithItems(null);
itemBehavior.elasticity = 0.6;
itemBehavior.friction = 0.5;
itemBehavior.resistance = 0.5;
animator.addBehavior(gravityBehavior);
animator.addBehavior(collisionBehavior);
animator.addBehavior(itemBehavior);
function tapped(params) {
var num = Math.floor(Math.random()*10) % 10 + 1;
var filename = "m"+num;
var image = UIImage.imageNamed(filename);
var imageView = UIImageView.alloc().initWithImage(image);
view.addSubview(imageView);
var tappedPos = gesture.locationInView(params.gesture.view);
imageView.center = tappedPos;
gravityBehavior.addItem(imageView);
collisionBehavior.addItem(imageView);
itemBehavior.addItem(imageView);
if (label.alpha > 0) {
UIView.beginAnimations(null,null);
UIView.setAnimationDuration(2);
label.alpha = 0.0;
UIView.commitAnimations();
}
}


Hyperloop JS apps are much performance oriented than Titanium SDK App, but in current scenario you need to understand Native Language Concept to get benefits out of it.

Feel Free to ask any query related to Hyperloop JS and in case you find some bug then report in GitHub(https://github.com/appcelerator/hyperloop/issues).