May 162014

Some days ago, I wrote a post about how to export a Topicmap in Deepamehta. This functionality is part of the final goal of doing an Import/Export plugin.

In this post, I will explain how have I done the import Topicmap method, that I will probably change in the next days, but in any case, I’ll tell what have I done until now :-)

Let’s see what do we need to actually import a Topicmap.

  1. Have a Topicmap file to import, obvious ;-)
  2. Create a new Topicmap where we will place the topics and associations of our exported Topicmap
  3. Add the topics of our exported Topicmap to our new Topicmap
  4. Add the associations of our exported Topicmap to our new Topicmap

So let’s proceed

First, read the file where the exported Topicmap is. For the moment, and to do things step by step, I’ve hard coded the file that I want to import.

As I said in the previous post, I exported the Topicmap into a JSON file placed in runner directory, that is at the root of your DM instance. We are going to read the same file that was exported there.

File file = new File("topicmap-11216.json");
String json = JavaUtils.readTextFile(file);

Now we will define a JSON Object from the read file

JSONObject topicmap = new JSONObject(json);

So the exported file with the Topicmap we have it accessable in JSON format in the variable topicmap.

The next task was to have a new Topicmap, where we will add the topics and the associations from the exported Topicmap.

Topic importedTopicmap = topicmapsService.createTopicmap("Imported Topicmap","dm4.webclient.default_topicmap_renderer", null);

To create a new map we need topicmapService, so you need to import it, that means add it to the rest of the import at the top of the file.

import de.deepamehta.plugins.topicmaps.service.TopicmapsService;

Fine, let’s continue. Which one was our third task? To add the topics of our exported Topicmap to our new Topicmap.

We will first create an array with the topics by extracting the information from the JSON that we already have.

We will first take a look at our JSON file, to parse it and visualize it you can check


So you can see that we have 3 parent objects: assocs, info and topics.

We are focusing in the topics, so we can see that there are 4 topics that need to be imported, we will access to the topics by getting the array associated to the key “topics”.

JSONArray topicsArray = topicmap.getJSONArray("topics");

When importing topics, there is one important thing to have in mind.
The way to retrieve the associations between topics, is because we establish an association between 2 topics through the topicIc, something like, association1 relates topicId=12 with topicId 23. So we have to map the new topicIds with the exported topicIds

We know that we are adding new topics to a recently created Topicmap. The id of the new topic will be automatically generated and set, so we don’t have the option of setting the id of the new topic to be the same as the id of the topic exported. That means that we have to keep track of which new topicId corresponds to the exported topicId by creating a Hash.

We define the Hash to map topic Ids.

Map<Long, Long> mapTopicIds = new HashMap();

In order to get the topics we have to iterate through the topicsArray by doing (for example)

 for (int i = 0, size = topicsArray.length(); i < size; i++)

By iterating we are going to get individual topics. If we take another look at the jsonparser, we can see that a topic is determined by an id, type_uri, uri, value, composite and view_props.

In each iteration we are going to get the content of all of these attributes.

 for (int i = 0, size = topicsArray.length(); i < size; i++)
                    JSONObject topic =  topicsArray.getJSONObject(i);
                    TopicModel model = new TopicModel(topic);
                    CompositeValueModel viewProps =new CompositeValueModel(topic.getJSONObject("view_props"));

                    Topic newTopic =  dms.createTopic(model, null);

                    long topicId = newTopic.getId();
                    long origTopicId = topic.getLong("id");
                    mapTopicIds.put(origTopicId, topicId);
                    topicmapsService.addTopicToTopicmap(topicmapId, topicId, viewProps);


To understand the loop, we’ll go line by line. By invoking getJSONObject(i) we will extract topic i.
On the other side we know that the createTopic method is provided by Deepamehta Servide (dms), where you need to pass a model and clientState. The clientState will be null.
The model we will be created by

TopicModel model = new TopicModel(topic);

so with a model and clientState we create the new Topic

Topic newTopic =  dms.createTopic(model, null);

We said that we have to keep the relation between new Topics id(newTopic.getId()) and exported Topics id(topic.getLong(“id”)), so we do that

long topicId = newTopic.getId();
long origTopicId = topic.getLong("id");
mapTopicIds.put(origTopicId, topicId);

In order to be able to add the new Topic to the new Topicmap, the topicmapService provides us with a couple of methods, the one we will choose is

addTopicToTopicmap(long topicmapId, long topicId, CompositeValueModel viewProps);

so before being able to add a Topic to a Topicmap, we need to get the CompositeValueModel, viewProps from the exported Topic.

 CompositeValueModel viewProps =new CompositeValueModel(topic.getJSONObject("view_props"));

Finally we can add the Topic with the info coming from the exportation to the new Topicmap

topicmapsService.addTopicToTopicmap(topicmapId, topicId, viewProps);

Wowww…now if you go to the webClient and click on import Topicmap, you will see how the topics appear in a new Topicmap :-))

And our last step was a”Add the associations of our exported Topicmap to our new Topicmap”

As with the topics we are going to extract the associations of the JSON file into an Array

JSONArray assocsArray = topicmap.getJSONArray("assocs");

