Categories

Introduction to OSGI Declarative Services using Apache Felix

I took a look at OSGI DS and was curios about how to create a hello world bundle to run on Apache Felix. After a little search i decided that it would be a good opportunity to learn basics of maven 2. I checked out one of the projects at apache incubator svn and seeing pom.xml files I had no idea what they were used for. So for the sake of simplicity I will use Pax Construct and Pax Runner for building and running my bundle.

You should install the following software to continue this tutorial

Lets start by creating our project by typing

>mvn org.ops4j:maven-pax-plugin:create-project -DgroupId=org.example -DartifactId=ds_helloworld -Dversion=1.0-SNAPSHOT

It creates a folder named ds_helloworld and some sub directories like ds_helloworld/provisions and ds_helloworld/poms each containing a pom.xml. For what purpose these directories are used are explained here. Since we are only interested in making a hello world bundle we simply do not care.

Lets import the resulting maven projects into eclipse and see what they look like:

eclipse_pax_fresh_import

Lets move on and add a bundle to our project.

>cd ds_helloworld

>mvn org.ops4j:maven-pax-plugin:create-bundle -Dpackage=org.example.ds_helloworld -Dname=ds_helloworld -Dinternals=false -Dactivator=false
-Dinterface=false

>cd org.example.ds_helloworld

>mvn eclipse:eclipse (this will generate eclipse specific project files from pom.xml)

this will create a org.example.ds_helloworld bundle, again import it into workspace.

add org.apache.felix.scr and org.apache.felix.scr.annotations to dependencies of pom.xml of the newly created bundle

also add maven-scr-plugin to the plugins and define a goal like this:

<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<version>1.4.4</version>
<executions>
<execution>
<id>generate-scr-descriptions</id>
<goals>
<goal>scr</goal>
</goals>
</execution>
</executions>
</plugin>

then go to the projects pom.xml file (/ds_helloworld/pom.xml)

and add following plugin:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>

Now we need to add our source files to the org.example.ds_helloworld bundle. There are three .java files to add

org.example.ds_helloworld.HelloWorldService.java : This will define the interface that service implementation should implement. Each service is defined through an interface.

1
2
3
4
5
6
package org.example.ds_helloworld;

public interface HelloWorldService {

public String helloWorld();
}

org.example.ds_helloworld.HelloWorldServiceImp.java : This is the component that will provide implementation for our service. Only components can provide or consume services. Every component has a default constructor(public, takes no arguments).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package org.example.ds_helloworld;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;

//This is a component so it can provide or consume services
@Component
// This component is providing the service that is defined through interface
// org.example.ds_helloworld.HelloWorldService
@Service
public class HelloWorldServiceImp implements HelloWorldService {

public String helloWorld() {
return "helloWorld";
}

}

org.example.ds_helloworld.ServiceConsumer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package org.example.ds_helloworld;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.osgi.service.component.ComponentContext;

//This is a component and it consumes a service
@Component
public class ServiceConsumer {

// Service reference is preserved in a field
@Reference
private HelloWorldService service;

// When needs of the component is statisfied the component will be activated
// by calling this function
@Activate
public void activate(ComponentContext cc) {
System.out.println(this.service.helloWorld());
}

// When a HelloWorldService service is discovered it will be given to this
// component through this method
public void bindService(HelloWorldService service) {
this.service = service;
}

}

maven-scr-plugin is smart enough to generate serviceComponents.xml file and it is attached to the resulting jar file.

<?xml version=”1.0″ encoding=”UTF-8″?>
<components xmlns:scr=”http://www.osgi.org/xmlns/scr/v1.1.0″>
<scr:component enabled=”true” name=”org.example.ds_helloworld.HelloWorldServiceImp”>
<implementation class=”org.example.ds_helloworld.HelloWorldServiceImp”/>
<service servicefactory=”false”>
<provide interface=”org.example.ds_helloworld.HelloWorldService”/>
</service>
<property name=”service.pid” value=”org.example.ds_helloworld.HelloWorldServiceImp”/>
</scr:component>
<scr:component enabled=”true” name=”org.example.ds_helloworld.ServiceConsumer” activate=”activate”>
<implementation class=”org.example.ds_helloworld.ServiceConsumer”/>
<property name=”service.pid” value=”org.example.ds_helloworld.ServiceConsumer”/>
<reference name=”service” interface=”org.example.ds_helloworld.HelloWorldService” cardinality=”1..1″ policy=”static” bind=”bindService” unbind=”unbindService”/>
</scr:component>
</components>

