Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/0old
out/*
69 changes: 69 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
FROM ubuntu:20.10

LABEL MAINTANER Jem Rayfield "jem.rayfield@ontotext.com"

RUN apt-get update -y
RUN apt-get install -y software-properties-common
RUN apt-get install -y perl
RUN apt-get install -y automake
RUN apt-get install -y graphviz
RUN apt-get install -y curl
RUN apt-get install -y git
RUN apt-get install -y wget

ENV DST_DIR=/puml-doc
ENV DST_DIR_OUT=/puml-doc/out

WORKDIR ${DST_DIR}

# CPAN
RUN apt-get install -y build-essential && \
curl -L https://cpanmin.us | perl - App::cpanminus
COPY rdfpuml-docker/MyConfig.pm /root/.cpan/CPAN/MyConfig.pm

# RDFPUML
RUN cd ${DST_DIR} && \
cpanm RDF::Trine && \
cpanm RDF::Query && \
cpanm RDF::Prefixes && \
cpanm Encode && \
cpanm FindBin && \
cpanm Carp::Always && \
cpanm Slurp && \
cpanm Getopt::Long && \
cpanm Pod::Usage && \
cpanm Path::Tiny

COPY rdfpuml-docker/rdfpuml ${DST_DIR}/
COPY bin/ ${DST_DIR}/rdf2rml/bin
COPY lib/ ${DST_DIR}/rdf2rml/lib
# JAVA
RUN apt update && \
apt-get install -y openjdk-8-jdk

ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/
RUN export JAVA_HOME

# MAVEN
RUN cd ${DST_DIR} && \
wget https://www.mirrorservice.org/sites/ftp.apache.org/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz && \
tar xvfz apache-maven-3.6.3-bin.tar.gz

ENV M2_HOME="${DST_DIR}/apache-maven-3.6.3"
ENV PATH=$PATH:$M2_HOME/bin

# Plant UML
RUN cd ${DST_DIR} && \
wget https://sourceforge.net/projects/plantuml/files/plantuml.jar
# git clone https://github.com/plantuml/plantuml.git && \
# cd plantuml && \
# mvn -Djar.finalName=plantuml package

COPY plantuml/plantuml.sh ${DST_DIR}/
ENV PATH=$PATH:${DST_DIR}/plantuml

COPY rdfpuml-docker/gen_puml.sh ${DST_DIR}/

COPY plantuml/plantuml.cfg ${DST_DIR}

ENTRYPOINT [ "/puml-doc/gen_puml.sh" ]
37 changes: 23 additions & 14 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,29 @@ See http://twitter.com/hashtag/rdfpuml for news, diagrams and announcements.
Source: [[./doc/rdfpuml.pod]], [[./doc/rdf2rml.pod]]

* Installation
Checkout this repo and add ~rdf2rml/bin~ to your path.
Install the following prerequisites:
- both tools: Perl. Tested with version 5.22 on Windows (cygwin and Strawberry).
- rdfpuml:
- [[http://www.graphviz.org/][GraphViz]]
- [[http://plantuml.com/download][PlantUML]].
You need a recent version for new features like arrow length and color. I'm currently running 1.2018.10beta7.
See in particular [[http://plantuml.com/class-diagram][plantuml class diagrams]].
- Perl modules: use ~cpan~ or ~cpanm~ to install them:
~RDF::Trine RDF::Query Encode FindBin Carp::Always Slurp~
- ~RDF::Prefixes::Curie~. This is my own module located in [[./lib]], and *rdfpuml* needs ~FindBin~ to locate it.
- rdf2rml:
- [[https://jena.apache.org/download/][Apache Jena]]: ~riot~, ~update~. Tested with version 3.1.0 of 2016-05-10.
- cat, grep, rm
Clone this repo

- Install Docker and Docker Compose

* [Install docker](https://docs.docker.com/install/)
* [Install docker compose](https://docs.docker.com/compose/install/)

- Build
```
docker-compose build
```

- Place your .ttl file for processing in directory `./ttl`
- Add any prefixes to ./ttl/prefixes.ttl
- Update and configure plantuml.cfg in directory `./plantuml

- Processing
```
docker-compose up
```

- .puml and .png will be place in ./out


* Evolution
Help needed for the following tasks.
Expand Down
105 changes: 86 additions & 19 deletions bin/rdfpuml.pl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@

use strict;
use Encode;
use warnings;
use autodie;
use Getopt::Long;
use Pod::Usage;
use Path::Tiny;
use Carp::Always; # http://search.cpan.org/~ferreira/Carp-Always-0.13/lib/Carp/Always.pm
# stronger than $Carp::Verbose = 1;
use RDF::Trine;
Expand All @@ -25,6 +30,7 @@
use lib "$FindBin::Bin/../lib"; # Curie is my own module, not yet on CPAN
use RDF::Prefixes::Curie;
#use Smart::Comments;
use File::Basename;

my %PREFIXES =
(
Expand Down Expand Up @@ -92,36 +98,96 @@
SPARQL
## $RE_SPARQL;

my $fname = shift or die "perl rdfpuml <file>: read <file>.ttl, write <file>.puml\n";
$fname =~ s{\.ttl$}{};
my $infile = '';
my $outfile = '';
my $prefixfile = '';
my $plantumlcfgfile = '';
my $help = 0;
GetOptions('infile' => \$infile, 'outfile=s'=> \$outfile, 'prefixfile=s'=> \$prefixfile, 'plantumlcfgfile=s'=> \$plantumlcfgfile, 'help|?'=> \$help) or pod2usage(2);
pod2usage(1) if $help;

my $prefixes = -e "prefixes.ttl" ? slurp("prefixes.ttl") : "";
my $file = slurp("$fname.ttl");
my $turtle = decode_utf8 "$PREFIXES_TURTLE\n$prefixes\n$file";
my $prefixes_all = decode_utf8 "$PREFIXES_TURTLE\n$prefixes";
open (STDOUT, ">:encoding(UTF-8)", "$fname.puml") or die "can't create $fname.puml: $!\n";
=head1 NAME

RdfPuml: Converts Turtle files .ttl into plantuml .puml

=head1 SYNOPSIS

rdfpuml [file] [options]

Options:
-help
-infile
-outfile
-prefixfile
-plantumlcfgfile

=over 8

=item B<help>

Brief help message

=item B<infile>

Turtle file to process

=item B<outfile>

Output to this puml file.

=item B<prefixfile>

RDF prefixies to use for URI shortening

=item B<plantumlcfgfile>

plantuml config to add style and layout, etc

=back

=head1 DESCRIPTION

B<This program> will read the input file and translate it into puml

=cut

pod2usage("$0: Missing input filename.\n") unless (@ARGV);

$infile = path( $ARGV[0] );
myprint ("Processing file [$ARGV[0]] \n");

my $sep = File::Spec->catfile('', '');
$outfile = path( $outfile || $infile->parent . $sep . $infile->basename('.ttl') . '.puml' );

$prefixfile = path( $prefixfile || $infile->sibling('prefixes.ttl') );

my $prefixes = $prefixfile->exists ? $prefixfile->slurp_utf8 : "";
my $data = $infile->slurp_utf8;
my $turtle = "$PREFIXES_TURTLE\n$prefixes\n$data";
my $prefixes_all = "$PREFIXES_TURTLE\n$prefixes";
unless ($plantumlcfgfile) {
$plantumlcfgfile = dirname(__FILE__) . $sep . ".." . $sep . "plantuml" . $sep . "plantuml.cfg";
}
my $plantumlcfgfile_path = path( $plantumlcfgfile );
my $plantuml_cfg = $plantumlcfgfile_path->exists ? $plantumlcfgfile_path->slurp_utf8 : "";

open (STDOUT, ">:encoding(UTF-8)", $outfile);
binmode STDERR, ":encoding(UTF-8)";
#print STDERR $turtle; die;

my $store = RDF::Trine::Store::Memory->new();
my $model = RDF::Trine::Model->new($store) or die "can't create model: $!\n";
my $model = RDF::Trine::Model->new($store);
my $parser = RDF::Trine::Parser->new('turtle');
$parser->parse_into_model (undef, $turtle, $model);
my $map = RDF::Prefixes::Curie->new ($prefixes_all);

myprint (<<'EOF');
@startuml
hide empty methods
hide empty attributes
hide circle
skinparam classAttributeIconSize 0
EOF
myprint ("\@startuml\n");
myprint ("$plantuml_cfg\n");

stereotypes();
replace_inlines();
collect_predicate_arrows();

for my $s ($model->subjects(undef,undef)) {
for my $s ( sort { RDF::Trine::Node::compare( $a, $b ) } $model->subjects(undef,undef) ) {
my $s1 = puml_node($s);
my $noReify = print_types ($s, $s1); # types come first
print_relations ($s, $s1, $noReify);
Expand All @@ -133,7 +199,7 @@

sub print_types {
my ($s, $s1) = @_;
my @types = map puml_node2($_), $model->objects ($s, U("rdf:type"));
my @types = sort map puml_node2($_), $model->objects ($s, U("rdf:type"));
my $noReify = grep m{puml:NoReify}, @types;
my $types = join ", ", grep !m{puml:NoReify}, @types;
myprint (qq{$s1 : a $types\n}) if $types;
Expand All @@ -142,7 +208,8 @@ sub print_types {

sub print_relations {
my ($s, $s1, $noReify) = @_;
for my $o ($model->objects ($s, undef, undef, type=>'resource'),
for my $o (sort { RDF::Trine::Node::compare( $a, $b ) }
$model->objects ($s, undef, undef, type=>'resource'),
$model->objects ($s, undef, undef, type=>'blank')) {
# collect all relations between the two nodes.
# TODO: also collect inverse relations? Then be careful for reifications!
Expand Down
10 changes: 10 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: '3'
services:
rdf-puml-generator:
build: .
container_name: rdf-puml-generator
image: rdf-puml-generator
volumes:
- ./ttl:/puml-doc/ttl/
- ./out:/puml-doc/out/
- ./plantuml/plantuml.cfg:/puml-doc/plantuml-cfg/plantuml.cfg
5 changes: 5 additions & 0 deletions docker_build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

docker build -t rdf-puml-gen:latest "${DIR}"
11 changes: 11 additions & 0 deletions docker_run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

docker run \
-it \
-v ${DIR}/ttl:/puml-doc/ttl/ \
-v ${DIR}/out:/puml-doc/out/ \
-v ${DIR}/plantuml/plantuml.cfg:/puml-doc/plantuml-cfg/plantuml.cfg \
rdf-puml-gen:latest \
/bin/bash
File renamed without changes.
3 changes: 3 additions & 0 deletions plantuml/plantuml.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#! /bin/sh -e
GRAPHVIZ_DOT=`which dot`
java -DPLANTUML_LIMIT_SIZE=8192 -jar /puml-doc/plantuml.jar "$@"
71 changes: 71 additions & 0 deletions rdfpuml-docker/MyConfig.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@

$CPAN::Config = {
'applypatch' => q[],
'auto_commit' => q[0],
'build_cache' => q[100],
'build_dir' => q[/root/.cpan/build],
'build_dir_reuse' => q[0],
'build_requires_install_policy' => q[yes],
'bzip2' => q[/bin/bzip2],
'cache_metadata' => q[1],
'check_sigs' => q[0],
'cleanup_after_install' => q[0],
'colorize_output' => q[0],
'commandnumber_in_prompt' => q[1],
'connect_to_internet_ok' => q[1],
'cpan_home' => q[/root/.cpan],
'ftp_passive' => q[1],
'ftp_proxy' => q[],
'getcwd' => q[cwd],
'gpg' => q[/usr/bin/gpg],
'gzip' => q[/bin/gzip],
'halt_on_failure' => q[0],
'histfile' => q[/root/.cpan/histfile],
'histsize' => q[100],
'http_proxy' => q[],
'inactivity_timeout' => q[0],
'index_expire' => q[1],
'inhibit_startup_message' => q[0],
'keep_source_where' => q[/root/.cpan/sources],
'load_module_verbosity' => q[none],
'make' => q[],
'make_arg' => q[],
'make_install_arg' => q[],
'make_install_make_command' => q[],
'makepl_arg' => q[INSTALLDIRS=site],
'mbuild_arg' => q[],
'mbuild_install_arg' => q[],
'mbuild_install_build_command' => q[./Build],
'mbuildpl_arg' => q[--installdirs site],
'no_proxy' => q[],
'pager' => q[/usr/bin/less],
'patch' => q[/usr/bin/patch],
'perl5lib_verbosity' => q[none],
'prefer_external_tar' => q[1],
'prefer_installer' => q[MB],
'prefs_dir' => q[/root/.cpan/prefs],
'prerequisites_policy' => q[follow],
'recommends_policy' => q[1],
'scan_cache' => q[atstart],
'shell' => undef,
'show_unparsable_versions' => q[0],
'show_upload_date' => q[0],
'show_zero_versions' => q[0],
'suggests_policy' => q[0],
'tar' => q[/bin/tar],
'tar_verbosity' => q[none],
'term_is_latin' => q[1],
'term_ornaments' => q[1],
'test_report' => q[0],
'trust_test_report_history' => q[0],
'unzip' => q[],
'urllist' => [q[http://www.cpan.org/]],
'use_prompt_default' => q[0],
'use_sqlite' => q[0],
'version_timeout' => q[15],
'wget' => q[/usr/bin/wget],
'yaml_load_code' => q[0],
'yaml_module' => q[YAML],
};
1;
__END__
Loading