Realizing an extension

Index


Introduction

Here we show how to realize an extension for Semantic Turkey.
First, the document will guide the developer step-by-step on how to configure the development environment (system and development tools) in order to achieve this goal. Then, a simple extension will be realized to provide a lively example for the developer.

Back to the Index

From the beginning

As a Semantic Turkey's aspiring developer, you should have already read some documentation about the generic information of the system, and an overview of its architecture, in particular about the “extension points”. If not, please take a look at the extension development page.

The first thing you have to do is download the source code of Semantic Turkey from google code. Follow the “GUI and IDE access” instructions there to discover how you can download the project using “subversion”.

As usual in subversioning, there could be some official code release (associated to a given version of the tool), these are represented as "tagged" versions in SVN (this page allows you to browse different tagged versions of Semantic Turkley code), while the main trunk always contains the last nightly build. You can decide yourself if it is better to develop your extension for an existing official version or to get the last build and make your extension compatible with it. If in doubt, ask the ST developers (the semantic cooks) when the last build will become a new official release.

After completing the download, annotate somewhere your tagged version or, in case of a nightly build from the main trunk, look for the revision number of the source code (if you have used the command line you'll see that number prompted on it).It is important to remember which ST revision you are working on, so you can guarantee that your extension will be compatible until that revision.

In the downloaded folder you can find the following sub-folders:

The purpose of the first three folders is two-fold: understand how ST works, and compile the last version of ST.

By now, you need to know how to work using Maven.
If you already know and are proficient with Maven, you can skip the next steps, otherwise...don''t worry! Just follow our instructions and you will be able to work on your extension in just 15 minutes.

Back to the Index


Maven

<Maven, a Yiddish word meaning accumulator of knowledge, was originally started as an attempt to simplify the build processes in the Jakarta Turbine project. There were several projects each with their own Ant build files that were all slightly different and JARs were checked into CVS. We wanted a standard way to build the projects, a clear definition of what the project consisted of, an easy way to publish project information and a way to share JARs across several projects. The result is a tool that can now be used for building and managing any Java-based project. We hope that we have created something that will make the day-to-day work of Java developers easier and generally help with the comprehension of any Java-based project>

First, download Maven and follow the installation instructions on that website. To make it short, you must put the unzipped folder where you want to install Maven and set some environment variables.
The setting-up of this last step need to be permanent. To do so under Linux you have to modify the file “.bashrc” in your home directory inserting at the end the instructions “export variable_name=new_value” for every variable, otherwise under Windows you have to “right click on Computer->click on Properties->Advanced System Settings->Advanced->Environment Variables” and modify the values or add new variables as needed.

Also Maven works with Java, so it is necessary to have a JDK on your own system (but we hope that it is already the case because you are going to work with a Java project).

From now on, when we say: "install <project-name> in Maven", we mean "build that project and deploy its jar inside Maven local repository". The local repository is a sort of local mirror of libraries, which are accessed by your Maven projects to materialize jars specified in library dependencies. More information again in the Maven site.

This guide shows how to invoke some Maven goals, but the full list can be obtained from the Maven website.

Note that you can run maven goals from the command line, or use available plugins for your IDE which may support you in using Maven through user friendly interfaces. The how-to-build-semantic-turkey guide provides useful insights for using the M2Eclipse plugin inside the Eclipse IDE.

A general advice on third party libraries you need to use in your extension: these may have been already included in the Maven Central repository, or may be provided by third party Maven repositories (in this case the vendor should report the site of their Maven repository so that you can update your POM accordingly) or, as a last choice, you need to provide information for installing it. The Maven goal for installing a local copy of a 3rd party JAR into the local repository can be invoke by typing this on the commad line:

mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> -DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>

If the library has no pom where you can find the groupid, artifactid, version, then you can choose them by your own.
Pay attention that the mvn install command has spaces between the symbol '-' and the previous word and no spaces in the assignments with '=' . Otherwise the command will have a wrong syntax!

Back to the Index


Building ST

You can find ST building instructions and replies to frequent questions in the how-to-build-semantic-turkey guide.

Note that the ant build file does not Maven-compiles the SemanticTurkeySE project, instead it plainly produces a jar from it, so, for the purposes of extension development, it's better to build in Maven even this project.

type (from the SemanticTurkeySE project folder) on the command line:

mvn clean install

to build the SE project and install it in Maven (that is, the jar is added to your Maven local repository).

It can be useful for you to have a list of frequent Maven goals (and combination of them) you will use.

After a build, the resulting files are also deployed in project's target folder.

Now it's time to set-up our work environment.

Back to the Index


Getting ready

We'll use the Eclipse IDE for Java EE Developers to work with the project, so all the IDE related tips and the settings we're going to show, are specific for the Eclipse platform (again, see MavenEclipse section of the how-to-build-ST document for info on using Maven facilities in Eclipse). However you can find on the Web other ways to work with other IDEs using Maven.

Now...let's get ready!
Just download Eclipse EE from the official website and set the workspace. Now install the m2eclipse Maven plugin for Eclipse following this link instructions.
Now you have everything, m2eclipse already contains an embedded Maven installation and is already configured to be usable in Eclipse. However, we recommed to set Eclipse to use the Maven distribution you installed during the first step of this guide.

In order to do this, from Eclipse, go to: Window->Preferences, then open the tree root on Maven, and click on Installations. In the opened tab add a new installation path inserting the path where the bin folder of the Maven program you installed is located. Then switch from the embedded one to the one you installed.

Now, just pay attention to the instructions already present in the MavenEclipse section of the how-to-build-ST guide.

Back to the Index

Building your first Extension: the mass istance creation extension

Now you can start with the creation of your first extension. In this tutorial, you will develop an extension for allowing users to add more than one instance at the same time to a given class

Extension Development: Client side

As you know Semantic Turkey consists of two parts: one of them is a "simple" Firefox extension that implements the Client side of the whole architecture. In the following steps you will learn how to build your own Semantic Turkey client side extension.

Note that Semantic Turkey extensions are - conceptually - extensions of a browser (Firefox) extension, though, from the point of view of Firefox, they are actually direct Firefox's extensions with a dependency on a another Firefox extension (Semantic Turkey).

We assume that you are familiar with Firefox extension development; if this is not the case, please refer to Mozilla Extension Development site and take an overview about the Firefox extension.

Installation and registration of files


The goal of this step is to add a button to the main extension allowing us to insert multiple instances to the ontology. Before starting we are going to give you some basic suggestions to improve your development knowledge:

The first step for realizing the extension is to create the project structure.

Consider that there are a few Eclipse plugins supporting XUL (and Mozilla extension) development: xulbooster and Orangevolt EclipseXUL are two of them.

In this section, we however report detailed instructions for doing it manually:

First of all, you need to create the folder tree for the project (as specified in the Mozilla Firefox extension website),

 <ext path>\
          install.rdf
          chrome.manifest
          chrome\
             content\
                sample.xul
and, as you can see, to populate it with the right files:

The first one is used by Firefox to install the extension, while the second one is used to load the extension every time Firefox starts, inserting a reference into the chrome registry [ detailed information at https://developer.mozilla.org/en/Chrome_Registration ].


Writing the code for them is quite simple: advising you that more detailed information can be retrieved at https://developer.mozilla.org/en/Chrome_Registration and https://developer.mozilla.org/en/Install_Manifests, we'll give you some basic knowledge sufficient to fill these files.

Since it can be boring to write the install.rdf due to its syntax, what's better than copying it from a similar one and modifying it?
So go to the .xpi of ST you created or look at the install.rdf of our sample extension, copy the install.rdf and make the required changes (it consists only in modifying the extension-description tags like names, version, creator, paying attention to let unchanged the “em:type” tag and the “em:targetApplication” one).

Otherwise it is simpler to write the chrome.manifest:
you only need to write the first line like (remember the final '/' !)

content packagename uri/to/files/

and (as you can read on the mozilla link above): < < this will register a location to use when resolving the URI

chrome://packagename/content/...

The URI may be absolute or relative to the location of the manifest file > > .

The second line must refer to the .xul file you are going to overlay and it needs to have the following syntax:

overlay chrome://URI-to-be-overlaid chrome://overlay-URI

The order in which you write these lines in the manifest is not so important. It is more prominent to respect the right syntax. An helpful plugin to verify that your manifest is correctly written (and so your extension is loaded by Firefox), can be retrieved here https://addons.mozilla.org/it/firefox/addon/4453/

The browser's overlaying

If you have already filled the tree folder with the necessary files, open the overlay.xul one (otherwise create and put it into the “content” folder).
This file contains the graphical elements you want to add (overlaying) to ST. In our case we want to add a simple button in the proper menu. To reach this aim we wrote this code in our extension:

< popup id="clipmenu" >
	< menuitem id="menuItemCreateMultiple" flex="1" insertafter="menuItemCreateIndividual" >
		< menuitem-iconic flex="1" >
			< image src="../images/multiple.png" flex="0"/>
			< label value="Create Multiple" flex="0"/> 						
		</menuitem-iconic >
	</menuitem >
 </popup >
The clipmenu id has been found by using the DOM Inspector.
It is important to use instructions that overlay and do not override an existing .xul . As you can see, we used the insertafter value in the “menuitem” tag, so that the button is simply added to the list. If you do not do so your extension will be dangerous and may make it impossible to use ST.
Note that there is no Javascript code in the XUL file, not even to specify the action to associate with the click of the mouse. In fact we recommend to NOT include in this file anything that is not traceable to XUL. Of course this choice doesn't involve the final result, it's just a way to have a cleaner and more understandable code and above all to let the XUL file take different Javascript files simply changing the ones it is importing.
In fact the only duty of the XUL file is to import a Javascript file (through the tag < script >), to give dynamics to the static graphical elements created by the XUL file itself.

Keep in mind that all the windows you let appear must be modal ones. It means that when the window is opened it is possible to interact only with that window and the other task of ST can't be used. It prevents the user to create inconsistency in ST, like creating an instance of a class and deleting the class before the instance is created.

The Javascript file begins by checking the existence of the variable “art_semanticturkey”: it's used as a namespace! In fact every Javascript function name has this prefix, in order to avoid conflicts between our functions and the other ones. This is only a “first level” namespace, used by every function implemented in Semantic Turkey, and we recommend to use a second level too, extending the first one:

if (typeof art_semanticturkey == 'undefined') var art_semanticturkey = {};
if (!art_semanticturkey.multiple) art_semanticturkey.multiple = {};

The first line only checks whether the first namespace is undefined or not; the second one define our second level namespace. In this case we have used a simple and easy and short name, but in general it's preferable to use an URI to ensure its uniqueness.
Remember that we refer to these variables as namespaces only for convenience, but they are no more than simple variables.
The main code lines to open the desired window are below here

var parameters = new Object();
parameters.name = treecell.getAttribute("label");
parameters.parentWindow = window;
window.openDialog("chrome://multiple/content/createMultiple.xul", "_blank", "modal=yes,resizable,centerscreen", parameters);

The last line just open a new window passing it two parameters: the class name of the instances we are going to create and the parent window; the necessity of the first parameter is quite evident, the second one will be explained later.
The above code lines are contained into the onMenuItemCommand function, and this last is registered into the onLoad function, adding it to the functions list associated with the event click.
Note that the third parameter explicitly requires a modal window, and that the parameters are passed to this windows as fields of an object.
What we have showed is surely the most important part of the file, but it will never work until we notify to ST that it has to manage the click event on our new button; it can be done by the onLoad function, but for this to be called we have to insert a last statement at the end of file:

window.addEventListener("load", art_semanticturkey.multiple.onLoad, true);

The last step of this “graphical” design is to define characteristics and behavior of the window in which we will insert the names of the instances we want to add to the ontology. Once again you need a XUL file and its related Javascript file; the first one is very simple, just read it to understand its structure and meaning. The Javascript file is similar to the one introduced few lines above: it will contain, among other things, the function that directly implements the way of communicating with the server. This communication is based on the HTTP protocol (request side) and on the XML language (response side), and we encourage you to use the proper functions exported by ST modules by importing it in your code:

 
Components.utils.import("resource://stmodules/SemTurkeyHTTP.jsm"); 

This module contains two similar functions that forward the request to ST server: the first one using the GET method of the protocol, the second one using the POST method. In order to complete this last step you have to choose between these two methods, taking into account that the length of the request is limited for the GET while it is unlimited for the POST.
In our case we have chosen the POST because a string composed of ten names can be very long:

var responseXML = HttpMgr.POST("multiple", "createMultipleInstances", ("clsame="+window.arguments[0].name), ("instancesName="+instanceNames));

The parameters of the POST method (the GET one is similar) are:

Note that the GET method allow you to immediately test the server side of your extension:
you can just paste the HTTP request in the Firefox address bar and it will affect the ontology in the same way of the ST interface. To read an example of the address just take a look at the Firefox error console (make sure you have set the extensions.semturkey.log parameter to debug in the about:config Firefox panel) immediately after (for example) the creation of an instance. Keep in mind to remove the first part (up to http://...) and the last one (from async to end) of what you read there before pasting it in the address bar.
Finished? Almost! Do you remember the parentWindow parameter we have met in the previous lines? It is fundamental for the proper running of your extension to refresh after the operation of the user interface of ST (to put it in a consistent state with respect to the below ontology):

parentWindow.art_semanticturkey.createInstance_RESPONSE(responseXML);

That’s all! Now just save your work, compress the directory tree in zip format and rename it with the the xpi extension.

Back to the Index

Server side

Remember that the server-side project of your extension will be a Maven project. If you've chosen Eclipse as your integrated development environment (IDE) as we suggested, you have to install the m2eclipse plugin (probably you already did it following previous instructins in this tutorial). From now on, we will assume that you're using Eclipse and that you followed every single step that was stated above. If you're having trouble following the next sections, please

  1. check again if you've executed all the previous steps correctly
  2. if the problem persist check the FAQs session for a valid answer
  3. as a third chance, try to contact the authors or, even better, send a mail to the Semantic Turkey Developers' group

Server side: setting-up

First of all open Eclipse and load your personal workspace. If you go to New and choose the Other option you'll see that thanks to the plugin installed you have now Maven as one of your possible option. You have to choose Maven Project under the Maven section.
The project you are about to create is a simple Maven project so you can skip the archetype selection by ticking the combo box with this option. It is rather insignificant where you place your new project but we suggest you to keep it in the workspace location so you won't be having problem finding your project folder on your file system when needed. You can simply ignore all the other option and go forward to the next screen.

In this second screen you have to enter some data regarding your artifact such as yout group id, the artifact id, the artifact version and the type of packaging. It is quite simple to guess what this few fields means but in any case, the first field, the group id, is a name or a code needed for identifying the creators of the extension, for us it was STEDoc Team. The second field is needed for identifying the extension, it is always better to use a name related to the extension capabilities and use. The version is needed for a more organized upgrade of the extension(remember that the SNAPSHOT suffix is useful to imply that the released version is not completed).
As the type of packaging you have to use bundle. The parent project field can be always be leaven blank without any relevant consequences.

In this screen you don't need to do anything and you can simply press finish and create your new Maven project.

The project has the classical Maven directory layout. In the folder named src /main/java (i.e. the section for java code related to the application you are developing) you can start to build your extension package/namespace. Fo our one, we use the standard one for semantic turkey, but you can use the one related to your company/organization:

it/uniroma2/art/semanticturkey/

To do so, you have to right click on the src/main/java folder in the Eclipse environment and create a new package. We suggest you using it.uniroma2.art.semanticturkey and as path #project_name#/src/main/java/it/uniroma2/art/semanticturkey/ . Naturally every new source file must be created inside the new package you've created.
Now browse the project and open the pom.xml file inside eclipse.

Here you can see a simple user interface where you can insert data about your extension. Particularly you need to select the second tab labelled “Dependencies” in the bottom of the window and add all the library to which you depend on. To do so click on the “Add” button in the section on the top-left of the main window, and begin to type the path of the library you installed in the Maven repository (the path is not an absolute one: it begins from the first folder of the library, i.e. for ST is “it.uniroma2.art.semanticturkey.semanticturkey”). If the package you are looking for does not appear, you can create manually the dependency clicking on “Create” and filling the section “Dependency Details” on the right. The first dependency you have to set is the one relative to SemanticTurkeyBM: it was inserted in your local repository when you built ST during the first steps of this guide.
If you need to create the dependency with the create button (for the above reason), you may want to know which are the strings you need to insert in the boxes. Well, to discover it, you have to look at the pom.xml file of the relative jar library, so: 
go to your local Maven repository and follow the path to the desired jar, then open the jar and look for the pom.xml (generally it is in the “META-INF” folder). The only tags you need are: groupid, artifactid, version. So use them to fill the boxes and terminate the setting of the dependency. Be sure that the symbol near the dependency-name is not a folder. If it's not, refer to the last part of this webpage. After setting all the dependencies you can save the pom of your extension and, if needed, update all the dependencies (right click on the project->Maven->UpdateDependencies). You can see that a background process is working for you and it is catching all the libraries that are not in your local repository but in Maven-central. If some libraries you specified in the dependencies are neither in your local repository nor in Maven-central, you can see an error on the console, so you need to download and install it manually because it isn't in any repository.
As a second step in setting-up the pom you need to specify the maven bundle plugin useful to obtain your bundle. Select the tab “plugin” in the pom window and add the plugin clicking on “Add” button on top-left of that window, type “org.apache.felix” and then select “maven bundle plugin” and when it is inserted tick the checkbox “Extensions” in the top-right to automatically insert the extension tag in the pom. You could specify other configuration tags for this plugin like the “bundleName”, “bundleDescritpion”“bundleVendor”, … . The most relevant for the extension is the “Bundle-Activator” tag, that is used to specify the path of the bundle activator class. Another important tag could be the “Import-Package” one used to specify in the future MANIFEST.MF which packages are needed by the extension (and, eventually, which not). To do so check the packages you are using and insert them in this tag (be aware to insert the name package but not the class path!). However if you do not specify any tag the default will be used and the packages to import will be all the dependencies, the dependencies of the dependencies, and so on...[further information clicking here ]. Also modify the “org.apache.maven.plugins:maven-compiler-plugin” in the pom, but specifying as further tags the following:

< configuration > 
			< source > 1.5 < /source > 
			< target > 1.5 < /target >
< /configuration > 
 
keeping in mind that 1.5 is the version of the jdk you are using or you are forcing to use with this project (be aware that until jdk 1.3 generics are not supported).
Moreover verify that the tag “packaging” with value “bundle” is present into the “project” tag (you should have inserted it before into “Packaging” list in the overview tab) so that the command “mvn package” will export a jar file containing a MANIFEST.MF specific for a bundle.
If these steps were tedious for you, think about on configuring manually the pom, writing yourself the xml code resulting in the tab “pom.xml” of Eclipse. We think you should be thankful to Eclipse plugin for helping you.
After this last setting-up, you can begin coding your classes, keeping in mind that if you need to add other dependencies or plugins you have only to add them in the pom.xml (as it is specified above), and let Maven worry about it.

Server side: generic implementation 

Now that everything is ready for creating the server side let's see how it works. We are trying to add a new request, or possibly more than one.
A request is a new method available for the ST's plugin on Firefox once it has been extended with the client side of our extension, which will call the new request in the server side. If you want ST to cope with your new requests you have to extend ST with a new service.
A service can be seen as a container for new requests: all the requests are contained into a service, and since we have more than one service registered on the platform we can have multiple requests with the same name defined in different services (be aware that is also possible to register more than one service in the same activator class). As you've seen while making the client side of your extension, the HTTP request contains both the field service and request. Thanks to these fields we can identify the code that must be executed when ST's server side receives the message.
You have to create a class that will be used to register the service when ST is started (this is usually called the activator class) and another class that will contain the code to be executed when the registered service will be asked from the client side.
This structure is necessary because ST uses an OSGi platform, in particular the Apache Felix implementation, to make the services, and thus their relative requests, available.

So, create two new java classes: the first one will be used to register (automatically) the bundle on Felix and consequently its service on that platform service-registry, while the second one will manage the service.
In both cases it is strongly recommended to give them names recalling the service. Generally, for the bundle activator class, this name is followed by the “Activator” suffix(for example we used “CreateMultipleActivator”) while the second class carries the same name as the first one without the “Activator” suffix.
As we said above the activator class will allow the service to be registered on the Felix platform. To do so it must implements BundleActivator interface and so it will have to contain the two methods stated in the interface: “start” and “stop” each of them throwing Exception to prevent any single exception that your extension could generate.
We will concentrate on the start method leaving the stop empty because, at this moment, ST does not support stopping a service.
The method that you must call in start is:

context.registerService(ServiceInterface.class.getName(), new *class managing the requests*(String *service name*), null)

where the first parameter is the string that will identify the class that managing the service, while the second one is an instance of the second class you created.
It is important that you use a unique name for the service. In fact ST uses a map data structure to manage a table “service-serviceID”, and since the services are registered sequentially, a serviceID (the service name) may overlap a registered one and the following behaviour may be undefined. It is so necessary that you check the existing services (looking at the source code of ST or other ST-extensions) and be sure to never use an already used name.
There is no need for you to add anything else inside this class. In fact this one must be as simpler as possible: it might only register the services and might not include any other instructions, because the registering of the services might take too much time and fail, making impossible to use the extension. If you need you can at most put in it a print method to verify that the services has been registered, but it is recommended to remove it after debugging.

Now we're going to talk about the second class.
As we suggested before use a name similar to the service you are creating. Usually it is named as the bundle activator class without the “Activator” suffix. This class will manage your new service and so all the requests defined in it.

This new class you created has to extend ServiceAdapter.
It is greatly recommended to declare a few useful static final variables for a better reading of the code by other programmers, declaring this variables will make the code easier to understand, easier to adapt to another request, more general.
Adopting the scheme used on the original ST project you should divide these variables in groups according to what they stand for. A good division could be:

Once all the variables are declared you can move to the constructor that should take a String as a parameter and give it to the super method. There is no need for any other operation in the constructor. The other important method that you have to define in your class is:

public Response getResponse()

This method will be called when the service registered by the activator will be specified in the HTTP message sent to ST's server side.
It is then necessary to make a sequence of controls to understand which request has been made and be ready to get the parameters of the request.
To do so we need two local variables: a new ServletUtilities object and a string in with you can put the request specified in the HTTP message thanks to the method setHttpPar(“request”). Now comparing the string containing the received request with the various strings that you should have created beforehand regarding the various requests, you can identify which request was forwarded in the HTTP message.
Once you've recognized which request was received you have to get the parameters from the HTTP message and then execute the request.
For retrieving the parameters from the HTTP message we can use the method of the class ServletUtilities (you should have created an object of this class already):

String removeInstNumberParentheses( setHttpPar( *parameter variable* ) ) 

< parameter variable > is one of the variable you should have created beforehand containing a string reporting the tag of the parameter inside the HTTP message.
Naturally if the request is not specified in our service we need to return an error of the type createNoSuchHandlerExceptionResponse as the response.
Before returning the response it is also important, if the response is created correctly, to execute the method:

void fireServletEvent()

this method should communicate to the other listener who registered for this event that the request was computed

Now we can't possibly know what kind of extension you want to make so we will continue describing our extension as an example hoping that it may be helpful.



Server side: implementation of the "create multiple service"

After taking the parameters from the HTTP message we had to separate the various instances names that were passed with this logic:

instancesName=name1,name2,name3,...,name10

We created a method that returns an ArrayList, the use of an ArrayList will be proven necessary later on when we will have to control the presence of duplicated instances.
The method that will create and return the Response object is:

Response createMultipleInstancesOption(ArrayList, String)

We passed to the method the ArrayList containing the various names of the instances and the class name. Of course we control if the user has inserted at least one instance name, if not there is nothing to add to the ontology.

Inside the createMultipleInstancesOption method (it was called like this recalling the method of the single instance creation in the original ST project) we had to create several objects for instantiate the ontology model and the various resources such as the class and the many instances to be created. Using the existing methods from the original ST's project we added the instances inside the ontology if they are not already existing inside it.
The method updateClassesOnTree takes the class name and the new instances names as well but has the duty of building the XML response to send back to the client side. The XML message we created is as similar as it could be to the one that the original ST's project uses.
It is not the role of this guide to illustrate how to create an XML message but since creating a correct response for the client side is one of the key points of the extension on the server side, we are going to provide some general notices.

First of all we can use an object of the class ResponseREPLY to contain the response. Is has to be initialized correctly, for example we used:

ResponseREPLY response = servletUtilities.createReplyResponse(request, RepliesStatus.ok);

The first think you can note is that the constructor has two parameters, the first one will specify which request has been answered to, and the second one will specify the status of the message. 
In the XML response elements can be added. It is possible to create many types of elements just instantiating the Element objects in different ways. One of the most useful is creating an Element referring to a specific tag in the XML like the data tag. To obtain “control” of the data tag we instantiated the Element object with the following method:

Element dataElement = response.getDataElement();

Using this Element we could include other XML elements inside the data part of the XML message. To create a basic XML element we used:

Element clsElement = XMLHelp.newElement(dataElement, "Class");

with this instruction we obtain a new XML element of the type “Class” contained in the data section of the XML message. After having created the instance the attribute of the XML element must be initialized:

clsElement.setAttribute("clsName", *value* );

Once all the XML element are created we had to simply return the ResponseReply object and the ST's code on the server side will send it back to the client side.


We are aware that this example doesn't cover all there is to know about the making of the XML file and the creations of elements, but we leave it to the reader to learn more about the XML from other sources in order to create more advanced features.

Back to the Index

The final countdown

Once, you coded the client side you should be ready to make your own .xpi and install it in Firefox. But if your extension needs a server side (so it's not only a graphical extension), then you need to create a bundle containing the service provided by the server side of your extension.
As we mentioned above, if you set-up correctly the pom.xml, you need just to use the command

mvn clean package

and get you packaged jar bundle file (be sure that the MANIFEST.MF inside is correct!).

To create your full client-side extension put the bundle jar into the “extensions/service” folder of the main folder, so that you will have the following folder tree
 <ext path>\
          install.rdf
          chrome.manifest
          chrome\
             content\
		    sample.xul (& related .js)
	  extensions\
		service\
			your_OSGi_bundle
then select all the folders inside the main one and zip them into a file. Now simply rename the file into .xpi and drag it into Firefox to install it.

If it works fine, well done! You reach your goal!
If it's not, don't panic! It is easy to forgot doing some steps or to make some mistakes. So read your code and verify to have followed our instructions.
If you have any other questions please refer to the FAQs or contact us.

Have a nice coding!

Back to the Index

FAQs

Back to the Index