RESTful service with TomEE and IntelliJ IDEA

In this tutorial you’ll build a basic RESTful service using the Java EE APIs, IntelliJ IDEA, and TomEE.

Overview

  1. Setup the TomEE application server in IntelliJ.
  2. Create a new project.
  3. Write a RESTful Java class.
  4. Run.

Used in This Tutorial

Prerequisites

  • Download and install IntelliJ.
  • Download and unpack TomEE.

Tutorial

  1. Setup the TomEE application server in IntelliJ.
    1. Start IntelliJ, and on the startup screen go to Configure -> Settings -> Application Servers.Screen Shot 2013-06-04 at 1.54.26 PM
    2. Click the “+” button (top center) to add an application server.
    3. Select “TomEE” for the type of server.Screen Shot 2013-06-04 at 1.55.41 PM
    4. Enter the directory where you unpacked TomEE.Screen Shot 2013-06-04 at 1.56.55 PM
    5. Click “Ok” and “Ok” again.  Then click the little back button in the start up screen to go back to the main menu.
  2. Create a new project.
    1. Select “Create New Project” in the IntelliJ startup screen.
    2. Select “Java Module”
    3. Name it “MyFirstRESTfulService”.
    4. There’s an option here to select your JDK. You may need to configure your JDK, first. This is an IntelliJ requirement, and I don’t remember how I did this, I hope it’s straight forward enough for you.
    5. Click “Next”.
    6. Select “Application Server” then select “TomEE” from the drop down box on the right.Screen Shot 2013-06-04 at 2.00.42 PM
    7. Select “RESTful service” and “Set up library later”.
    8. Click “Finish”.
  3. Write a RESTful Java class.
    1. Double click the project name to expand the tree view and you will see the “src” directory.
    2. Right click “src” and create a package (select New -> Package) called “org.mybiz”.
    3. Right click “org.mybiz” and create a class (select New -> Java Class) called “Greeter”.
    4. Edit the Greeter class until it reads like this:
      package org.mybiz;
      
      import javax.ws.rs.GET;
      import javax.ws.rs.Path;
      
      @Path("greeting")
      public class Greeter {
          @GET
          public String sayHi() {
              return "Hi!!";
          }
      }
  4. Run. Click the green play button to run the RESTful service. You should see messages in an output window at the bottom of IntelliJ. Look for a line like
    INFO: REST Service: http://localhost:8080/greeting/*  -> Pojo org.mybiz.Greeter

    This indicates the service was successfully deployed at the URL specified. Check for exceptions in case something failed.Screen Shot 2013-06-04 at 2.10.15 PM

Point your browser to the correct URL: http://localhost:8080/greeting/, and it works, yay!Screen Shot 2013-06-04 at 2.11.00 PM

Drag and Drop with Gtk2 and Perl

For the impatient, scroll down to the complete code example.  You may find this to be all you need.

I’ve struggled with drag and drop using Gtk2-perl for years… now I’m sharing my discoveries so you don’t have to struggle, too!

Here are some resources I used to create this article:

I’m mainly concerned with drag and drop within and between a tree or list (Gtk2::TreeView).  This turns out to be a rather complicated subject.  There are three ways to setup drag and drop in a tree view: set_reorderable, enable_model_drag_dest/enable_model_drag_source, and your own low level implementation using drag_dest_set/drag_source_set.  You can only use one of these methods.  The methods will step on each other and badness ensues when you try to use more than one.  set_reorderable is a convenience function for setting up reordering of elements within a tree using drag and drop.  It does not allow items to be dragged between different trees.  For these reasons we will not cover this function here.  Implementing your own low level drag and drop is very powerful and opens doors to unlimited possibilities, but requires a lot of work and I’ve found the middle road to be just fine for applications I’ve worked on.  The middle road (using enable_model_drag_dest and enable_model_drag_source) gives you lots of expected functionality with little effort.

In this tutorial the dragged item is moved and all code assumes the item is to be moved.  If you need the item to be copied, linked, or something else, you’ll need to modify the code.

set_reorderable – caution!

Gtk2::TreeView->set_reorderable – sets up drag and drop for reordering elements in the tree view.  No drag and drop is enabled between other widgets or applications with this method.  This is great until you start to want both reordering and drag and drop to other widgets.  Enabling this feature interferes with calls to drag_source_set and drag_dest_set, because it makes its own calls to those methods.  (note: if you’re using Glade to build your user interface, the “set_reorderable” can be set using Glade, effectively hiding the call to set_reorderable from you).

Basic Overview