We will iterate through the Array

 for (int i=0, size = assocsArray.length(); i< size; i++)

Take a moment, to check in the jsonparser, that the elements that form an association are id, role1, role2, type_uri, uri, value and composite. Inside role1 and role2 is stored the reference to the topicId to the "two sides" of the association.


As with Topics, DeepaMehta Service provides us with a createAssociation method

Association newAssociation = dms.createAssociation(assocModel, null);

We can create a new Association Model by

AssociationModel assocModel = new AssociationModel(assocsArray.getJSONObject(i));

but the important thing is to actually associate the two topics "coming" from our export file. To track this association we have already built a Hash that maps the topicId from the exported file with the new topicId, now we are going to use that mapping. So we have to change the values created automatically when creating an AssociationModel and set them with the values of the exported Topicmap.

RoleModel role1 = assocModel.getRoleModel1();
RoleModel role2 = assocModel.getRoleModel2();

So first, we get the RoleModel of the new association and we set the topicId(playerId is a general term that can be refered to a topicId or an associationId) to the value that was stored on our hash called mapTopicIds.

We are almost done :-) .. just one step missing, to add an Association to a Topicmap, the need the id of the new association, with that we are able to use the method provided by topicmapsService, AddAssociationToTopicmap to add our associations to our imported Topicmap :-)

long assocId = newAssociation.getId()              topicmapsService.addAssociationToTopicmap(topicmapId, assocId);

So, if you go to the webClient and chose to Import a Topicmap, you'll see it directly on the screen, as an example the one that I have :-)


 Posted by at 4:41 pm
May 032014

In the previous post , we explained how to writer the export part of the server side part of the import-export plugin. But with almost everything done, we missed one thing, the implementation of the export option from one of the menus in DM webclient.

The place to click the export action will be inside the topicmap drop-down menu.

First we need to create the directory structure for our client side, that is, inside /src/main you have to create


and in there the file plugin.js

Once the plugin.js file is created, we have to add our plugin, for that you have to invoke dm client (dm4c)