then from the command line go to the root directory of the project and type:

>mvn clean install

after some console output eventually you will see something like that:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] org.example.ds_helloworld (OSGi project) .............. SUCCESS [5.407s]
[INFO] ds_helloworld - plugin configuration .................. SUCCESS [0.032s]
[INFO] ds_helloworld - wrapper instructions .................. SUCCESS [0.095s]
[INFO] ds_helloworld - bundle instructions ................... SUCCESS [0.026s]
[INFO] ds_helloworld - imported bundles ...................... SUCCESS [0.025s]
[INFO] org.example.ds_helloworld ............................. SUCCESS [5.287s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 14 seconds
[INFO] Finished at: Tue Aug 10 20:43:41 EEST 2010
[INFO] Final Memory: 22M/53M
[INFO] ------------------------------------------------------------------------

goto ds_helloworld/provision/pom.xml and add dependency (this is a dependency for Apache Felix SCR but not required in the org.example.sd_helloworld bundle so we put it into provisions module. This will be used when PAX runner constructs our launcher for felix platform).

<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.configadmin</artifactId>
<version>1.2.4</version>
<type>bundle</type>
<scope>compile</scope>
</dependency>

Now we can create our launcher :

from command line go to the root of the project and type:

>mvn pax:provision

soon Apace Felix will start and output something like that:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
__________                 __________
\______   \_____  ___  ___ \______   \__ __  ____   ____   ___________
|     ___/\__  \ \  \/  /  |       _/  |  \/    \ /    \_/ __ \_  __ \
|    |     / __ \_>    <   |    |   \  |  /   |  \   |  \  ___/|  | \/
|____|    (____  /__/\_ \  |____|_  /____/|___|  /___|  /\___  >__|
\/      \/         \/           \/     \/     \/

Pax Runner (1.4.0) from OPS4J - <a href="http://www.ops4j.org">http://www.ops4j.org</a>
----------------------------------------------------

> Using config [classpath:META-INF/runner.properties]
> Using only arguments from command line
> Scan bundles from [C:\Users\Cihan\Documents\Blog\OSGI DS Intro\ds_helloworld\runner\deploy-pom.xml]
> Scan bundles from [scan-pom:file:/C:/Users/Cihan/Documents/Blog/OSGI DS Intro/ds_helloworld/runner/deploy-pom.xml]
> Provision bundle [mvn:org.apache.felix/org.apache.felix.configadmin/1.2.4, at default start level, bundle will be started, bundle will be loaded from the cache]
> Provision bundle [mvn:org.example.ds_helloworld/org.example.ds_helloworld/1.0-SNAPSHOT, at default start level, bundle will be started, bundle will be loaded from the cache]
> Provision bundle [mvn:org.apache.felix/org.apache.felix.scr/1.4.0, at default start level, bundle will be started, bundle will be loaded from the cache]
> Preparing framework [Felix 2.0.2]
> Downloading bundles...
> mvn:org.apache.felix/org.apache.felix.configadmin/1.2.4 : 85016 bytes @ [ 14169kBps ]
> mvn:org.example.ds_helloworld/org.example.ds_helloworld/1.0-SNAPSHOT : 5615 bytes @ [ 5615kBps ]
> mvn:org.apache.felix/org.apache.felix.scr/1.4.0 : 185418 bytes @ [ 23177kBps ]
> Using execution environment [J2SE-1.6]
> Runner has successfully finished his job!

Welcome to Felix
================

> helloWorld

This shows us our HelloWorldService is created bound to the component that uses it and when this component activated it printed out the text.

-> shutdown

and stop Felix.

To start this launcher and debug it we need to define a run configuration in eclipse.

Run –> Run Configurations  right click on OSGI Framework select new. A window will appear

goto Pax Runner tab and click Add POM and choose deploy-pom.xml from /ds_helloworld/runner

goto  Bundles tab and choose Felix 2.0.1 via Pax runner as Framework and uncheck all bundles

Apply and Run then you will see helloWorld on Eclipse Console Tab.

Thats all for now next time we will be writing a Component Factory to create configured services at runtime.

Character Comparison Problem – Python

I realized in some part of a program of mine following statements print False:

1
2
3
4
5
#coding = utf-8
turkishConsonants = ['b', 'c', 'ç', 'd','f','g','ğ','h','j','k','l','m',
    'n','p','r','s','ş','t','v','y','z']
word = "ağla"
print word[-3] in turkishConsonants

The reason for this was the letter ‘ğ’ is stored as two array elements and word[-3] returns only half of it.
Proper way to make comparison is decoding the string before indexing. So fixed version is

1
2
3
4
5
6
7
8
9
10
11
12
#coding = utf-8
def contains(charArray,letter):
    for c in charArray:
        if(letter == c.decode('utf_8')):
            return True
    return False

turkishConsonants = ['b', 'c', 'ç', 'd','f','g','ğ','h','j','k','l','m',
    'n','p','r','s','ş','t','v','y','z']
word = "ağla"
letter = word.decode('utf_8')[-3]
print contains(turkishConsonants,letter)

The situation is similar while calling len() on a string, make sure to decode it first in such sensitive cases.

Custom Java Events

To create custom Java events we need basicly three classes:

  1. The event class which will be fired
  2. An interface which indicating responsibility of event listeners of this event
  3. The class which fires the Java events

When these classes are prepared, other classes can subscribe to events  by providing their event listener.

An event class must extend java.util.EventObject class. Below you can see an event class example which I used in an application that exchanges messages over TCP/IP sockets.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package prototype.communication.events;

import java.util.EventObject;

/**
 *
 * @author Server
 */

public class CommunicationEvent extends EventObject {


    private int eventType;
    public static final int ConnectionLost = 0;
    public static final int MessageReceived = 1;
    public static final int ConnectionEstablished = 2;
    public static final int ServerSocketFailed = 3;

    public CommunicationEvent(Object source, int eventType) {
        super(source);
        this.eventType = eventType;
    }

    public int getEventType() {
        return eventType;
    }
}

Coding the interface is usually trivial, note that this interface must extend java.util.EventListener interface which is a tagging interface.

1
2
3
4
5
6
7
8
9
10
11
package prototype.communication.events;

import java.util.EventListener;

/**
 *
 * @author Server
 */

public interface CommunicationEventListener extends EventListener{
    public void communicationEventReceived(CommunicationEvent event);
}

The third class which will fire should provide following functions to enable other class to subscribe to events:

1
2
public synchronized void addEventListener(CommunicationEventListener l);
public synchronized void removeEventListener(CommunicationEventListener l);

Following field can be used to store event listeners:

1
private List eventListeners;

Then implementation of add and remove functions follows intuitively:

1
2
3
4
5
6
7
public synchronized void addEventListener(CommunicationEventListener l) {
    eventListeners.add(l);
}

public synchronized void removeEventListener(CommunicationEventListener l) {
    eventListeners.remove(l);
}

Whenever this class needs to fire an event it will iterate over listeners and will call communicationEventReceived method of EventListener interface. You can see an example function that fires an event:

1
2
3
4
5
6
7
private synchronized void fireCommunicationEvent(int eventType) {
    CommunicationEvent event = new CommunicationEvent(this, eventType);
    Iterator listeners = eventListeners.iterator();
    while (listeners.hasNext()) {
        listeners.next().communicationEventReceived(event);
    }
}

Basketball Game: Robot (www.onlinegames.com/basketball/)

I have coded another helper program to a popular game using Robot class of Java. In this game, players are trying to score baskets in a 2d pitch by shooting the ball random positions to a basket of which position remains unchanged. The players only decide highest point of the path of the ball. By observation, it can be noticed that path of the ball is a parabola. Therefore the problem can be reduced to finding highest point of a parabolum of which two points (position of basket and initial position of ball) are known. Of course, countless different parabola can pass through two points. So setting height of highest point is also needed. Also note that basket and ball are on the separate arms of parabola. Consequently, we have the following known values

Coordinates of basket: Px,Py

Coordinates of ball: Tx,Ty

Height of highest point: H

Parabola equation: y = a(x-X)^2 + H

We need to find axis of highest point: X

Since we know that basket and position are on the parabola, we have following two equations:

1: Py=a(Px-X)^2 + H

2: Ty=a(Tx-X)^2 + H

Find value of a from 1 and 2, these values will also be equal:

Py–H / (Px-X)^2 = Ty-H / (Tx-X)^2

Py – H / Ty – H = (Px – X)^2 / (Tx – X)^2

(Py – H / Ty – H)^1/2 = |Px – X| / |Tx – X|

You can see that Px < X < Tx by looking at positions of basket and ball in the game.

(Py – H / Ty – H)^1/2 = (X – Px) / (Tx – X)

Tx * (Py – H / Ty – H)^1/2 – X * (Py – H / Ty – H)^1/2 = X – PX

Tx * (Py – H / Ty – H)^1/2 + Px = X + X * (Py – H / Ty – H)^1/2

X = (Tx * (Py – H / Ty – H)^1/2 + Px) / (1 + (Py – H / Ty – H)^1/2)

So we have axis of the highest point expressed in terms of known values.

The Java program below helps you to play the game using the calculations above. Things you have to do: Start program and open the game. Put your mouse to the lowest point of the ball. Then wait a moment for program to calculate and move your mouse to shooting position. Click your mouse to shoot. When new ball appears put your mouse to the lowest point of the ball and make the loop continue.

N.B. Coordinates of basket can be different for each screen. You can update the values in your program, since the program prints positions of the mouse to standard output. Put your mouse in the middle of the basket to see its coordinates in standard output. Then update basketPositionX and basketPositionY values in the code.

N.B. Since the movement of the ball is not a perfect parabola, the calculations fail during long shots. There is a variable called optCons to regulate calculations for long shots. So if the program fails in your computer, try increasing and decreasing this variable by small amounts (like 0.01 or 0.005).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import java.awt.AWTException;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Robot;

/**
 *
 * @author Server
 */

public class Main {

    /* screen dependent variables */
        public static final double basketPositionX = 143;
        public static final double basketPositionY = 336;
        public static final double optCons = 0.03;
    /* end of screen dependent variables */

    public static final double shootHeightY = -44;

    public static void main(String[] args) throws AWTException, InterruptedException {
        Robot robot = new Robot();
        Point lastLocation = MouseInfo.getPointerInfo().getLocation();
        Point location = MouseInfo.getPointerInfo().getLocation();
        int counter = 0;

        while (true) {

            Thread.sleep(100);
            location = MouseInfo.getPointerInfo().getLocation();

            if (lastLocation.x != location.x || lastLocation.y != location.y) {
                lastLocation = location;
                counter = 0;
            } else {
                counter++;
                if (counter == 5) {
                    Point calculatedLocation = calculate(location);
                    robot.mouseMove(calculatedLocation.x, calculatedLocation.y);
                    System.out.println("Coordinate Get:" + location.x + "," + location.y);
                    counter = 0;
                }
            }
        }

    }

    private static Point calculate(Point location) {
        double x1 = location.x;
        double y1 = -location.y ;
        double h = shootHeightY;

        double opt;

        double a = Math.sqrt(basketPositionY + shootHeightY);
        double b = Math.sqrt(Math.abs( -y1 + h));

        double r = (x1 * a + basketPositionX * b) / (a + b);
        System.out.println(r);
        opt = (x1-r) * optCons;
        r += opt;

        return new Point((int) r, (int) -h);
    }
}

DL – Safe SWRL Rules on OWL DL Ontologies with Pellet

Here is a simple example to understand the meaning of DL Safety.

In a DL Safe rule execution, only explicitly named individuals are bound to the variables in the rule.

Lets say we have a transitive object property named ancestorOf.

Can we simulate this transitivity using a DL-Safe SWRL rule rather than defining the ancestorOf property as transitive?

At the first glance it seems possible since transitivity is simply: transitive_property(?X, ?Y), transitive_property(?Y, ?Z) –> transitive_property(?X, ?Z)

To illustrate more clearly lets create the following ontology. I used Protégé 4.0 and Pellet Reasoner Plug-in 1.0 for Protégé.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
test:AncestorOfOlympian
a       owl:Class ;
owl:equivalentClass
[ a       owl:Restriction ;
owl:onProperty test:ancestorOf ;
owl:someValuesFrom test:Olympian
] .test:Olympian
a       owl:Class .test:AncestorOfChronos
a       owl:Class ;
owl:equivalentClass
[ a       owl:Restriction ;
owl:hasValue test:Chronos ;
owl:onProperty test:ancestorOf
] .
a       owl:Ontology .test:ancestorOf
a       owl:TransitiveProperty , owl:ObjectProperty .test:Uranus
a       owl:Thing ;
test:ancestorOf test:Chronos .

test:Chronos
a       test:AncestorOfOlympian , owl:Thing .

As expected the inferred class hierarchy is :

Now remove the transitive characteristic of ancestorOf. And Add the rule shown below.

Now classify the ontology again and look at the inferred class hierarchy.

In the first case the inference mechanism determines that AncestorOfOlympian is a super class of AncestorOfChronos.

Because Chronos is already an ancestor of some unknown individual of type Olympian and ancestorOf is transitive, then ancestor of Chronos is already an ancestor of Olympian.

Also Uranus is listed as an instance of AncestorOfOlympian.

In the second case , since there is no individual of Olympian is present, the inferences mentioned above can not be done.

Note that if we add an instance of Olympian (e.g. Zeus) and make Chronos ancestor of Zeus then Uranus is listed as an instance of AncestorOfOlympian however the inferred class hierarchy remains unchanged.

P.S. This example is a simplified version of weblog entry of Bijan Parsia.

Setting Java Character Encoding

When operations on different character sets need to be done in Java, we need to initialize JVM with required options.

First lets have a look at basics of java character encodings.

  • Internally the JVM always operates with Unicode.
  • Data transferred in or out of the JVM is converted to a format specified in the file.encoding property of the JVM
    • Data transferred in the JVM is converted from the format specified at file.encoding to Unicode
    • Data transferred out of the JVM is converted from Unicode to the format specified at file.encoding
  • When data need to be processed from Java Program other than the format specified in file.encoding the following classes which allows usage of encodings that takes precedence over the default one can be used
    • java.io.InputStreamReader
    • java.io.FileReader
    • java.io.OutputStreamReader
    • java.io.FileWriter

Default character set of the JVM varies across platform. Following piece of code shows how to get default character set of JVM.

1
2
3
4
5
6
System.out.println(System.getProperty("file.encoding"));
System.out.println(
new java.io.OutputStreamWriter(
new java.io.ByteArrayOutputStream()).getEncoding()
);
System.out.println(java.nio.charset.Charset.defaultCharset().name());

Output on linux

1
2
3
ANSI_X3.4-1968
ASCII
US-ASCII

This property can be set using System.setProperty(“file.encoding”, {desired encoding});

However doing this did not help me much since, the core Java libraries does not use this mechanism to determine default encoding.

My problem was to read from an java.net.URLConnection so i used the following piece of code:

1
2
URL url = new URL(urlStr);
URLConnection connection = url.openConnection();
1
2
3
//Create InputStreamReader with UTF8 Charset
BufferedReader in = new BufferedReader(new InputStreamReader(connection
.getInputStream(), Charset.forName("UTF-8")));
1
2
 // If we need to read this stream into a string we need to create the string like:
String str = new String(bytes, Charset.forName("UTF-8"));

BlazeDS - Remote Object Service Tutorial

Remoting Object Service of BlazeDS , is used for making remote procedure calls from Flex applications to Java Server.

Having BlazeDS deployed on an application server (Tomcat is used here) , following steps shows the server and client side coding for a simple scenario where a flex application is used to display instances of  Person and Car classes send by Java Web Application as a result of remote procedure call.

Server Side Coding and Configuration

Net Beans is used for creating Java Web Application. Here are the classes of the application

Class definition of the Java class of which methods will be invoked from Flex application must conform following specification :

  • Access modifier of the class must be “public”
  • Access modifier of the methods to be invoked must be “public”

Here is my deneme.Manager class that will send some Person instances to Flex application :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package deneme;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Cihan
 */

public class Manager {

    public List<Person> persons = new ArrayList<Person>();

    public Manager() {
        //We have no persistence
        //So create some dummy data to send
        Person person1 = new Person();
        Person person2 = new Person();
        Car car1 = new Car();
        Car car2 = new Car();

        person1.setName("Person1");
        person2.setName("Person2");

        car1.setModel("Model1");
        car2.setModel("Model2");

        person1.addCar(car1);
        person2.addCar(car2);

        persons.add(person1);
        persons.add(person2);

    }

    //The method that will be invoked
    public List<Person> getPersons() {
        return persons;
    }
}

There are two things left to do on the server side :

  • Copy the folders under directory {Project_Root}/build/web/WEB-INF/classes to {BlazeDS_Root}/WEB-INF/classes
  • Add the following XML element as a child of {BlazeDS_Root}/WEB-INF/flex/remoting-config.xml ‘s “service“ element
1
2
3
4
5
6
7
8
9
<destination id="PersonManager">
        <properties>
            <source>deneme.Manager</source>
            <scope>application</scope>
        </properties>
       
        <adapter ref="java-object" >
        </adapter>
    </destination>

Client Side Coding

I used a flex project with J2EE as server technology and LiveCycle Data Services as remote object access service with following server configuration :

The only thing we need to make remote procedure call is to create a mx.rpc.remoting.RemoteObject in ActionScript and call getPersons() method.

The call is asynchronous and server will respond this call in one of following forms (How to handle these events are shown in the code) :

  • An mx.rpc.events.ResultEvent of which result field  contains the return value of the invoked method
  • An mx.rpc.events.FaultEvent if any error occurs during remote procedure call

Here is the .mxml and .as files of the Flex application:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="{init()}">
    <mx:Script>
        <![CDATA[
            import deneme.Car;
            import mx.events.ListEvent;
            import mx.events.DataGridEvent;
            import mx.controls.Alert;
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;
            import mx.rpc.remoting.RemoteObject;
            import mx.collections.ArrayCollection;
            import deneme.Person;
           
           
            private var manager:RemoteObject;
           
            [Bindable]
            private var persons:ArrayCollection;
           
            [Bindable]
            private var selectedPerson:Person;
           
            [Bindable]
            private var selectedCars:ArrayCollection;
           
           
           
            private function init():void{
                //Argument given to the constructor should be same as the 'id' of the destination  
                manager = new RemoteObject("PersonManager");
               
                //Add EventListener for result case
                manager.addEventListener(ResultEvent.RESULT, onGetPersonsResult);
                //Add EventListener for fault case
                manager.addEventListener(FaultEvent.FAULT, onGetPersonsFault);
                //Call function using the same name as the method of Java class
                manager.getPersons();
            }
           
            private function onGetPersonsResult(event:ResultEvent):void{
                //Remove EventListeners
                manager.removeEventListener(ResultEvent.RESULT, onGetPersonsResult);
                manager.removeEventListener(FaultEvent.FAULT, onGetPersonsFault);
               
                //Store result in a variable
                persons = event.result as ArrayCollection;
               
            }
           
            private function onGetPersonsFault(event:FaultEvent):void{
                //Remove EventListeners
                manager.removeEventListener(ResultEvent.RESULT, onGetPersonsResult);
                manager.removeEventListener(FaultEvent.FAULT, onGetPersonsFault);
               
                //Display fault message in a popup window
                Alert.show(event.fault.message);
            }
           
            private function onChange(event:Event):void{
                selectedPerson = person_dg.selectedItem as Person;
                selectedCars = (person_dg.selectedItem as Person).cars;
           
            }  
           
        ]]>
    </mx:Script>
    <mx:DataGrid id="person_dg" x="10" y="10" dataProvider="{persons}" change="{onChange(event)}">
        <mx:columns>
            <mx:DataGridColumn headerText="Name" dataField="name"/>
        </mx:columns>
    </mx:DataGrid>
    <mx:DataGrid  x="120" y="10" dataProvider="{selectedCars}" >
        <mx:columns>
            <mx:DataGridColumn headerText="Model" dataField="model" />
        </mx:columns>
    </mx:DataGrid>
   
</mx:Application>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package deneme
{
    //Remote Class alias should be the fully qualified name of the Remote Class
    [RemoteClass(alias="deneme.Car") ]
   
    public class Car
    {
       
        //fields should be declared as "public" with same name and type
        public var model:String;
       
        //Default constructor should be declared
        public function Car()
        {
        }

    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package deneme
{
    import mx.collections.ArrayCollection;
   
    [RemoteClass(alias="deneme.Person") ]
    public class Person
    {
       
        public var name:String;
        [Bindable]
        public var cars:ArrayCollection;
       
       
        public function Person()
        {
        }
       
       
       

    }
}

Here is the .java files for Person and Car

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package deneme;

public class Car {
    public String model;

    public Car() {
    }

    public void setModel(String model) {
        this.model = model;
    }

    public String getModel() {
        return model;
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package deneme;

import java.util.ArrayList;
import java.util.List;

public class Person {

    public String name;
    public List<Car> cars;

    public Person() {
        cars= new ArrayList<Car>();
    }

    public void setCars(List<Car> cars) {
        this.cars = cars;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Car> getCars() {
        return cars;
    }

    public String getName() {
        return name;
    }

    public void addCar(Car car) {
        cars.add(car);
    }
}

Farmville: Clicking Robot

Too many clicks are needed while playing games like farmville. To this automatically, firstly I used a tool named xdotools which generates false keyboard and mouse input. But, since xdotools only supports X11, I switched to Java to have a platform independent program.

java.awt.Robot class can be used to generate false input in Java. You can easily imitate effects of moving mouse, rotating mouse wheel, pressing keyboard buttons or mouse buttons by utilizing this class.

Below, you can see a very simple Java program that moves mouse and clicks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.InputEvent;

public class Main {

        public static void main(String[] args) throws AWTException {
                Robot robot = new Robot();

                robot.mouseMove(100, 100); //move mouse
                robot.mousePress(InputEvent.BUTTON1_MASK); //press left button of mouse
                robot.mouseRelease(InputEvent.BUTTON1_MASK); //release left button
        }
}
Here is the full code for a farm of one of my friends.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package farmville;

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.InputEvent;

/**
 *
 * @author Server
 */

public class Main {

        /**
         * @param args the command line arguments (not used)
         * @throws AWTException
         * @throws InterruptedException
         */

        public static void main(String[] args) throws AWTException, InterruptedException {
                Robot rbt = new Robot();

                int startX = 718;
                int startY = 706;
                int startPosX = 718;
                int startPosY = 706;
                Thread.sleep(3500); //sleep while I switch to facebook and make the window fulscreen
                rbt.mouseMove(startPosX, startPosY); // start at x=718 and y=706
                int x = 25;
                int y = 12;
                for (int j = 1; j < 23; j++) {
                        for (int i = 1; i < 22; i++) {
                                rbt.mousePress(InputEvent.BUTTON1_MASK);
                                rbt.mouseRelease(InputEvent.BUTTON1_MASK);
                                rbt.mouseMove(startPosX += x, startPosY -= y);
                        }
                        rbt.mousePress(InputEvent.BUTTON1_MASK);
                        rbt.mouseRelease(InputEvent.BUTTON1_MASK);
                        startX -= x;
                        startY -= y;
                        startPosX = startX;
                        startPosY = startY;
                        rbt.mouseMove(startPosX, startPosY);
                }
        }
}

Dealing with lots of paranthesis…

While dealing with lambda calculus expression that I mentioned in my previos post, from time to time many paranthesis appears. Exampli gratia: While trying to SKI equivalent of

λx.λy.+ x y,

intermediate expressions like

S (S (K S) (S (K (S (K +))) (S (λx K) (λx x)))) (λx I)

can be encountered. While dealing with such expression text editor of KDE named Kate may help you. Use highlighting support of Kate for Scheme language which colors nested paranthesis with seven different colors. To enable this feature select Tools->Highlighting->Scripts->Scheme from menu of Kate. The same effect can also be achieved by changing extension of the file you are working on to “scm”, “scheme”, “guile” or “ss”.

You can see calculation of SKI equivalent of λx.λy.+ x y with colored paranthesis

Finding SKI Equivalents of λ-Calculus Expressions

Define S, K and I as

S x y z = x z (y z)

K x y = x

I x = x

Apply following transformations to lambda calculus expression until the expression becomes free of lambda abstractions and variables.

1) λx.e1 e2 => S (λx e1) (λx e2)

2) λx.x => I

3) λx.c => K c [Here, c should not contain any free variable x.]

E.g.:

Lets find SKI equivalent of λx.+ x x

Since function application is left-associative in lambda calculus

λx.+ x x = (λx(+x) x)

Apply transformation 1:

(S (λx + x) (λx x))

Apply transformation 1, again:

(S (S (λx +) (λx x)) (λx x))

Appyle transformation 3,2 and 2 again:

(S (S (K +) I) I)

We are done, since we have a variable and lambda abstraction free expression. Now we can check our result by applying a number.

For example, apply 3:

(S (S (K +) I) I) 3 [Use definition of combinators to evaluate this expression. We began with S x y z = x z (y z)]

(S (K +) I 3) (I 3)

(K + 3) (I 3) (I 3)

+ 3 3

6