Tuesday 24 June 2014

Java Reflections on inner classes

Java Reflections is another powerful feature of Java that enables you to inspect the contents of java classes in run time without even knowing the name of the class.

Consider this scenario that you have an access to java object and you want to read the following properties of the object:

1. Object's class name
2. Details of the fields in the class
3. Details of the methods present in classes and etc.

Java reflections allows you to perform the above mentioned activities with its powerful feature and you can find more details about it here.

Consider another scenario, that you have an access to the object that is an instance of inner class of another class. Now you want to perform the same activities that are listed above on the inner class.

In this blog, I am going to explain how to inspect the fields and properties of inner classes using Java reflections.

Say, you are having access to the object (innerObj), which is an instance of the inner class 'innerClass' (say, its enclosing class is com.test.outerClass').

Whenever you fetch the name of the object innerObj with below statement

                   innerObj.getClass().getName();

it will return the string value as 'com.test.outerClass$innerClass'

With this value as a reference - we can obtain the name of the outer class, as below:

                String parent = innerObj.getClass().getName().split("\\$")[0];

From then on, we can get the access to inner class details as below:

Class<?> enclosingClass = Class.forName(parent);
Object enclosingInstance = enclosingClass.newInstance();

Class<?> innerClass = Class.forName(myObj.getClass().getName());
Constructor<?> ctor = innerClass.getDeclaredConstructor(enclosingClass);
Object innerInstance = ctor.newInstance(enclosingInstance);

Field[] fields = innerClass.getDeclaredFields();

Now, we can perform various operations as detailed in the Java reflections on 'innerClass' and inspect the various attributes of inner classes.

Thursday 19 June 2014

Add javascript event handlers to frames and iframes of web page

Hi All,

Those who are familiar with javascript would know, how powerful are javascript event handlers and how it makes their life easier in web applications.

Javascript event handlers are inserted at document or at individual element level in web sites and they listen for the specific events and perform the required actions as defined by the developer.

You can find the definition about events and its various types here: http://www.w3schools.com/js/js_events.asp

Events can be inserted into web pages with help of below mentioned methods:

i) addEventListener (for firefox, chrome and IE 9+ browsers)
ii) attachEvent (for IE 5-8)

But, when we need to attach event handlers to elements present inside frames and iframes of web pages - we need to do some additional work. In this blog, I am going to explain how to achieve it.

Event handlers can be added into iframes as below:

var iframes = document.getElementsByTagName('iframe');
alert(iframes.length);

document.iframes[0].contentDocument.addEventListener('click',callback,false);
function callback(e){
alert(123);
}
For adding into Frames, you can use the below statement:

var frames = document.getElementsByTagName('frame');
alert(frames.length);

parent.frames[0].document.addEventListener('click',callback,false);
function callback(e){
alert(123);
}



Wednesday 18 June 2014

Eclipse Kepler - Network Connection - Socks Proxy Bypass Issue

In this post, I am going to describe about how to overcome one of the Eclipse Kepler issue that bogged me for few days before identifying it.

Before getting into issue, I would like to cover some basic information related to 'Network Connections' preferences of Eclipse.

Most of the Eclipse users would have set the proxy in the 'Network Connections' preference settings during their course of work. For long time, I had a question of what is its significance and what does the options 'native', 'direct' and 'manual' means.

As far as its significance is concerned, during plugin installation and updates - Eclipse would directly contact the internet and download the updates. If you are sitting behind proxy, then Eclipse would not be able to successfully connect to internet and would be hanging whenever we attempt to make the connection.

To address this, we are required to mention the proxy details in the 'Network Connections' preferences of Eclipse. Eclipse provides us with 3 options here:

a. Direct - Makes the connection directly without the aid of any proxies. If you are connecting to internet only through proxy, then this option would not help you and you need to change it to either native or manual.
b. Native - Makes the connection using the proxy set at the OS level. With this option, eclipse fetches the proxy details that you would have set from your browsers (Tools --> Intenet Option --> Connections --> LAN Settings) and uses it.
c. Manual - Makes the connection with user provided proxy details. As far as 'Manual' option is concerned, we can set the proxy value for the protocols 'http', 'https' and 'socks' in it.