dm4c.add_plugin("net.abriraqui.import-export", function(){

Then dmc4 provides a listener that will allow you add elements to the topicmap menu. The elements that we will add are: a separator and the new item with “Export Topicmap” label, that will execute a export_topicmap method.

dm4c.add_listener("post_refresh_topicmap_menu", function(topicmap_menu) {
    label: "Export Topicmap",
    handler: export_topicmap

and of course, we need to write the export_topicmap method, which will be quite simple. We define the uri for the export action, “/import-export/export”. Since we want to show an alert box that tells us that the topicmap has been exported, we first get the topicmap and then in the alert we call the get_id() method to know which topic map are we in.

function export_topicmap(){
 dm4c.restc.request("POST", "/import-export/export") 
 var topicmap =   dm4c.get_plugin("de.deepamehta.topicmaps").get_topicmap()
 alert("Export of topicmap " + topicmap.get_id() + " complete")

Once done that, now we can finally check into our runner directory, in the root directory of your plugin, for the topicmap-XXX.json file with the info of the topicmap exported.

Implementing export topicmap option

May 032014

Some months ago, I wrote a post of how to start creating a plugin in DeepaMehta, it was basically to show, the use of migrations to create new topic types in a permanent way, in your DeepaMehta instance.
It was the first step to create a Calendar plugin for DeepaMehta, but since to create both client side and server side for that plugin would be quite difficult task as a first contact with DeepaMehta, I decided to do a couple of things first.

One was to actually write a casual user guide of how DeepaMehta can be used, that has deepen my understanding of how to use it, how it works, what I miss, etc.

On its way, one of the things that I miss is the possibility to import and export topicmaps. So since import-export feature works more at a server side, I thought it would be good to first focus on the server side, with a bit of client side, to get familiar with DM development framework.

The good thing is that this part is already documented in DeepaMehta  plugin developers documentation :) so what I’ll try to do is write down my use case with the import-export plugin.

To start the plugin main file must be located directly in the plugin’s src/main/java/, so the first thing to do is to create this structure, then it will have to be followed by a specific tree structure and the plugin name(as a convention, must end with Plugin). So the first thing is to figure out this directory structure.

One thing that I forgot to say, is that actually the first thing to do when creating a plugin is to define the pom.xml file. Following the guide, the initial pom.xml will look something like

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="" xmlns:xsi=""

  <name>DeepaMehta 4 Import Export </name>
  <groupId>net.abriraqui.dm4 </groupId>
  <packaging>bundle </packaging>



The important thing to see is the groupId, where we are defining the unique namespace for our plugin,net.abriraqui.dm4, and the artifactId, where we are defining the context where is created, that is DeepaMehta version (4.3) SNAPSHOT , the development version, followed by the name of the plugin, import-export.

We will build a correspondent directory structure inside src/main/java  that will me net/abriraqui/dm4/importexport  , importexport is the name of the plugin that in the directory structure, by convention, won’t have a dash in between.

Once you’ve created the directory structure, you create your plugin java file that should be called, .

So as in the dev guide says, the plugin package is net.abriraqui.dm4.importexport and the plugin main class is ImportExportPlugin

A plugin main file is a Java class that is derived from de.deepamehta.core.osgi.PluginActivator. The smallest possible plugin main file looks like this

package net.abriraqui.dm4.importexport;

import de.deepamehta.core.osgi.PluginActivator;
public class ImportExportPlugin extends PluginActivator {

Continue reading »

Apr 222014

It feels a long time without writing in the blog. After diving in some near world, is the moment to share how it looks like, the invisible white world.

A veces, pasa el tiempo, pero fuera del reloj, es otro, es el tiempo que pertenece a  otro mundo, dentro de este mundo, pero invisible. Existe, y está cerca,  en ocasiones ese mundo subterráneo le da el cambiazo al que está en superficie, ahora quiero visibilizarlo.


Un día cualquiera llegas a una puerta, de un edificio en una calle cualquiera, y entras, pone “Urgencias”. Cuando llegas no eres consciente de que estas a punto de entrar en un mundo en sí mismo, simplemente piensas que es una pata más de ese en el que te mueves diariamente. Sin embargo, en esos primeros minutos, ya notas las diferencias. Tras los cristales, salas de espera, pantallas donde avisarán si ya tienen información sobre el ingresado. Mayoritariamente se ven personas solas, o en parejas, en silencio, no hay muchas ganas de hablar. Se buscan los enchufes, imprescindibles para mantener los teléfonos encendidos, imprescindibles para tener contacto con el exterior. Los enchufes evidentemente escasean, no funcionan, comienzan los paseos arriba y abajo, buscando, mirando detrás de cada asiento, de cada maceta, de cada máquina, en cada rincón, confiando que alguno disponible esté libre, alguno que nadie haya visto y así conectar nuestro teléfono.

Siempre lo hay, acabas dejando el móvil metido en una maceta o en la papelera, pero cargando la batería.

It’s funny to think, that  normally, one sees a hospital and never thinks what is inside, is quite obvious, sick people, but thoughts stop there. Until one day you arrive to a door that says “Emergency”, your loved one enters to an area and you wait outside. Glass doors, people alone, or in pairs, silence and a worry to find a plug where to plug the handy, our contact to the world. Although most of the people use mobile phones, buildings don’t provide an easy way of charging them, you have to find the plug, behind seats, plants, hidden in some corner, so for a moment, all the movement around the the waiting room has to do with the discovery of an empty plug.

Entonces, aparece tu número en pantalla, te darán información, es como esperar una sentencia. Te acercas, esta vez el jurado ha fallado, te quedas. Empieza una nueva vida. Sales y ves un grupo numeroso en la puerta, quizá sean 10 personas, se hace raro en mitad de la noche y del silencio, van y vienen, es un grupo de gitanos que vienen a acompañar, han ingresado a uno de ellos, al contrario que la norma, son muchos, de todas las edades, grandes y niños, hombres y mujeres. Momentos de envidia, es el grupo, la comunidad la que cuida de sus miembros, no estan solos, allí se quedarán, se relevarán hasta que su ser querido salga. Tu sigues tu camino, ahora dentro del área de urgencias, te permiten ver a tu ser querido, un rato.

Continue reading »

 Posted by at 5:48 am
Feb 212014

Rails Girls LogoA bit more of a year ago, I got to know about RailsGirls initiative, I joined one of their workshops and had a great time. So I joined other of their initiatives, like meeting on Sundays in a more informal way to have a coffee while talk about coding, and of course Rails Girls Summer of Code!!, where with my pair @juliaguar, we contributed to Diaspora free social network.

After one year of profiting of all the good work done by RailsGirls, I had the feeling to give back something, so once I knew the Hackday was coming up and also knowing that @phansch was taking part as a coach, made me take the decision to sign as a coach for beginners.

Honestly I must say I had no clue how to do it, nor did I have much time to think about it. Saturday morning arrived, I had a cold, I was tired and thought OMG! how am I going to be able to explain anything. Anyway, the fact was that I was going to the Hackday and let’s see.

After a first “hello” , a coffee (10 a.m. is a good moment to have a coffee on a Saturday), and realizing that I knew some people,  we did a round to introduce ourselves, our name, experience, expectations about the workshop. This time there were around 5 complete beginners and the rest were study groups that work on a week basis and the Hackday is a good excuse to impulse a bit more the project.

Hackday whiteboardSuddenly I forgot about the cold, the fatigue, it was fun being there! So three of us wanted to coach the beginners which was really cool, after setting up rails, discussion a bit how to proceed, where to start from, what was the background of everybody.

We started and decided to have the RailsGirls tutorial as a guide, but we would not use so much the gems, but explain how things worked from scratch, so that Rails “magic” could be better understood. We used the white board to explain the main MVC principles, then went into see how  routing works, how models, controllers, views look like.

We stopped for lunch, everybody brought something and then we shared it :-), and after lunch, for an  hour or so, we had lightning talks, and yes I also gave one, “Free/Libre software and Open Source, because social responsability matters”

After the talks, back to coding!!
At Rails Grils Hackday
So yes, that was how we spent the day, it was a really nice experience, that I would like to repeat :-)