The drag and drop process follows these steps internally:

  1. User drags a row from one view to another.
  2. Gtk calls drag_data_get on the source widget.
  3. The drag_data_get handler (written by you) puts the dragged data into a selection.
  4. Gtk calls drag_data_received on the destination widget.
  5. The drag_data_received handler (written by you) puts the dragged data from the selection into the destination and calls finish on the drag context.
  6. Gtk updates the view.
  7. User is happy.

As the developer all you need to do (not as simple as it sounds until you’ve done it once) is implement step 3, step 5, and connect the signals to the signal handlers in steps 3 and 5.

Nitty Gritty Details

There are so many nitty gritty details to programming in Gtk2 and Gtk2-perl, it drives me nuts!!  Here are some that I discovered while working on the code example below… but by no means is this a complete list.  Please leave comments with details you discovered that may be of use to me and others.

  • get_selected only works if GTK_SELECTION_MULTIPLE is not used.  See my ($model,$iter) = $tv_selection->get_selected; below.
  • enable_model_drag_dest can only be called once on a TreeView (if called multiple times, only the last call is used).  If you need multiple targets or actions you’ll have to list all the targets as arguments and combine all the actions into a Perl array reference, for example: [ 'move', 'link', 'copy' ]

Complete Code Example

The code highlighted in pastel red controls the drag and drop functionality.  All other code sets up the window, views, initialization code, etc..

#!/opt/local/bin/perl

use strict;

use Gtk2 '-init';

my $main = Gtk2::Window->new;

my $src_tree   = Gtk2::TreeView->new;
my $dest_tree  = Gtk2::TreeView->new;
my $src_model  = Gtk2::TreeStore->new("Glib::String");
my $dest_model = Gtk2::TreeStore->new("Glib::String");

# Setup trees
# src tree
$src_tree->set_model($src_model);
my $col = Gtk2::TreeViewColumn->new;
$src_tree->append_column($col);
my $renderer = Gtk2::CellRendererText->new;
$col->pack_start($renderer,1);
$col->add_attribute($renderer,"text",0);
# dest tree
$dest_tree->set_model($dest_model);
$col = Gtk2::TreeViewColumn->new;
$dest_tree->append_column($col);
$renderer = Gtk2::CellRendererText->new;
$col->pack_start($renderer,1);
$col->add_attribute($renderer,"text",0);
# end setup trees
# Drag and drop
$src_tree->enable_model_drag_source(
    'button1-mask',
    'move',
    [ 'text/plain', 'same-app', 1 ]
);
$dest_tree->enable_model_drag_dest(
    'move',
    [ 'text/plain', 'same-app', 1 ]
);
# signals for drag and drop:
$src_tree->signal_connect_after( drag_data_get => \&drag_data_get );
$dest_tree->signal_connect( drag_data_received => \&drag_data_received );
# end drag and drop
# setup ui
my $hbox = Gtk2::HBox->new;
my $vbox = Gtk2::VBox->new;

$hbox->pack_start($src_tree,1,1,5);
$hbox->pack_start($dest_tree,1,1,5);

$vbox->pack_start($hbox,1,1,5);
$main->add($vbox);

$main->set_size_request(640,480);
#end setup ui

# Fill models with test data
$src_model->set($src_model->append(undef),0,"One");
$src_model->set($src_model->append(undef),0,"Two");
$src_model->set($src_model->append(undef),0,"Three");
$dest_model->set($dest_model->append(undef),0,"Four");
$dest_model->set($dest_model->append(undef),0,"Five");
$dest_model->set($dest_model->append(undef),0,"Six");
# end fill models

$main->show_all;

Gtk2->main;
# Drag and drop signal handlers.

sub drag_data_get {
    my ($widget,$context,$selection,$info,$time,$data) = @_;
    my $tv_selection = $widget->get_selection;
    my ($model,$iter) = $tv_selection->get_selected;
    my $value = $model->get_value($iter,0);
    $selection->set($selection->target,8,$value);
    return 0;
}

sub drag_data_received {
    my ($widget,$context,$x,$y,$selection,$info,$time,$data) = @_;
    my $value = $selection->data;
    my $model = $widget->get_model;
    my ($path,$position) = $widget->get_dest_row_at_pos($x,$y);
    my $iter = undef;
    if ( $path ) {
        my $drop_iter = $model->get_iter($path);
        if (
            $position eq 'before' ||
            $position eq 'GTK_TREE_VIEW_DROP_BEFORE' ||
            $position eq 'into-or-before' ||
            $position eq 'GTK_TREE_VIEW_DROP_INTO_OR_BEFORE'
        ) {
            $iter = $model->insert_before(undef,$drop_iter);
        } else {
            $iter = $model->insert_after(undef,$drop_iter);
        }
    } else {
        $iter = $model->append(undef);
    }
    $model->set($iter,0,$value);
    $context->finish(1,1,$time);
    return 0;
}