Coming back to the issue that bogged me, whenever we set the proxy values for the above mentioned 3 protocols - looks like, Eclipse Kepler would ignore http and https protocol and tries to establish the internet connection only using 'socks' protocol.

If your update site does not support communication using 'socks' protocol, then Eclipse could not make connection and it would hang indefinitely.

Fortunately, people have found this bug and identified the work around for it. Work around is simple just clear the proxy details under 'socks' and proceed. It worked for me and helped me resolve the issue!!

You can refer this blog for more details: http://oakgreen.blogspot.jp/2011/10/eclipse-proxy-settings-bug-and.html 

Tuesday 17 June 2014

Firefox addon - Pass data between addon script and content script

In this blog, I am going to describe how to pass data between addon script and content script of Firefox addon.

Those familiar with Firefox addon would know about addon script and content script files.

Firefox sdk provides various apis to interact with local system attributes such as registry keys, clipboard content, context menu etc. And these apis could be accessed from a script called addon script (main.js under lib folder of addon).

But from this addon script, we cannot access any of the document object that contains the html details of web page that we load in browsers. To access document object, we need to use separate script called content script that could be accessed from data folder. These restrictions are introduced to ensure the security of user information.

This article from developer website provides detailed information about the features of addon script and content script.

As far as communication between addon script and content script, they have a feature called 'port', which enables the user to send and receive data between the scripts.

In this blog, I am explaining about how to send and receive the data using PageMod module. We can also send and receive information from other modules such as tabs and panel.

Have the below code in main.js file:

pageMod.PageMod({
  include: "*",
  contentScriptFile: data.url("textscript.js"),
  contentScriptWhen: "ready",
  onAttach: startListening
});

function startListening(worker) {
    worker.port.emit('check','test emit');
}

Here, we are attaching 'startListening' function with PageMod object and it emits a message 'test emit' with the user defined event 'check'.

And in contentscript, below code will capture the data emitted by addon script:

self.port.on('check', function(message) {
 console.log(message);
});

Similarly, you can emit the message from content script and can receive it in addon script. You can find those details here: https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts

Monday 16 June 2014

Install Mozilla Firefox addon programmatically

This blog summarizes the procedure to install Mozilla Firefox addon programmatically.

We do have a command '-install-global-extension' to install addons for the firefox versions that are earlier than ver 3.6. (Refer: https://support.mozilla.org/en-US/questions/729981)

For the latest firefox versions, Mozilla does not support the above mentioned command. Hence we need to install addons through some work arounds.

This blog details about how to install addons programmatically for latest versions of firefox, which do not support '-install-global-extension' command.

Usually, firefox addons are installed at the user level and not at the system level. In other words, if you install a firefox addon - it will be available only for the user who installed it. If another user logins to the same machine with his credentials, addon will not be available to him/her.

User can install the addon either by dragging and dropping the .xpi files into firefox browser or by placing the xpi file in the below location:

C:\Users\<User>\AppData\Roaming\Mozilla\Firefox\Profiles\<.default>\extensions

If user installs the addon by placing the .xpi file in the above location, firefox will prompt the user to install the addon at the next launch of firefox.

Some points to be noted here:

1. Usually 'AppData' folder will be a hidden folder. Hence we need to change the windows folder setting to display it.
2. '.default' folder will precede with some random text. For every user, this random text will change. Hence we need to handle this programmatically.
3. We need to ensure that .xpi file is named with the same value of '<em:id>' parameter as defined in the install.rtf file.

So, to install addon programmatically, we just need to copy and paste our .xpi file into the location mentioned above. Below code mentions how to find the .default file using regular expression. After finding the location, you are just required to copy and paste the xpi file into the identified location:


import java.io.File;
import java.io.FileFilter;
import java.io.IOException;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.RegexFileFilter;

public class New {
                static String dataFolder = System.getProperty("user.home") + "\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles";
               
  public static void main(String[] args) {
                 File dir = new File(dataFolder);
                 FileFilter fileFilter = new RegexFileFilter(".*default");
                 File[] files = dir.listFiles(fileFilter);
                 File extDir = new File(files[i]+"\\extensions")
}
}

Please let me know if you have any queries with respect to above explanation.