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

resources/web/script 

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) {
  topicmap_menu.add_separator()
  topicmap_menu.add_item({
    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="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <name>DeepaMehta 4 Import Export </name>
  <groupId>net.abriraqui.dm4 </groupId>
  <artifactId>dm43-SNAPSHOT-import-export</artifactId>
  <version>0.1-SNAPSHOT</version>
  <packaging>bundle </packaging>

  <parent>
    <groupId>de.deepamehta</groupId>
    <artifactId>deepamehta-plugin-parent</artifactId>
    <version>4.3-SNAPSHOT</version>
  </parent>

</project>

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, ImportExportPlugin.java .

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 »

Dec 272013
 

The day that I’m able to write properly DeepaMehta in the first try, will be amazing!!

Anyway, the thing is that in hackership I’m building a webcalendar as a petproject to learn more ruby & rails, but one of my goals at some point of my learning process is to work with graph databases and semantics. I find that the representation of knowledge needs graphs and the retrieve of information semantics.

A year ago, more or less, DeepaMehta appeared into my life, I found it a really, really cool project, one of those that at some point you want to take part of. No idea when or how.

DeepaMehta is a webclient and an application developpment framework and in its webpage says

DeepaMehta represents information contexts as a network of relationships. This graphical representation exploits the cognitive benefits of mind maps and concept maps. Visual maps — in DeepaMehta called Topic Maps — support the user’s process of thinking, learning, remembering and generating ideas

You also can read more about the concept behind it.

During the last DeepaMehta Lounge, a possibility was opened, to try it to use it with the webcalendar, let’s say to have it as the database behind the scene, probably is not the best thing to do, since it’s a framework and you can directly develop in it, but it’s Java, and for the moment I have no idea of Java, and I want to continue with Ruby & Rails but, having a specific idea in mind, I want to learn some basics of how DM works. So for the moment, I’m going to use it as database and communicate with it through its REST API.

So to do that I need to build a plugin. I was very lucky to be able to go through this process with some of the DM core members, so the least I can do is to share what I learned :). Let’s do it.

First, let’s install DeepaMehta, for that we have to check the requirements, as an Ubuntu user, they are the following:

DeepaMehta requires JAVA 1.6 or later:
sudo apt-get install default-jdk

For the development system you will also need to install maven and git:

sudo apt-get install maven git-core

Then I want to build DM from source so I have to clone the software from github
git clone git://github.com/jri/deepamehta.git
cd deepamehta
mvn install -P all

This may take a while, so just be patient  :). Once it has finish, you need to run DM
mvn pax:run

This starts the DeepaMehta server and then opens the DeepaMehta web client in a browser window.
If no browser window appears open it manually:

 http://localhost:8080/de.deepamehta.webclient/

You will see

Deepamehta

There on the top-right corner is a login link, click on it and put user admin and password empty. You’re DM is ready!!

Now is time to start writing the plugin.

First you have to create a directory with the name of the plugin, better if somehow reflects that is your plugin and is uniquely identified. In my case I named the directory cgc-calendar, name that I will use as the id of the project, though is not mandatory.

Inside our directory you need to set up a specific directory structure

cgc-calendar/
    pom.xml
    src/
        main/
            resources/
                migrations/
                    migration1.json
                plugin.properties

where

  • pom.xml file stands for Project Object Model and is a representation in XML of the maven project
  • migration1.json A migration is a sequence of operations that transform the database, defines the database schema and ensure its structure and content is compatible with the code
  • plugin.properties is a file that allows the developer to configure certain aspects of the plugin

Ok, now let’s see how the files look like.

We’ll check first the pom.xml

<project>

<modelVersion>4.0.0</modelVersion>

<name>CGC Calendar</name>
<groupId>net.abriraqui.cgc-calendar</groupId>
<artifactId>cgc-calendar</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>bundle</packaging>

<parent>
<groupId>de.deepamehta</groupId>
<artifactId>deepamehta-plugin-parent</artifactId>
<version>4.2-SNAPSHOT</version>
</parent>

</project>

Let’s try to understand a bit the file

<name> Is the human readable name of the plugin
<groupId> must be globally unique name under which you collect the project’s artifacts. So a best practice to achieve this is to write first, the top-level domain and then your specific subdomain, in my case net.abriraqui.cgc-calendar
<artifactId> is the name of the generated .jar file. Within the group this name must be unique and in my case I use cgc-calendar.

Under <parent> are all the specifications referred to DM, here you have to be careful and set correctly the <version> of DM that you are using, in my case 4.2-SNAPSHOT

Next is to define the migration1.json file, here we are including all the database structure of the app. This case is a very basic one as shown in the following diagram

webcalendar UML

So we have to translate this into a json file.
Now we have to have in mind several things, DM uses graphs to represent knowledge, so we must forget about tables, join tables, etc in DM everything are nodes and relations or in DM language, topics and associations.

  • Topics – representing any concept, from people, countries, and organizations to software modules, individual files, and events,
  • Associations – representing hypergraph relationships between topics

Next step is to define the migration,  we will be doing a declarative migration, that is the one using json to define it. In it you can define 4 things: topic types, association types, topics, associations. The general format is:

{
    topic_types: [
        ...
    ],
    assoc_types: [
        ...
    ],
    topics: [
        ...
    ],
    associations: [
        ...
    ]
}

So a simplyfied representation of the event should look like something similar to

webcalendar2

This is the diagram that we have to translate to a migration in json format (migration1.json), which looks like

{
    topic_types: [
        {
            value: "Start date",
            uri: "cgc.calendar.start_date",
            data_type_uri: "dm4.core.number",
            index_mode_uris: ["dm4.core.key"]
        },
        {
            value: "End date",
            uri: "cgc.calendar.end_date",
            data_type_uri: "dm4.core.number",
            index_mode_uris: ["dm4.core.key"]
        },
        {
            value: "Event",
            uri: "cgc.calendar.event",
            data_type_uri: "dm4.core.composite",
            assoc_defs: [
                {
                    child_type_uri:        "cgc.calendar.start_date",
                    child_cardinality_uri: "dm4.core.one",
                    assoc_type_uri:        "dm4.core.composition_def"
                },

                {
                    child_type_uri:        "cgc.calendar.end_date",
                    child_cardinality_uri: "dm4.core.one",
                    assoc_type_uri:        "dm4.core.composition_def"
                }       
            ],

            view_config_topics: [
                {
                    type_uri: "dm4.webclient.view_config",
                    composite: {
                        dm4.webclient.show_in_create_menu: true
                    }
                }
            ]
          }
       ]
}

Let’s understand what it all means or at least try to 😉

We are defining different “nodes” / topics  of our graph, those are event, start_date, end_date.

Each topic_type has a

  • value, is the  human readable name
  • uri, the unique identifier
  • data_type, to determine the type of data

In the case of the dates, we have a

value: “Start date”,
uri: “cgc.calendar.start_date”,
data_type_uri: “dm4.core.number”, there are no date type, so we use directly number to specify dates

when looking at the event we see that the data_type is a composite, which would mean that is a topic type composed of ,or that needs, other topics types to be defined. In the case of event is quite clear, it needs an start_date, end_date, to say that, we have to define the association as follows

assoc_defs: [
                {
                    child_type_uri:        "cgc.calendar.start_date",
                    child_cardinality_uri: "dm4.core.one",
                    assoc_type_uri:        "dm4.core.composition_def"
                }

So now we are almost done with the first very simplified definition of event but in order to see our topic type  in the graphical interface we need to add to the migration, some configuration info

view_config_topics: [
                {
                    type_uri: "dm4.webclient.view_config",
                    composite: {
                        dm4.webclient.show_in_create_menu: true
                    }
                }
            ]

where say that we want to see our recent created topic type in the create menu. Now in the create drop down menu of DM you will be able to see event as topic type and you can now use it in your projects 🙂

The last thing to explain is what goes inside the plugin.properties, for the moment the file consists of one line, referring to the migration

requiredPluginMigrationNr=1
importModels=de.deepamehta.webclient

The first line is require in order to be able to run the migrations and the second line
declares your plugin, makes use of the DM Webclient data model (namely its type dm4.webclient.view_config). DM then takes care the Webclient is installed *before* the Calendar plugin. However, this is only of importance if Calendar is installed along with DM.

Once you’ve made any changes to the plugin files, you have to build the plugin again. So in the terminal you have to put:

$ mvn clean package

In order to let DM know of the existence of your plugin(so you can see it on your browser), you must add  the plugin’s target directory (here: /home/myhome/cgc-calendar/target) to the felix.fileinstall.dir property’s CDATA section, which is in DM’s “global” pom.xml. This is found at the top-level of its home directory. Important: don’t forget to append a comma to the previous line

<project>

<felix.fileinstall.dir>
<![CDATA[
${project.basedir}/modules/dm4-core/target,
${project.basedir}/modules/dm4-webservice/target,
${project.basedir}/modules/dm4-webclient/target,

${project.basedir}/modules/dm4-storage-neo4j/target,
/home/myhome/cgc-calendar/target
]]>
</felix.fileinstall.dir>

</project>

So for a start with Deepamehta is not bad 🙂 … I’ll continue working on it, probably slowly since I have to do also the Rails part 😀 but as I do things I’ll be writing them and also I’ve set up a repo on github for it

This declares your plugin makes use of the DM Webclient data model (namely its type dm4.webclient.view_config). DM then takes care the Webclient is installed *before* the Calendar plugin. However, this is only of importance if Calendar is installed along with DM