Merge pull request #279 from martinbremmer/merge4

Merge master into security
This commit is contained in:
eboasson 2019-10-22 20:31:12 +02:00 committed by GitHub
commit 5399e5103c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
93 changed files with 7999 additions and 13305 deletions

View file

@ -74,18 +74,36 @@ osx_xcode10_3: &osx_xcode10_3
compiler: clang
addons:
homebrew:
packages:
- pyenv-virtualenv
packages: [ python3 ]
before_install:
- eval "export CC=clang"
- eval "export CXX=clang++"
- eval "export COV_COMPTYPE=clang COV_PLATFORM=macOSX"
- eval "export PATH=\"${PATH}:$(python3 -m site --user-base)/bin\""
install:
- eval "$(pyenv init -)"
- pyenv virtualenv conan
- pyenv rehash
- pyenv activate conan
- pip install conan --upgrade
- pip3 install conan --upgrade --user
osx_xcode9: &osx_xcode9
<<: *osx_xcode10_3
osx_image: xcode9
cache:
directories:
- $HOME/Library/Caches/Homebrew
- /usr/local/Homebrew
addons:
homebrew:
packages: [ python3 ]
# Homebrew must be updated before packages can be installed on outdated
# macOS images. The update process unfortunately takes a VERY long time
# and can even cause Travis to terminate the build. Travis caching is
# used to ensure Homebrew is kept up-to-date and build times are kept to
# a minimum.
update: true
before_cache:
- brew cleanup
- find /usr/local/Homebrew -type d -name .git |
xargs -I {} dirname {} |
xargs -I {} git --git-dir={}/.git --work-tree={} clean -f -d -x
windows_vs2017: &windows_vs2017
os: windows
@ -149,6 +167,8 @@ jobs:
env: [ ARCH=x86_64, ASAN=address, BUILD_TYPE=Debug, SSL=YES, SECURITY=NO, GENERATOR="Unix Makefiles" ]
- <<: *linux_clang
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles" ]
- <<: *osx_xcode9
env: [ ARCH=x86_64, ASAN=none, BUILD_TYPE=Release, SSL=NO, SECURITY=YES, GENERATOR="Unix Makefiles" ]
- <<: *osx_xcode10_3
env: [ ARCH=x86_64, ASAN=address, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, GENERATOR="Unix Makefiles" ]
- <<: *osx_xcode10_3

View file

@ -26,7 +26,6 @@ endif()
# core library is required, there's no need to build them, and that in turn eliminates the Maven and
# JDK dependency.
option(BUILD_IDLC "Build IDL preprocessor" ON)
option(BUILD_CONFTOOL "Build configuration file edit tool" ON)
# By default don't treat warnings as errors, else anyone building it with a different compiler that
# just happens to generate a warning, as well as anyone adding or modifying something and making a

View file

@ -28,10 +28,10 @@ installed, and the rest should already be there. On Windows, installing chocola
install git cmake openjdk maven`` should get you a long way. On macOS, ``brew install maven cmake``
and downloading and installing the JDK is easiest.
The Java-based components are the preprocessor and a configurator tool. The run-time libraries are
pure C code, so there is no need to have Java available on "target" machines. If desired, it is
possible to do a build without Java or Maven installed by defining ``BUILD_IDLC=NO`` and
``BUILD_CONFTOOL=NO``, but that effectively only gets you the core library. For the
The Java-based components are the preprocessor and a configurator tool. The run-time
libraries are pure C code, so there is no need to have Java available on "target"
machines. If desired, it is possible to do a build without Java or Maven installed by
defining ``BUILD_IDLC=NO``, but that effectively only gets you the core library. For the
current [ROS2 RMW layer](https://github.com/ros2/rmw_cyclonedds), that is sufficient.
To obtain Eclipse Cyclone DDS, do
@ -185,6 +185,8 @@ be tweaked by creating an XML file with the desired settings and defining the ``
point to it. E.g. (on Linux):
$ cat cyclonedds.xml
<?xml version="1.0" encoding="UTF-8" ?>
<CycloneDDS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://github.com/eclipse-cyclonedds/cyclonedds/etc/cyclonedds.xsd">
<CycloneDDS>
<Domain id="any">
<General>
@ -231,9 +233,9 @@ This example shows a few things:
has buffered too much unacknowledged data. There is some auto-tuning, the (current) default value
is a bit small to get really high throughput.
The configurator tool ``cycloneddsconf`` can help in discovering the settings, as can the config
dump. Background information on configuring Cyclone DDS can be
found [here](docs/manual/config.rst).
Background information on configuring Cyclone DDS can be found
[here](docs/manual/config.rst) and a list of settings is
[available](docs/manual/options.md).
# Trademarks

1926
cdds.md Normal file

File diff suppressed because it is too large Load diff

676
docs/makernc.pl Normal file
View file

@ -0,0 +1,676 @@
: # -*- perl -*-
eval 'exec perl -w -S $0 "$@"'
if 0;
use strict;
use Data::Dumper;
if (@ARGV != 3) {
print STDERR "usage: $0 input output.md output.rnc\n";
exit 2;
}
my $input = $ARGV[0];
my $output_md = $ARGV[1];
my $output_rnc = $ARGV[2];
# This "perl" script extracts the configuration elements and their types and descriptions
# from the source and generates a RELAX NG Compact Form (RNC) and a MarkDown version of
# it. The scare quotes are necessary because it really is just a translation to perl
# syntax of an old gawk script, originally used for generating input to a half-baked
# Java-based configuration editor.
#
# There are tools out there to convert RNC to, e.g., XSD. RNC has the advantage of being
# understood by Emacs' nXML mode, but more importantly, of being fairly straightforward to
# generate.
#
# In an ideal world it would be a bit less fragile in its parsing of the input, and
# besides one should generate the C code for the configuration tables from a sensible
# source format, rather than try to extract it from the C source.
#
# Other issues:
# - knowledge of conversion functions in here
# - hard definitions of enums in here
# - some other hard-coded knowledge of the top level nodes
#
# INCANTATION
#
# trang is a tool for converting (among other things) RNC to XSD
#
# perl -w ../docs/makernc.pl ../src/core/ddsi/src/q_config.c ../docs/manual/options.md ../etc/cyclonedds.rnc \
# && java -jar trang-20091111/trang.jar -I rnc -O xsd ../etc/cyclonedds.rnc ../etc/cyclonedds.xsd
$|=1;
my $debug = 0;
my %typehint2xmltype =
("____" => "____",
"nop" => "____",
"networkAddress" => "String",
"partitionAddress" => "String",
"networkAddresses" => "String",
"ipv4" => "String",
"boolean" => "Boolean",
"boolean_default" => "Enum",
"string" => "String",
"tracingOutputFileName" => "String",
"verbosity" => "Enum",
"tracemask" => "Comma",
"peer" => "String",
"float" => "Float",
"int" => "Int",
"int32" => "Int",
"uint" => "Int",
"uint32" => "Int",
"natint" => "Int",
"natint_255" => "Int",
"domainId" => "String",
"participantIndex" => "String",
"port" => "Int",
"dyn_port" => "Int",
"duration_inf" => "String",
"duration_ms_1hr" => "String",
"duration_ms_1s" => "String",
"duration_100ms_1hr" => "String",
"duration_us_1s" => "String",
"memsize" => "String",
"bandwidth" => "String",
"standards_conformance" => "Enum",
"locators" => "Enum",
"service_name" => "String",
"sched_class" => "Enum",
"cipher" => "Enum",
"besmode" => "Enum",
"retransmit_merging" => "Enum",
"sched_prio_class" => "Enum",
"sched_class" => "Enum",
"maybe_int32" => "String",
"maybe_memsize" => "String",
"maybe_duration_inf" => "String",
"allow_multicast" => "Comma",
"transport_selector" => "Enum",
"many_sockets_mode" => "Enum",
"xcheck" => "Comma",
"min_tls_version" => "String");
my %typehint2unit =
("duration_inf" => "duration_inf",
"duration_ms_1hr" => "duration",
"duration_100ms_1hr" => "duration",
"duration_ms_1s" => "duration",
"duration_us_1s" => "duration",
"bandwidth" => "bandwidth",
"memsize" => "memsize",
"maybe_memsize" => "memsize",
"maybe_duration_inf" => "duration_inf");
my %enum_values =
("locators" => "local;none",
"standards_conformance" => "lax;strict;pedantic",
"verbosity" => "finest;finer;fine;config;info;warning;severe;none",
"besmode" => "full;writers;minimal",
"retransmit_merging" => "never;adaptive;always",
"sched_prio_class" => "relative;absolute",
"sched_class" => "realtime;timeshare;default",
"cipher" => "null;blowfish;aes128;aes192;aes256",
"boolean_default" => "false;true;default",
"many_sockets_mode" => "false;true;single;none;many",
"transport_selector" => "default;udp;udp6;tcp;tcp6;raweth");
# should extrace these from the source ...
my %comma_values =
("tracemask" => "|fatal;error;warning;info;config;discovery;data;radmin;timing;traffic;topic;tcp;plist;whc;throttle;rhc;content;trace",
"allow_multicast" => "default|false;spdp;asm;ssm;true",
"xcheck" => "|whc;rhc;all");
my %range =
("port" => "1;65535",
"dyn_port" => "-1;65535",
"general_cfgelems/startupmodeduration" => "0;60000",
"natint_255" => "0;255",
"duration_ms_1hr" => "0;1hr",
"duration_100ms_1hr" => "100ms;1hr",
"duration_ms_1s" => "0;1s",
"duration_us_1s" => "0;1s");
my %unit_blurb =
("bandwidth" => "\n<p>The unit must be specified explicitly. Recognised units: <i>X</i>b/s, <i>X</i>bps for bits/s or <i>X</i>B/s, <i>X</i>Bps for bytes/s; where <i>X</i> is an optional prefix: k for 10<sup>3</sup>, Ki for 2<sup>10</sup>, M for 10<sup>6</sup>, Mi for 2<sup>20</sup>, G for 10<sup>9</sup>, Gi for 2<sup>30</sup>.</p>",
"memsize" => "\n<p>The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2<sup>10</sup> bytes), MB & MiB (2<sup>20</sup> bytes), GB & GiB (2<sup>30</sup> bytes).</p>",
"duration" => "\n<p>The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.</p>",
"duration_inf" => "\n<p>Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.</p>");
my %unit_patterns =
("memsize" => '0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([kMG]i?)?B',
"bandwidth" => '0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([kMG]i?)?[Bb][p/]s',
"duration" => '0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([num]?s|min|hr|day)',
"duration_inf" => 'inf|0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([num]?s|min|hr|day)');
while (my ($k, $v) = each %typehint2xmltype) {
die "script error: values of enum type $k unknown\n" if $v eq "Enum" && $enum_values{$k} eq "";
}
my %elem;
my %typehint_seen;
my %tables;
my @root = read_config ($input);
{
open my $fh, ">", "$output_rnc" or die "can't open $output_rnc";
print $fh "namespace a = \"http://relaxng.org/ns/compatibility/annotations/1.0\"\n";
print $fh "grammar {\n";
print $fh " start =\n";
my $isfirst = 1;
conv_table($fh, \&conv_to_rnc, \@root, "/", " ", "", \$isfirst);
for (sort keys %unit_patterns) {
printf $fh " %s = xsd:token { pattern = \"%s\" }\n", $_, $unit_patterns{$_};
}
print $fh "}\n";
close $fh;
}
{
open my $fh, ">", "$output_md" or die "can't open $output_md";
my $sep_blurb = "";
conv_table($fh, \&conv_to_md, \@root, "/", " ", "", \$sep_blurb);
close $fh;
}
exit 0;
sub clean_description {
my ($desc) = @_;
$desc =~ s/^\s*BLURB\s*\(\s*//s;
$desc =~ s/^\s*"//s;
$desc =~ s/\s*"(\s*\))? *(\}\s*,\s*$)?$//s;
$desc =~ s/\\"/"/g;
$desc =~ s/\\n\s*\\/\n/g;
$desc =~ s/\\\\/\\/g;
$desc =~ s/\n\n/\n/g;
# should fix the source ...
$desc =~ s/DDSI2E?/Cyclone DDS/g;
return $desc;
}
sub html_to_md {
my ($desc) = @_;
$desc =~ s/^\<\/p\>//gs;
$desc =~ s/\<\/p\>//gs;
$desc =~ s/<sup>/^/s;
$desc =~ s/<\/sup>//s;
$desc =~ s/\<p\>/\n\n/gs;
$desc =~ s/\<\/?(i|ul)\>//gs;
$desc =~ s/\<li\>(.*?)\<\/li\>\n*/* $1\n/gs;
$desc =~ s/&quot;/"/gs;
$desc =~ s/\n+/\n/gs;
$desc =~ s/^\n*//s;
return $desc;
}
sub kind_to_kstr {
my ($kind, $typehint, $table, $name) = @_;
if ($kind eq "GROUP" || $kind eq "MGROUP") {
return "element";
} elsif ($kind eq "ATTR") {
return "$typehint2xmltype{$typehint}";
} elsif ($kind eq "LEAF") {
return "$typehint2xmltype{$typehint}";
} else {
die "error: $kind unrecognized kind ($table/$name)\n";
}
}
sub store_entry {
my ($name, $table, $kind, $subtables, $multiplicity, $defaultvalue, $typehint, $description) = @_;
$name =~ s/\|.*//; # aliases are not visible in osplconf
my $ltable = lc $table;
my $lname = lc $name;
die "error: no mapping defined for type $typehint\n" if $typehint2xmltype{$typehint} eq "";
my $ub = exists $typehint2unit{$typehint} && exists $unit_blurb{$typehint2unit{$typehint}} ? $unit_blurb{$typehint2unit{$typehint}} : "";
if ($kind eq "GROUP" || $kind eq "MGROUP") {
# GROUP and MGROUP have no data, so also no default value
$defaultvalue = undef;
} elsif ($defaultvalue eq "" || $defaultvalue eq "NULL") {
$defaultvalue = undef;
} else {
$defaultvalue =~ s/^"(.*)"$/$1/;
}
my ($min_occ, $max_occ);
if ($multiplicity =~ /MAX/) {
$min_occ = $max_occ = 0;
} elsif ($multiplicity == 0 || $multiplicity == 1) {
# multiplicity = 0 => special case, treat as-if 1
# multiplicity = 1 => required if no default
if ($kind eq "GROUP" || $kind eq "MGROUP") {
$min_occ = 0;
} elsif (not defined $defaultvalue) {
$min_occ = 1;
} else {
$min_occ = 0;
}
$max_occ = 1;
} else {
$min_occ = 0; $max_occ = $multiplicity;
}
my $kstr = kind_to_kstr($kind, $typehint, $table, $name);
my $desc = clean_description($description).$ub;
$desc .= "<p>The default value is: &quot;$defaultvalue&quot;.</p>" if defined $defaultvalue;
my $fs;
push @{$tables{$table}}, { table => $table, name => $name,
kind => $kind, kstr => $kstr,
subtables => $subtables, multiplicity => $multiplicity,
min_occ => $min_occ, max_occ => $max_occ, root => 0,
defaultvalue => $defaultvalue, typehint => $typehint,
description => $desc };
# typehint_seen is for verifying no bogus type hints are defined in this script
$typehint_seen{$typehint} = 1;
}
sub fmtblurb {
my ($blurb) = @_;
my $isbullet = ($blurb =~ s/^\* //);
my $maxlen = $isbullet ? 78 : 74;
my @words = split ' ', $blurb;
my @lines = ();
while (@words > 0) {
my $x = shift @words;
while (@words > 0 && (length $x) + 1 + (length $words[0]) < $maxlen) {
$x .= " " . shift @words;
}
push @lines, "$x";
}
my $sep = "\n" . ($isbullet ? " " : "");
return ($isbullet ? "* " : "") . join $sep, @lines;
}
sub print_description_rnc {
my ($fh, $desc, $indent) = @_;
my $x = $desc;
my @xs = split /\n+/, $x;
$_ = fmtblurb ($_) for @xs;
$x = join "\n\n", @xs;
return 0 if $x =~ /^\s$/s;
print $fh "[ a:documentation [ xml:lang=\"en\" \"\"\"\n$x\"\"\" ] ]\n";
return 1;
}
sub print_description_md {
my ($fh, $desc, $indent) = @_;
my $x = html_to_md ($desc);
my @xs = split /\n+/, $x;
$_ = fmtblurb ($_) for @xs;
$x = join "\n\n", @xs;
return 0 if $x =~ /^\s$/s;
print $fh "$x\n";
return 1;
}
sub conv_to_rnc {
my ($fh, $fs, $name, $fqname, $indent, $prefix, $isfirstref) = @_;
printf $fh "${indent}%s", ($$isfirstref ? "" : "& ");
print_description_rnc ($fh, $fs->{description}, $indent);
printf $fh "${indent}%s %s {\n", ($fs->{kind} eq "ATTR" ? "attribute" : "element"), $name;
if ($fs->{kind} eq "GROUP" || $fs->{kind} eq "MGROUP") {
my $sub_isfirst = 1;
conv_table($fh, \&conv_to_rnc, $fs->{subtables}, $fqname, "${indent} ", $prefix, \$sub_isfirst);
printf $fh "${indent} empty\n" if $sub_isfirst;
} elsif ($fs->{kstr} eq "Boolean") {
printf $fh "${indent} xsd:boolean\n";
} elsif ($fs->{kstr} eq "Comma") {
die unless exists $comma_values{$fs->{typehint}};
my $pat = "";
my @xs = split /\|/, $comma_values{$fs->{typehint}};
my $allowempty = 0;
for (@xs) {
if ($_ eq "") { $allowempty = 1; next; }
(my $vs = $_) =~ s/;/|/g;
$pat .= "|" unless $pat eq "";
if ($vs =~ /\|/) {
$pat .= "(($vs)(,($vs))*)";
} else {
$pat .= $vs;
}
}
$pat .= "|" if $allowempty;
printf $fh "${indent} xsd:token { pattern = \"%s\" }\n", $pat;
} elsif ($fs->{kstr} eq "Enum") {
die unless exists $enum_values{$fs->{typehint}};
my @vs = split /;/, $enum_values{$fs->{typehint}};
printf $fh "${indent} %s\n", (join '|', map { "\"$_\"" } @vs);
} elsif ($fs->{kstr} eq "Int") {
printf $fh "${indent} xsd:integer\n";
#if (exists $range{$lctn} || exists $range{$fs->{typehint}}) {
# # integer with range
# my $rr = exists $range{$lctn} ? $range{$lctn} : $range{$fs->{typehint}};
# my @vs = split /;/, $range{$lctn};
#}
} elsif ($typehint2unit{$fs->{typehint}}) {
# number with unit
printf $fh "${indent} $typehint2unit{$fs->{typehint}}\n";
} elsif ($typehint2xmltype{$fs->{typehint}} =~ /String$/) {
printf $fh "${indent} text\n";
} else {
die;
}
my $suffix;
if ($fs->{min_occ} == 0) {
$suffix = ($fs->{max_occ} == 1) ? "?" : "*";
} else {
$suffix = ($fs->{max_occ} == 1) ? "" : "+";
}
printf $fh "${indent}}%s\n", $suffix;
$$isfirstref = 0;
}
sub list_children_md {
my ($fh, $fs, $name, $fqname, $indent, $prefix, $children) = @_;
if ($fs->{kind} eq "ATTR") {
push @{$children->{attributes}}, $name;
} else {
push @{$children->{elements}}, $name;
}
}
sub conv_to_md {
my ($fh, $fs, $name, $fqname, $indent, $prefix, $separator_blurb_ref) = @_;
print $fh $$separator_blurb_ref;
$$separator_blurb_ref = "\n\n";
# Print fully-qualified element/attribute name as a heading, with the heading level
# determined by the nesting level. The nesting level can be computed from the number of
# slashes :)
(my $slashes = $fqname) =~ s/[^\/]//g;
die unless length $slashes >= 2;
my $level = (length $slashes) - 1;
printf $fh "%s $fqname\n", ("#"x$level);
# Describe type (boolean, integer, &c.); for a group list its attributes and children as
# links to their descriptions
if ($fs->{kind} eq "GROUP" || $fs->{kind} eq "MGROUP") {
my %children = ("attributes" => [], "elements" => []);
conv_table($fh, \&list_children_md, $fs->{subtables}, "", "${indent} ", $prefix, \%children);
if (@{$children{attributes}} > 0) {
my @xs = sort @{$children{attributes}};
my @ys = map { my $lt = lc "$fqname\[\@$_]"; $lt =~ s/[^a-z0-9]//g; "[$_](#$lt)" } @xs;
printf $fh "Attributes: %s\n\n", (join ', ', @ys);
}
if (@{$children{elements}} > 0) {
my @xs = sort @{$children{elements}};
my @ys = map { my $lt = lc "$fqname\[\@$_]"; $lt =~ s/[^a-z0-9]//g; "[$_](#$lt)" } @xs;
printf $fh "Children: %s\n\n", (join ', ', @ys);
}
} elsif ($fs->{kstr} eq "Boolean") {
printf $fh "Boolean\n";
} elsif ($fs->{kstr} eq "Comma") {
die unless exists $comma_values{$fs->{typehint}};
my $pat = "";
my @xs = split /\|/, $comma_values{$fs->{typehint}};
if (@xs > 1) {
printf $fh "One of:\n";
}
my $allowempty = 0;
for (@xs) {
if ($_ eq "") { $allowempty = 1; next; }
my @vs = split /;/, $_;
if (@vs > 1) {
printf $fh "* Comma-separated list of: %s\n", (join ', ', @vs);
} else {
printf $fh "* Keyword: %s\n", $vs[0];
}
}
printf $fh "* Or empty\n" if $allowempty;
} elsif ($fs->{kstr} eq "Enum") {
die unless exists $enum_values{$fs->{typehint}};
my @vs = split /;/, $enum_values{$fs->{typehint}};
printf $fh "One of: %s\n", (join ', ', @vs);
} elsif ($fs->{kstr} eq "Int") {
printf $fh "Integer\n";
#if (exists $range{$lctn} || exists $range{$fs->{typehint}}) {
# # integer with range
# my $rr = exists $range{$lctn} ? $range{$lctn} : $range{$fs->{typehint}};
# my @vs = split /;/, $range{$lctn};
#}
} elsif ($typehint2unit{$fs->{typehint}}) {
# number with unit
printf $fh "Number-with-unit\n";
} elsif ($typehint2xmltype{$fs->{typehint}} =~ /String$/) {
printf $fh "Text\n";
} else {
die;
}
# Descriptive text
printf $fh "\n";
print_description_md ($fh, $fs->{description}, $indent);
# Generate attributes & children
if ($fs->{kind} eq "GROUP" || $fs->{kind} eq "MGROUP") {
conv_table($fh, \&conv_to_md, $fs->{subtables}, $fqname, "${indent} ", $prefix, $separator_blurb_ref);
}
}
sub conv_table {
my ($fh, $convsub, $tablenames, $fqname, $indent, $prefix, $closure) = @_;
my $elems = 0;
for (@$tablenames) {
next unless exists $tables{$_};
for my $fs (sort { $a->{name} cmp $b->{name} } @{$tables{$_}}) {
my $fqname1;
if ($fs->{kind} eq "ATTR") {
die unless $elems == 0;
$fqname1 = "${fqname}[\@$fs->{name}]";
} else {
$fqname1 = "$fqname/$fs->{name}";
$elems++;
}
my $prefix1 = ($fs->{table} eq "unsupp_cfgelems") ? "<b>Internal</b>" : $prefix;
&$convsub ($fh, $fs, $fs->{name}, $fqname1, $indent, $prefix1, $closure);
}
}
}
sub read_config {
my %incl = (# included options
'DDSI_INCLUDE_SSL' => 1,
'DDSI_INCLUDE_NETWORK_PARTITIONS' => 1,
'DDSI_INCLUDE_SSM' => 1,
# excluded options
'DDSI_INCLUDE_NETWORK_CHANNELS' => 0,
'DDSI_INCLUDE_BANDWIDTH_LIMITING' => 0);
my ($input) = @_;
my ($name, $table, $kind, @subtables, $multiplicity, $defaultvalue, $typehint, $description);
my ($gobbling_description, $in_table, $rest, $deprecated);
my @stk = (); # stack of conditional nesting, for each: copy/discard/ignore
open FH, "<", $input or die "can't open $input\n";
while (<FH>) {
chomp;
# ignore parts guarded by #if/#ifdef/#if!/#ifndef if $incl says so
if (/^\s*\#\s*if(n?def|\s*!)?\s*([A-Za-z_][A-Za-z_0-9]*)\s*(?:\/(?:\/.*|\*.*?\*\/)\s*)?$/) {
my $x = (not defined $1 || $1 eq "def") ? -1 : 1; my $var = $2;
die if $var =~ /^DDSI_INCLUDE_/ && !exists $incl{$var};
push @stk, (not defined $incl{$var}) ? 0 : $incl{$var} ? $x : -$x;
} elsif (/^\s*\#\s*if/) { # ignore any other conditional
push @stk, 0;
} elsif (/^\s*\#\s*else/) {
$stk[$#stk] = -$stk[$#stk];
} elsif (/^\s*\#\s*endif/) {
pop @stk;
}
next if grep {$_ < 0} @stk;
if ($gobbling_description) {
$description .= $_;
#print " .. $_\n";
}
if ($gobbling_description && /(^|")(\s*\)) *\} *, *$/) {
$gobbling_description = 0;
my @st = @subtables;
store_entry ($name, $table, $kind, \@st, $multiplicity, $defaultvalue, $typehint, $description)
unless $deprecated;
next;
}
if ($gobbling_description) {
next;
}
if (/^[ \t]*(#[ \t]*(if|ifdef|ifndef|else|endif).*)?$/) { # skip empty lines, preproc
next;
}
if (/^ *END_MARKER *$/) {
if (!$in_table) {
warn "END_MARKER seen while not in a table";
}
$in_table = 0;
print "END_MARKER $table\n" if $debug;
next;
}
if (/^static +const +struct +cfgelem +([A-Za-z_0-9]+)\s*\[/) {
$in_table = 1;
$table = $1;
print "TABLE $table\n" if $debug;
next;
}
if ($in_table && /^ *WILDCARD *, *$|^ *\{ *(MOVED) *\(/) {
next;
}
# Recognise all "normal" entries: attributes, groups, leaves and
# leaves with attributes. This doesn't recognise the ones used for the
# root groups: those are dealt with by the next pattern
if ($in_table && /^ *\{ *((?:DEPRECATED_)?(?:ATTR|GROUP|GROUP_W_ATTRS|MGROUP|LEAF|LEAF_W_ATTRS)) *\(/) {
$rest = $_;
# extract kind
$rest =~ s/^ *\{ *((?:DEPRECATED_)?(?:ATTR|GROUP|GROUP_W_ATTRS|MGROUP|LEAF|LEAF_W_ATTRS)) *\( *(.*)/$2/;
$kind = $1;
$deprecated = ($kind =~ s/^DEPRECATED_//);
# extract name + reference to subtables
$rest =~ s/\"([A-Za-z_0-9|]+)\" *(.*)/$2/;
$name = $1;
my ($subelems, $subattrs) = ("", "");
if ($kind eq "GROUP" || $kind eq "GROUP_W_ATTRS" || $kind eq "MGROUP") {
$rest =~ s/, *([A-Za-z_0-9]+) *(.*)/$2/;
$subelems = $1;
}
if ($kind eq "LEAF_W_ATTRS" || $kind eq "GROUP_W_ATTRS" || $kind eq "MGROUP") {
$rest =~ s/, *([A-Za-z_0-9]+) *(.*)/$2/;
$subattrs = $1;
}
@subtables = ();
push @subtables, $subattrs if $subattrs ne "";
push @subtables, $subelems if $subelems ne "";
$rest =~ s/ *\) *, *//;
print " kind $kind name $name subtables @subtables -- $rest\n" if $debug;
# don't care about the distinction between GROUP/LEAF and
# GROUP/LEAF_W_ATTRS in the remainer of the code: we simply
# rely on subtables.
$kind =~ s/_W_ATTRS//;
}
# Root groups: use a special trick, which allows them to do groups
# with attributes. Which the DDSI2 proper doesn't use, but which the
# service configuration stuff does rely on.
if ($in_table && /^ *\{ *"([A-Za-z_0-9|]+)" *, */) {
$rest = $_;
# root elements are all groups, formatted as: <name>, <subelems>,
# <attrs>, NODATA, description. They're therefore pretty easy to
# parse.
$kind = "GROUP";
$rest =~ s/^ *\{ *\"([A-Za-z_0-9|]+)\" *, *(.*)/$2/;
$name = $1;
# then follow the sub-elements and the attributes
$rest =~ s/([A-Za-z_0-9]+) *, *(.*)/$2/;
my $subelems = $1;
$rest =~ s/([A-Za-z_0-9]+) *, *(.*)/$2/;
my $subattrs = $1;
# then we require NODATA (could do this in the pattern also)
die "error: NODATA expected" unless $rest =~ /^NODATA *,/;
# multiplicity is hard coded: we want to allow multiple ddsi2 services
$multiplicity = 0;
@subtables = ();
push @subtables, $subattrs if $subattrs ne "";
push @subtables, $subelems if $subelems ne "";
$rest =~ s/([A-Za-z_0-9]+) *, *(.*)/$2/;
}
# Extract stuff specific to ATTRs, LEAFs and MGROUPs
if ($in_table && ($kind eq "ATTR" || $kind eq "LEAF" || $kind eq "MGROUP")) {
# extract multiplicity
$rest =~ s/([0-9]+|U?INT(?:16|32|64)?_MAX) *, *(.*)/$2/;
$multiplicity = $1;
# extract default value
$rest =~ s/(\"(?:[^\"]*)\"|NULL|0) *, *(.*)/$2/;
$defaultvalue = $1;
if ($defaultvalue eq "0") {
$defaultvalue = "NULL";
}
# skip reference to internal name (either ABSOFF(field),
# RELOFF(field,field) or <int>,<int> (the latter being used by
# "verbosity")
$rest =~ s/(ABSOFF *\( *[A-Za-z_0-9.]+ *\)|RELOFF *\( *[A-Za-z_0-9.]+ *, *[A-Za-z_0-9]+ *\)|[0-9]+ *, *[0-9]+) *, *//;
# skip init function
$rest =~ s/([A-Za-z_0-9]+|0) *, *//;
# type hint from conversion function
$rest =~ s/(uf_(?:[A-Za-z_0-9]+)|NULL|0) *, *(.*)/$2/;
$typehint = $1;
$typehint =~ s/^uf_//;
# accept typehint = NULL for a LEAF_WITH_ATTRS: there is no defined
# "syntax" for groups that have only attributes, pretending it is a
# group because that causes us to emit an "element" and not a
# "leaf".
if ($typehint eq "0" || $typehint eq "NULL") {
$kind = "GROUP";
$typehint = "____";
}
# skip free, print functions
$rest =~ s/([A-Za-z_0-9]+|0) *, *([A-Za-z_0-9]+|0) *, *//;
#print " .. multiplicity $multiplicity default $defaultvalue typehint $typehint\n";
}
# Extract description (or NULL, if not to be included in the configurator XML)
if ($in_table) {
#print " .. $rest\n";
# description or NULL
if ($rest =~ /NULL *\} *, *$/) {
# no description - discard this one/simply continue with next one
} elsif ($rest =~ /(?:BLURB\s*\(\s*)?(".*")(?:\s*\))? *\} *, *$/) {
# description ending on same line
$description = $1;
my @st = @subtables;
store_entry ($name, $table, $kind, \@st, $multiplicity, $defaultvalue, $typehint, $description)
unless $deprecated;
} else {
# strip the quotes &c. once the full text has been gathered
$description = $rest;
$gobbling_description = 1;
}
#print " .. gobbling $gobbling_description";
next;
}
}
close FH;
my @roots = @{$tables{cyclonedds_root_cfgelems}};
die "error: cyclonedds_root_cfgelems has no or multiple entries\n" if @roots != 1;
die "error: root_cfgelems doesn't exist\n" unless exists $tables{root_cfgelems};
my $root = $roots[0];
die "error: root_cfgelems doesn't exist\n" unless defined $root;
$root->{min_occ} = $root->{max_occ} = $root->{isroot} = 1;
while (my ($k, $v) = each %typehint_seen) {
warn "script warning: type mapping defined for $k but not used" if $v == 0;
}
return ("cyclonedds_root_cfgelems");
}

1716
docs/manual/options.md Normal file

File diff suppressed because it is too large Load diff

1397
etc/cyclonedds.rnc Normal file

File diff suppressed because it is too large Load diff

1886
etc/cyclonedds.xsd Normal file

File diff suppressed because it is too large Load diff

View file

@ -51,7 +51,6 @@ static const ddsrt_avl_treedef_t dds_domaintree_def = DDSRT_AVL_TREEDEF_INITIALI
static dds_return_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_id, const char *config)
{
dds_return_t ret = DDS_RETCODE_OK;
char * uri = NULL;
uint32_t len;
dds_entity_t domain_handle;
@ -90,7 +89,7 @@ static dds_return_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i
domain->cfgst = config_init (config, &domain->gv.config, domain_id);
if (domain->cfgst == NULL)
{
DDS_ILOG (DDS_LC_CONFIG, domain_id, "Failed to parse configuration XML file %s\n", uri);
DDS_ILOG (DDS_LC_CONFIG, domain_id, "Failed to parse configuration\n");
ret = DDS_RETCODE_ERROR;
goto fail_config;
}

View file

@ -47,7 +47,6 @@ PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src"
q_qosmatch.c
q_radmin.c
q_receive.c
q_security.c
q_sockwaitset.c
q_thread.c
q_time.c
@ -106,7 +105,6 @@ PREPEND(hdrs_private_ddsi "${CMAKE_CURRENT_LIST_DIR}/include/dds/ddsi"
q_radmin.h
q_receive.h
q_rtps.h
q_security.h
q_sockwaitset.h
q_thread.h
q_time.h

View file

@ -21,12 +21,7 @@ extern "C" {
#endif
struct ddsi_iid {
#if DDSRT_ATOMIC64_SUPPORT
ddsrt_atomic_uint64_t counter;
#else
ddsrt_mutex_t lock;
uint64_t counter;
#endif
uint32_t key[4];
};

View file

@ -14,9 +14,6 @@
#include "dds/ddsi/q_log.h"
#include "dds/ddsi/q_thread.h"
#ifdef DDSI_INCLUDE_ENCRYPTION
#include "dds/ddsi/q_security.h"
#endif /* DDSI_INCLUDE_ENCRYPTION */
#include "dds/ddsi/q_xqos.h"
#include "dds/ddsi/q_feature_check.h"
@ -73,34 +70,6 @@ struct config_listelem {
struct config_listelem *next;
};
#ifdef DDSI_INCLUDE_ENCRYPTION
struct q_security_plugins
{
c_bool (*encode) (q_securityEncoderSet, uint32_t, void *, uint32_t, uint32_t *);
c_bool (*decode) (q_securityDecoderSet, void *, size_t, size_t *);
q_securityEncoderSet (*new_encoder) (void);
q_securityDecoderSet (*new_decoder) (void);
c_bool (*free_encoder) (q_securityEncoderSet);
c_bool (*free_decoder) (q_securityDecoderSet);
ssize_t (*send_encoded) (ddsi_tran_conn_t, const nn_locator_t *dst, size_t niov, ddsrt_iovec_t *iov, q_securityEncoderSet *, uint32_t, uint32_t);
char * (*cipher_type) (q_cipherType);
c_bool (*cipher_type_from_string) (const char *, q_cipherType *);
uint32_t (*header_size) (q_securityEncoderSet, uint32_t);
q_cipherType (*encoder_type) (q_securityEncoderSet, uint32_t);
c_bool (*valid_uri) (q_cipherType, const char *);
};
struct q_security_plugins q_security_plugin;
struct config_securityprofile_listelem
{
struct config_securityprofile_listelem *next;
char *name;
q_cipherType cipher;
char *key;
};
#endif /* DDSI_INCLUDE_ENCRYPTION */
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
struct config_networkpartition_listelem {
struct config_networkpartition_listelem *next;
@ -108,10 +77,6 @@ struct config_networkpartition_listelem {
char *address_string;
struct addrset *as;
int connected;
#ifdef DDSI_INCLUDE_ENCRYPTION
char *profileName;
struct config_securityprofile_listelem *securityProfile;
#endif /* DDSI_INCLUDE_ENCRYPTION */
uint32_t partitionHash;
uint32_t partitionId;
};
@ -346,9 +311,6 @@ struct config
struct config_channel_listelem *channels;
struct config_channel_listelem *max_channel; /* channel with highest prio; always computed */
#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */
#ifdef DDSI_INCLUDE_ENCRYPTION
struct config_securityprofile_listelem *securityProfiles;
#endif /* DDSI_INCLUDE_ENCRYPTION */
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
struct config_networkpartition_listelem *networkPartitions;
unsigned nof_networkPartitions;

View file

@ -203,28 +203,7 @@ enum writer_state {
WRST_DELETING /* writer is actually being deleted (removed from hash table) */
};
#if DDSRT_ATOMIC64_SUPPORT
typedef ddsrt_atomic_uint64_t seq_xmit_t;
#define INIT_SEQ_XMIT(wr, v) ddsrt_atomic_st64(&(wr)->seq_xmit, (uint64_t) (v))
#define READ_SEQ_XMIT(wr) ((seqno_t) ddsrt_atomic_ld64(&(wr)->seq_xmit))
#define UPDATE_SEQ_XMIT_LOCKED(wr, nv) do { uint64_t ov_; do { \
ov_ = ddsrt_atomic_ld64(&(wr)->seq_xmit); \
if ((uint64_t) nv <= ov_) break; \
} while (!ddsrt_atomic_cas64(&(wr)->seq_xmit, ov_, (uint64_t) nv)); } while (0)
#define UPDATE_SEQ_XMIT_UNLOCKED(sx, nv) UPDATE_SEQ_XMIT_LOCKED(sx, nv)
#else
typedef seqno_t seq_xmit_t;
#define INIT_SEQ_XMIT(wr, v) ((wr)->seq_xmit = (v))
#define READ_SEQ_XMIT(wr) ((wr)->seq_xmit)
#define UPDATE_SEQ_XMIT_LOCKED(wr, nv) do { \
if ((nv) > (wr)->seq_xmit) { (wr)->seq_xmit = (nv); } \
} while (0)
#define UPDATE_SEQ_XMIT_UNLOCKED(wr, nv) do { \
ddsrt_mutex_lock (&(wr)->e.lock); \
if ((nv) > (wr)->seq_xmit) { (wr)->seq_xmit = (nv); } \
ddsrt_mutex_unlock (&(wr)->e.lock); \
} while (0)
#endif
struct writer
{
@ -276,6 +255,18 @@ struct writer
struct local_reader_ary rdary; /* LOCAL readers for fast-pathing; if not fast-pathed, fall back to scanning local_readers */
};
inline seqno_t writer_read_seq_xmit (const struct writer *wr) {
return (seqno_t) ddsrt_atomic_ld64 (&wr->seq_xmit);
}
inline void writer_update_seq_xmit (struct writer *wr, seqno_t nv) {
uint64_t ov;
do {
ov = ddsrt_atomic_ld64 (&wr->seq_xmit);
if ((uint64_t) nv <= ov) break;
} while (!ddsrt_atomic_cas64 (&wr->seq_xmit, ov, (uint64_t) nv));
}
struct reader
{
struct entity_common e;

View file

@ -11,9 +11,6 @@
*/
/* Feature macros:
- ENCRYPTION: support for encryption
requires: NETWORK_PARTITIONS
- SSM: support for source-specific multicast
requires: NETWORK_PARTIITONS
also requires platform support; SSM is silently disabled if the
@ -31,12 +28,6 @@
*/
#ifdef DDSI_INCLUDE_ENCRYPTION
#ifndef DDSI_INCLUDE_NETWORK_PARTITIONS
#error "ENCRYPTION requires NETWORK_PARTITIONS"
#endif
#endif
#ifdef DDSI_INCLUDE_SSM
#ifndef DDSI_INCLUDE_NETWORK_PARTITIONS
#error "SSM requires NETWORK_PARTITIONS"

View file

@ -26,10 +26,6 @@
#include "dds/ddsi/q_sockwaitset.h"
#include "dds/ddsi/q_config.h"
#ifdef DDSI_INCLUDE_ENCRYPTION
#include "dds/ddsi/q_security.h" /* for q_securityDecoderSet */
#endif /* DDSI_INCLUDE_ENCRYPTION */
#if defined (__cplusplus)
extern "C" {
#endif
@ -288,13 +284,6 @@ struct q_globals {
int sendq_stop;
struct thread_state1 *sendq_ts;
#ifdef DDSI_INCLUDE_ENCRYPTION
/* Codecs needed for decoding incoming encrypted messages
FIXME: should be a property of the receiver thread, and pass down
while processing messages. For now made global */
q_securityDecoderSet recvSecurityCodec;
#endif /* DDSI_INCLUDE_ENCRYPTION */
/* File for dumping captured packets, NULL if disabled */
FILE *pcap_fp;
ddsrt_mutex_t pcap_lock;

View file

@ -1,46 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#ifdef DDSI_INCLUDE_ENCRYPTION
#ifndef Q_SECURITY_H
#define Q_SECURITY_H
#include "c_typebase.h"
#if defined (__cplusplus)
extern "C" {
#endif
/* Generic class */
C_CLASS(q_securityEncoderSet);
C_CLASS(q_securityDecoderSet);
/* Set of supported ciphers */
typedef enum
{
Q_CIPHER_UNDEFINED,
Q_CIPHER_NULL,
Q_CIPHER_BLOWFISH,
Q_CIPHER_AES128,
Q_CIPHER_AES192,
Q_CIPHER_AES256,
Q_CIPHER_NONE,
Q_CIPHER_MAX
} q_cipherType;
void ddsi_security_plugin (void);
#if defined (__cplusplus)
}
#endif
#endif
#endif

View file

@ -15,7 +15,7 @@
#include "dds/ddsrt/sync.h"
#include "dds/ddsi/ddsi_iid.h"
static struct ddsi_iid dds_iid;
static struct ddsi_iid ddsi_iid;
static void dds_tea_encrypt (uint32_t v[2], const uint32_t k[4])
{
@ -48,16 +48,8 @@ uint64_t ddsi_iid_gen (void)
{
uint64_t iid;
union { uint64_t u64; uint32_t u32[2]; } tmp;
#if DDSRT_ATOMIC64_SUPPORT
tmp.u64 = ddsrt_atomic_inc64_nv (&dds_iid.counter);
#else
ddsrt_mutex_lock (&dds_iid.lock);
tmp.u64 = ++dds_iid.counter;
ddsrt_mutex_unlock (&dds_iid.lock);
#endif
dds_tea_encrypt (tmp.u32, dds_iid.key);
tmp.u64 = ddsrt_atomic_inc64_nv (&ddsi_iid.counter);
dds_tea_encrypt (tmp.u32, ddsi_iid.key);
iid = tmp.u64;
return iid;
}
@ -65,26 +57,14 @@ uint64_t ddsi_iid_gen (void)
void ddsi_iid_init (void)
{
union { uint64_t u64; uint32_t u32[2]; } tmp;
#if ! DDSRT_ATOMIC64_SUPPORT
ddsrt_mutex_init (&dds_iid.lock);
#endif
for (size_t i = 0; i < sizeof (dds_iid.key) / sizeof (dds_iid.key[0]); i++)
dds_iid.key[0] = ddsrt_random ();
for (size_t i = 0; i < sizeof (ddsi_iid.key) / sizeof (ddsi_iid.key[0]); i++)
ddsi_iid.key[i] = ddsrt_random ();
tmp.u64 = 0;
dds_tea_decrypt (tmp.u32, dds_iid.key);
#if DDSRT_ATOMIC64_SUPPORT
ddsrt_atomic_st64 (&dds_iid.counter, tmp.u64);
#else
dds_iid.counter = tmp.u64;
#endif
dds_tea_decrypt (tmp.u32, ddsi_iid.key);
ddsrt_atomic_st64 (&ddsi_iid.counter, tmp.u64);
}
void ddsi_iid_fini (void)
{
#if ! DDSRT_ATOMIC64_SUPPORT
ddsrt_mutex_destroy (&dds_iid.lock);
#endif
}

View file

@ -52,10 +52,6 @@ typedef enum update_result (*update_fun_t) (struct cfgst *cfgst, void *parent, s
typedef void (*free_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem);
typedef void (*print_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources);
#ifdef DDSI_INCLUDE_ENCRYPTION
struct q_security_plugins q_security_plugin = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
#endif
struct unit {
const char *name;
int64_t multiplier;
@ -120,6 +116,10 @@ struct cfgst {
been inserted */
enum implicit_toplevel implicit_toplevel;
/* Whether unique prefix matching on a name is allowed (again for environment
variables) */
bool partial_match_allowed;
/* current input, mask with 1 bit set */
uint32_t source;
@ -142,7 +142,7 @@ static const ddsrt_avl_treedef_t cfgst_found_treedef =
#define DU(fname) static enum update_result uf_##fname (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value)
#define PF(fname) static void pf_##fname (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
#define DUPF(fname) DU(fname) ; PF(fname)
PF(nop);
DUPF(nop);
DUPF(networkAddress);
DUPF(networkAddresses);
DU(ipv4);
@ -181,9 +181,6 @@ DUPF(retransmit_merging);
DUPF(sched_class);
DUPF(maybe_memsize);
DUPF(maybe_int32);
#ifdef DDSI_INCLUDE_ENCRYPTION
DUPF(cipher);
#endif
#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING
DUPF(bandwidth);
#endif
@ -207,9 +204,6 @@ DF(ff_networkAddresses);
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
DI(if_channel);
#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */
#ifdef DDSI_INCLUDE_ENCRYPTION
DI(if_security_profile);
#endif
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
DI(if_network_partition);
DI(if_ignored_partition);
@ -290,33 +284,6 @@ static const struct cfgelem general_cfgelems[] = {
END_MARKER
};
#ifdef DDSI_INCLUDE_ENCRYPTION
static const struct cfgelem securityprofile_cfgattrs[] = {
{ ATTR("Name"), 1, NULL, RELOFF(config_securityprofile_listelem, name), 0, uf_string, ff_free, pf_string,
BLURB("<p>This attribute specifies the name of this DDSI2E security profile. Two security profiles cannot have the same name.</p>") },
{ ATTR("Cipher"), 1, "null", RELOFF(config_securityprofile_listelem, cipher), 0, uf_cipher, 0, pf_cipher,
BLURB("<p>This attribute specifies the cipher to be used for encrypting traffic over network partitions secured by this security profile. The possible ciphers are:</p>\n\
<ul><li><i>aes128</i>: AES with a 128-bit key;</li>\n\
<li><i>aes192</i>: AES with a 192-bit key;</li>\n\
<li><i>aes256</i>: AES with a 256-bit key;</li>\n\
<li><i>blowfish</i>: the Blowfish cipher with a 128 bit key;</li>\n\
<li><i>null</i>: no encryption;</li></ul>\n\
<p>SHA1 is used on conjunction with all ciphers except \"null\" to ensure data integrity.</p>") },
{ ATTR("CipherKey"), 1, "", RELOFF(config_securityprofile_listelem, key), 0, uf_string, ff_free, pf_key,
BLURB("<p>The CipherKey attribute is used to define the secret key required by the cipher selected using the Cipher attribute. The value can be a URI referencing an external file containing the secret key, or the secret key can be defined in-place as a string value.</p>\n\
<p>The key must be specified as a hexadecimal string with each character representing 4 bits of the key. E.g., 1ABC represents the 16-bit key 0001 1010 1011 1100. The key should not follow a well-known pattern and must exactly match the key length of the selected cipher.</p>\n\
<p>A malformed key will cause the security profile to be marked as invalid, and disable all network partitions secured by the (invalid) security profile to prevent information leaks.</p>\n\
<p>As all DDS applications require read access to the XML configuration file, for security reasons it is recommended to store the secret key in an external file in the file system, referenced by its URI. The file should be protected against read and write access from other users on the host.</p>") },
END_MARKER
};
static const struct cfgelem security_cfgelems[] = {
{ LEAF_W_ATTRS("SecurityProfile", securityprofile_cfgattrs), INT_MAX, 0, ABSOFF(securityProfiles), if_security_profile, 0, 0, 0,
BLURB("<p>This element defines a DDSI2E security profile.</p>") },
END_MARKER
};
#endif /* DDSI_INCLUDE_ENCRYPTION */
#ifdef DDSI_INCLUDE_SECURITY
/** Security Configuration */
static const struct cfgelem authentication_library_attributes[] = {
@ -468,10 +435,6 @@ static const struct cfgelem networkpartition_cfgattrs[] = {
BLURB("<p>This attribute specifies the multicast addresses associated with the network partition as a comma-separated list. Readers matching this network partition (cf. Partitioning/PartitionMappings) will listen for multicasts on all of these addresses and advertise them in the discovery protocol. The writers will select the most suitable address from the addresses advertised by the readers.</p>") },
{ ATTR("Connected"), 1, "true", RELOFF(config_networkpartition_listelem, connected), 0, uf_boolean, 0, pf_boolean,
BLURB("<p>This attribute is a placeholder.</p>") },
#ifdef DDSI_INCLUDE_ENCRYPTION
{ ATTR("SecurityProfile"), 1, "null", RELOFF(config_networkpartition_listelem, profileName), 0, uf_string, ff_free, pf_string,
BLURB("<p>This attribute selects the DDSI2E security profile for encrypting the traffic mapped to this DDSI2E network partition. The default \"null\" means the network partition is unsecured; any other name refers to a security profile defined using the Security/SecurityProfile elements.</p>") },
#endif /* DDSI_INCLUDE_ENCRYPTION */
END_MARKER
};
@ -907,7 +870,7 @@ static const struct cfgelem discovery_cfgelems[] = {
};
static const struct cfgelem tracing_cfgelems[] = {
{ LEAF("EnableCategory"), 1, "", 0, 0, 0, uf_tracemask, 0, pf_tracemask,
{ LEAF("Category|EnableCategory"), 1, "", 0, 0, 0, uf_tracemask, 0, pf_tracemask,
BLURB("<p>This element enables individual logging categories. These are enabled in addition to those enabled by Tracing/Verbosity. Recognised categories are:</p>\n\
<ul><li><i>fatal</i>: all fatal errors, errors causing immediate termination</li>\n\
<li><i>error</i>: failures probably impacting correctness but not necessarily causing immediate termination</li>\n\
@ -926,7 +889,7 @@ static const struct cfgelem tracing_cfgelems[] = {
<p>In addition, there is the keyword <i>trace</i> that enables all but <i>radmin</i>, <i>topic</i>, <i>plist</i> and <i>whc</i></p>.\n\
<p>The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is <i>trace</i>.</p>") },
{ LEAF("Verbosity"), 1, "none", 0, 0, 0, uf_verbosity, 0, pf_nop,
BLURB("<p>This element enables standard groups of categories, based on a desired verbosity level. This is in addition to the categories enabled by the Tracing/EnableCategory setting. Recognised verbosity levels and the categories they map to are:</p>\n\
BLURB("<p>This element enables standard groups of categories, based on a desired verbosity level. This is in addition to the categories enabled by the Tracing/Category setting. Recognised verbosity levels and the categories they map to are:</p>\n\
<ul><li><i>none</i>: no DDSI2E log</li>\n\
<li><i>severe</i>: error and fatal</li>\n\
<li><i>warning</i>: <i>severe</i> + warning</li>\n\
@ -947,7 +910,7 @@ static const struct cfgelem tracing_cfgelems[] = {
};
static const struct cfgelem domain_cfgattrs[] = {
{ LEAF("Id"), 0, "any", ABSOFF(domainId), 0, uf_domainId, 0, pf_domainId,
{ ATTR("Id"), 0, "any", ABSOFF(domainId), 0, uf_domainId, 0, pf_domainId,
BLURB("<p>Domain id this configuration applies to, or \"any\" if it applies to all domain ids.</p>") },
END_MARKER
};
@ -956,10 +919,6 @@ static const struct cfgelem domain_cfgelems[] = {
{ MOVED("Id", "CycloneDDS/Domain[@Id]") },
{ GROUP("General", general_cfgelems),
BLURB("<p>The General element specifies overall DDSI2E service settings.</p>") },
#ifdef DDSI_INCLUDE_ENCRYPTION
{ GROUP("Security", security_cfgelems),
BLURB("<p>The Security element specifies DDSI2E security profiles that can be used to encrypt traffic mapped to DDSI2E network partitions.</p>") },
#endif
#ifdef DDSI_INCLUDE_SECURITY
{ MGROUP ("DDSSecurity", security_omg_config_elements, NULL), INT_MAX, NULL, ABSOFF(omg_security_configuration), if_omg_security, 0, 0, 0,
BLURB("<p>This element is used to configure DDSI2E with the DDS Security specification plugins and settings.</p>") },
@ -999,9 +958,6 @@ static const struct cfgelem root_cfgelems[] = {
{ GROUP_W_ATTRS("Domain", domain_cfgelems, domain_cfgattrs),
BLURB("<p>The General element specifying Domain related settings.</p>") },
{ MOVED("General", "CycloneDDS/Domain/General") },
#ifdef DDSI_INCLUDE_ENCRYPTION
{ MOVED("Security", "CycloneDDS/Domain/Security") },
#endif
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
{ MOVED("Partitioning", "CycloneDDS/Domain/Partitioning") },
#endif
@ -1026,8 +982,14 @@ static const struct cfgelem root_cfgelems[] = {
END_MARKER
};
static const struct cfgelem root_cfgattrs[] = {
{ ATTR("xmlns:xsi"), 0, "", 0, 0, 0, uf_nop, 0, pf_nop, NULL },
{ ATTR("xsi:noNamespaceSchemaLocation"), 0, "", 0, 0, 0, uf_nop, 0, pf_nop, NULL },
END_MARKER
};
static const struct cfgelem cyclonedds_root_cfgelems[] = {
{ "CycloneDDS", root_cfgelems, NULL, NODATA, BLURB("CycloneDDS configuration") },
{ "CycloneDDS", root_cfgelems, root_cfgattrs, NODATA, BLURB("CycloneDDS configuration") },
END_MARKER
};
@ -1416,15 +1378,6 @@ static int if_channel(struct cfgst *cfgst, void *parent, struct cfgelem const *
}
#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */
#ifdef DDSI_INCLUDE_ENCRYPTION
static int if_security_profile (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem)
{
if (if_common (cfgst, parent, cfgelem, sizeof (struct config_securityprofile_listelem)) == NULL)
return -1;
return 0;
}
#endif /* DDSI_INCLUDE_ENCRYPTION */
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
static int if_network_partition (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem)
{
@ -1432,10 +1385,6 @@ static int if_network_partition (struct cfgst *cfgst, void *parent, struct cfgel
if (new == NULL)
return -1;
new->address_string = NULL;
#ifdef DDSI_INCLUDE_ENCRYPTION
new->profileName = NULL;
new->securityProfile = NULL;
#endif /* DDSI_INCLUDE_ENCRYPTION */
return 0;
}
@ -1480,6 +1429,11 @@ static void ff_free (struct cfgst *cfgst, void *parent, struct cfgelem const * c
ddsrt_free (*elem);
}
static enum update_result uf_nop (UNUSED_ARG (struct cfgst *cfgst), UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), UNUSED_ARG (const char *value))
{
return URES_SUCCESS;
}
static void pf_nop (UNUSED_ARG (struct cfgst *cfgst), UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (uint32_t sources))
{
}
@ -1722,7 +1676,7 @@ static enum update_result uf_verbosity (struct cfgst *cfgst, UNUSED_ARG (void *p
static void pf_tracemask (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), uint32_t sources)
{
/* EnableCategory is also (and often) set by Verbosity, so make an effort to locate the sources for verbosity and merge them in */
/* Category is also (and often) set by Verbosity, so make an effort to locate the sources for verbosity and merge them in */
struct cfgst_node *n;
struct cfgst_nodekey key;
bool isattr;
@ -1847,31 +1801,6 @@ static void pf_memsize (struct cfgst *cfgst, void *parent, struct cfgelem const
pf_int64_unit (cfgst, *elem, sources, unittab_memsize, "B");
}
#ifdef DDSI_INCLUDE_ENCRYPTION
static enum update_result uf_cipher(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG(int first), const char *value)
{
if (q_security_plugin.cipher_type_from_string)
{
q_cipherType * const elem = cfg_address (cfgst, parent, cfgelem);
if (! q_security_plugin.cipher_type_from_string (value, elem))
return cfg_error (cfgst, "%s: undefined value", value);
}
return URES_SUCCESS;
}
static void pf_cipher (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources)
{
q_cipherType const * const p = cfg_address (cfgst, parent, cfgelem);
if (q_security_plugin.cipher_type)
cfg_logelem (cfgst, sources, "%s", (q_security_plugin.cipher_type) (*p));
}
static void pf_key (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), uint32_t sources)
{
cfg_logelem (cfgst, sources, "<hidden, see configfile>");
}
#endif /* DDSI_INCLUDE_ENCRYPTION */
static enum update_result uf_tracingOutputFileName (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value)
{
struct config * const cfg = cfgst->cfg;
@ -2476,10 +2405,17 @@ static void free_configured_elements (struct cfgst *cfgst, void *parent, struct
free_configured_element (cfgst, parent, ce);
}
static int matching_name_index (const char *name_w_aliases, const char *name)
static int matching_name_index (const char *name_w_aliases, const char *name, size_t *partial)
{
const char *ns = name_w_aliases, *p = strchr (ns, '|');
const char *ns = name_w_aliases;
const char *aliases = strchr (ns, '|');
const char *p = aliases;
int idx = 0;
if (partial)
{
/* may be set later on */
*partial = 0;
}
while (p)
{
if (ddsrt_strncasecmp (ns, name, (size_t) (p - ns)) == 0 && name[p - ns] == 0)
@ -2492,7 +2428,24 @@ static int matching_name_index (const char *name_w_aliases, const char *name)
p = strchr (ns, '|');
idx++;
}
return (ddsrt_strcasecmp (ns, name) == 0) ? idx : -1;
if (ddsrt_strcasecmp (ns, name) == 0)
return idx;
else
{
if (partial)
{
/* try a partial match on the primary name (the aliases are for backwards compatibility,
and as partial matches are for hackability, I am of the opinion that backwards
compatibility on those is a bit over the top) */
size_t max_len = strlen (name);
if (aliases && (size_t) (aliases - name_w_aliases) < max_len)
max_len = (size_t) (aliases - name_w_aliases);
if (ddsrt_strncasecmp (name_w_aliases, name, max_len) == 0)
*partial = max_len;
/* it may be a partial match, but it is still not a match */
}
return -1;
}
}
static const struct cfgelem *lookup_element (const char *target, bool *isattr)
@ -2523,7 +2476,7 @@ static const struct cfgelem *lookup_element (const char *target, bool *isattr)
}
for (; cfgelem->name; cfgelem++)
{
if (matching_name_index (cfgelem->name, p) >= 0)
if (matching_name_index (cfgelem->name, p, NULL) >= 0)
{
/* not supporting chained redirects */
assert (cfgelem->name[0] != '>');
@ -2566,6 +2519,8 @@ static int proc_elem_open (void *varg, UNUSED_ARG (uintptr_t parentinfo), UNUSED
const struct cfgelem *cfgelem = cfgst_tos (cfgst);
const struct cfgelem *cfg_subelem;
int moved = 0;
size_t partial = 0;
const struct cfgelem *partial_match = NULL;
if (cfgelem == NULL)
{
@ -2576,11 +2531,12 @@ static int proc_elem_open (void *varg, UNUSED_ARG (uintptr_t parentinfo), UNUSED
for (cfg_subelem = cfgelem->children; cfg_subelem && cfg_subelem->name && strcmp (cfg_subelem->name, "*") != 0; cfg_subelem++)
{
const char *csename = cfg_subelem->name;
size_t partial1;
int idx;
moved = (csename[0] == '>');
if (moved)
csename++;
idx = matching_name_index (csename, name);
idx = matching_name_index (csename, name, &partial1);
if (idx > 0)
{
if (csename[0] == '|')
@ -2594,15 +2550,34 @@ static int proc_elem_open (void *varg, UNUSED_ARG (uintptr_t parentinfo), UNUSED
}
}
if (idx >= 0)
{
/* an exact match is always good */
break;
}
if (partial1 > partial)
{
/* a longer prefix match is a candidate ... */
partial = partial1;
partial_match = cfg_subelem;
}
else if (partial1 > 0 && partial1 == partial)
{
/* ... but an ambiguous prefix match won't do */
partial_match = NULL;
}
}
if (cfg_subelem == NULL || cfg_subelem->name == NULL)
{
if (partial_match != NULL && cfgst->partial_match_allowed)
cfg_subelem = partial_match;
else
{
cfg_error (cfgst, "%s: unknown element", name);
cfgst_push (cfgst, 0, NULL, NULL);
return 0;
}
else if (strcmp (cfg_subelem->name, "*") == 0)
}
if (strcmp (cfg_subelem->name, "*") == 0)
{
/* Push a marker that we are to ignore this part of the DOM tree */
cfgst_push (cfgst, 0, NULL, NULL);
@ -2934,6 +2909,7 @@ struct cfgst *config_init (const char *config, struct config *cfg, uint32_t domi
}
cfgst->implicit_toplevel = (fp == NULL) ? ITL_ALLOWED : ITL_DISALLOWED;
cfgst->partial_match_allowed = (fp == NULL);
cfgst->first_data_in_source = true;
cfgst_push (cfgst, 0, &root_cfgelem, cfgst->cfg);
ok = (ddsrt_xmlp_parse (qx) >= 0) && !cfgst->error;
@ -3012,67 +2988,13 @@ struct cfgst *config_init (const char *config, struct config *cfg, uint32_t domi
ok = 0;
#endif
#ifdef DDSI_INCLUDE_ENCRYPTION
/* Check security profiles */
{
struct config_securityprofile_listelem *s = cfgst->cfg->securityProfiles;
while (s)
{
switch (s->cipher)
{
case Q_CIPHER_UNDEFINED:
case Q_CIPHER_NULL:
/* nop */
if (s->key && strlen(s->key) > 0)
DDS_ILOG (DDS_LC_INFO, domid, "config: DDSI2Service/Security/SecurityProfile[@cipherkey]: %s: cipher key not required\n", s->key);
break;
default:
/* read the cipherkey if present */
if (!s->key || strlen(s->key) == 0)
{
DDS_ILOG (DDS_LC_ERROR, domid, "config: DDSI2Service/Security/SecurityProfile[@cipherkey]: cipher key missing\n");
ok = 0;
}
else if (q_security_plugin.valid_uri && !(q_security_plugin.valid_uri) (s->cipher, s->key))
{
DDS_ILOG (DDS_LC_ERROR, domid, "config: DDSI2Service/Security/SecurityProfile[@cipherkey]: %s : incorrect key\n", s->key);
ok = 0;
}
}
s = s->next;
}
}
#endif /* DDSI_INCLUDE_ENCRYPTION */
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
/* Assign network partition ids */
#ifdef DDSI_INCLUDE_ENCRYPTION
/* also create links from the network partitions to the
securityProfiles and signal errors if profiles do not exist */
#endif /* DDSI_INCLUDE_ENCRYPTION */
{
struct config_networkpartition_listelem *p = cfgst->cfg->networkPartitions;
cfgst->cfg->nof_networkPartitions = 0;
while (p)
{
#ifdef DDSI_INCLUDE_ENCRYPTION
if (ddsrt_strcasecmp(p->profileName, "null") == 0)
p->securityProfile = NULL;
else
{
struct config_securityprofile_listelem *s = cfgst->cfg->securityProfiles;
while (s && ddsrt_strcasecmp(p->profileName, s->name) != 0)
s = s->next;
if (s)
p->securityProfile = s;
else
{
DDS_ILOG (DDS_LC_ERROR, domid, "config: DDSI2Service/Partitioning/NetworkPartitions/NetworkPartition[@securityprofile]: %s: unknown securityprofile\n", p->profileName);
ok = 0;
}
}
#endif /* DDSI_INCLUDE_ENCRYPTION */
cfgst->cfg->nof_networkPartitions++;
/* also use crc32 just like native nw and ordinary ddsi2e, only
for interoperability because it is asking for trouble &

View file

@ -195,7 +195,7 @@ static int print_participants (struct thread_state1 * const ts1, struct q_global
whcst.min_seq, whcst.max_seq, whcst.unacked_bytes,
w->throttling ? " THROTTLING" : "",
w->whc_low, w->whc_high,
w->seq, READ_SEQ_XMIT(w), w->cs_seq);
w->seq, writer_read_seq_xmit (w), w->cs_seq);
if (w->reliable)
{
x += cpf (conn, " hb %"PRIu32" ackhb %"PRId64" hb %"PRId64" wr %"PRId64" sched %"PRId64" #rel %"PRId32"\n",

View file

@ -110,6 +110,9 @@ extern inline bool builtintopic_is_builtintopic (const struct ddsi_builtin_topic
extern inline struct ddsi_tkmap_instance *builtintopic_get_tkmap_entry (const struct ddsi_builtin_topic_interface *btif, const struct ddsi_guid *guid);
extern inline void builtintopic_write (const struct ddsi_builtin_topic_interface *btif, const struct entity_common *e, nn_wctime_t timestamp, bool alive);
extern inline seqno_t writer_read_seq_xmit (const struct writer *wr);
extern inline void writer_update_seq_xmit (struct writer *wr, seqno_t nv);
static int compare_guid (const void *va, const void *vb)
{
return memcmp (va, vb, sizeof (ddsi_guid_t));
@ -2735,7 +2738,7 @@ static void new_writer_guid_common_init (struct writer *wr, const struct ddsi_se
ddsrt_cond_init (&wr->throttle_cond);
wr->seq = 0;
wr->cs_seq = 0;
INIT_SEQ_XMIT(wr, 0);
ddsrt_atomic_st64 (&wr->seq_xmit, (uint64_t) 0);
wr->hbcount = 0;
wr->state = WRST_OPERATIONAL;
wr->hbfragcount = 0;

View file

@ -1001,14 +1001,6 @@ int rtps_init (struct q_globals *gv)
gv->xmsgpool = nn_xmsgpool_new ();
gv->serpool = ddsi_serdatapool_new ();
#ifdef DDSI_INCLUDE_ENCRYPTION
if (q_security_plugin.new_decoder)
{
gv->recvSecurityCodec = (q_security_plugin.new_decoder) ();
GVLOG (DDS_LC_CONFIG, "decoderset created\n");
}
#endif
nn_plist_init_default_participant (&gv->default_plist_pp);
nn_plist_init_default_participant (&gv->default_local_plist_pp);
nn_xqos_init_default_reader (&gv->default_xqos_rd);
@ -1337,10 +1329,6 @@ err_unicast_sockets:
ddsrt_cond_destroy (&gv->participant_set_cond);
ddsrt_mutex_destroy (&gv->participant_set_lock);
free_special_topics (gv);
#ifdef DDSI_INCLUDE_ENCRYPTION
if (q_security_plugin.free_decoder)
q_security_plugin.free_decoder (gv->recvSecurityCodec);
#endif
nn_xqos_fini (&gv->builtin_endpoint_xqos_wr);
nn_xqos_fini (&gv->builtin_endpoint_xqos_rd);
nn_xqos_fini (&gv->spdp_endpoint_xqos);
@ -1498,12 +1486,6 @@ void rtps_stop (struct q_globals *gv)
nn_reorder_free (gv->spdp_reorder);
nn_defrag_free (gv->spdp_defrag);
ddsrt_mutex_destroy (&gv->spdp_lock);
#ifdef DDSI_INCLUDE_ENCRYPTION
if (q_security_plugin.free_decoder)
{
(q_security_plugin.free_decoder) (gv->recvSecurityCodec);
}
#endif /* DDSI_INCLUDE_ENCRYPTION */
{
struct ephash_enum_proxy_participant est;

View file

@ -206,19 +206,6 @@ static int valid_InfoTS (InfoTS_t *msg, size_t size, int byteswap)
}
}
static int valid_PT_InfoContainer (PT_InfoContainer_t *msg, size_t size, int byteswap)
{
if (size < sizeof (PT_InfoContainer_t))
return 0;
#if 0
if (msg->smhdr.flags)
return 0;
#endif
if (byteswap)
msg->id = bswap4u (msg->id);
return 1;
}
static int valid_Heartbeat (Heartbeat_t *msg, size_t size, int byteswap)
{
if (size < sizeof (*msg))
@ -568,7 +555,7 @@ static void force_heartbeat_to_peer (struct writer *wr, const struct whc_state *
static seqno_t grow_gap_to_next_seq (const struct writer *wr, seqno_t seq)
{
seqno_t next_seq = whc_next_seq (wr->whc, seq - 1);
seqno_t seq_xmit = READ_SEQ_XMIT(wr);
seqno_t seq_xmit = writer_read_seq_xmit (wr);
if (next_seq == MAX_SEQ_NUMBER) /* no next sample */
return seq_xmit + 1;
else if (next_seq > seq_xmit) /* next is beyond last actually transmitted */
@ -849,7 +836,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
that issue; if it has, then the timing is terribly unlucky, but
a future request'll fix it. */
enqueued = 1;
seq_xmit = READ_SEQ_XMIT(wr);
seq_xmit = writer_read_seq_xmit (wr);
const bool gap_for_already_acked = vendor_is_eclipse (rst->vendor) && prd->c.xqos->durability.kind == DDS_DURABILITY_VOLATILE && seqbase <= rn->seq;
const seqno_t min_seq_to_rexmit = gap_for_already_acked ? rn->seq + 1 : 0;
for (uint32_t i = 0; i < numbits && seqbase + i <= seq_xmit && enqueued; i++)
@ -1473,7 +1460,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N
qxev_msg (wr->evq, m);
}
}
if (seq < READ_SEQ_XMIT(wr))
if (seq < writer_read_seq_xmit (wr))
{
/* Not everything was retransmitted yet, so force a heartbeat out
to give the reader a chance to nack the rest and make sure
@ -2474,22 +2461,6 @@ static int handle_DataFrag (struct receiver_state *rst, nn_etime_t tnow, struct
return 1;
}
#ifdef DDSI_INCLUDE_ENCRYPTION
static size_t decode_container (unsigned char *submsg, size_t len)
{
size_t result = len;
if (gv.recvSecurityCodec && len > 0)
{
if (! (q_security_plugin.decode)
(gv.recvSecurityCodec, submsg, len, &result /* in/out, decrements the length*/))
{
result = 0;
}
}
return result;
}
#endif /* DDSI_INCLUDE_ENCRYPTION */
static void malformed_packet_received_nosubmsg (const struct q_globals *gv, const unsigned char * msg, ssize_t len, const char *state, nn_vendorid_t vendorid
)
{
@ -2829,41 +2800,6 @@ static int handle_submsg_sequence
ts_for_latmeas = 0;
}
break;
case SMID_PT_INFO_CONTAINER:
if (vendor_is_eclipse_or_prismtech (rst->vendor))
{
state = "parse:pt_info_container";
GVTRACE ("PT_INFO_CONTAINER(");
if (!valid_PT_InfoContainer (&sm->pt_infocontainer, submsg_size, byteswap))
goto malformed;
switch (sm->pt_infocontainer.id)
{
case PTINFO_ID_ENCRYPT:
#ifdef DDSI_INCLUDE_ENCRYPTION
if (q_security_plugin.decode)
{
/* we have: msg .. submsg .. submsg+submsg_size-1 submsg .. msg+len-1
our container: data starts immediately following the pt_infocontainer */
const size_t len1 = submsg_size - sizeof (PT_InfoContainer_t);
unsigned char * const submsg1 = submsg + sizeof (PT_InfoContainer_t);
size_t len2 = decode_container (submsg1, len1);
if ( len2 != 0 ) {
TRACE ((")\n"));
thread_state_asleep (ts1);
if (handle_submsg_sequence (conn, srcloc, tnowWC, tnowE, src_prefix, dst_prefix, msg, (size_t) (submsg1 - msg) + len2, submsg1, rmsg) < 0)
goto malformed_asleep;
thread_state_awake (ts1);
}
TRACE (("PT_INFO_CONTAINER END"));
}
#endif /* DDSI_INCLUDE_ENCRYPTION */
break;
default:
GVTRACE ("(unknown id %"PRIu32"?)\n", sm->pt_infocontainer.id);
}
}
break;
case SMID_PT_MSG_LEN:
{
#if 0

File diff suppressed because it is too large Load diff

View file

@ -251,10 +251,7 @@ static struct thread_state1 *init_thread_state (const char *tname, const struct
ts = &thread_states.ts[cand];
ddsrt_atomic_stvoidp (&ts->gv, (struct q_globals *) gv);
assert (vtime_asleep_p (ddsrt_atomic_ld32 (&ts->vtime)));
DDSRT_WARNING_MSVC_OFF(4996);
strncpy (ts->name, tname, sizeof (ts->name));
DDSRT_WARNING_MSVC_ON(4996);
ts->name[sizeof (ts->name) - 1] = 0;
ddsrt_strlcpy (ts->name, tname, sizeof (ts->name));
ts->state = state;
return ts;

View file

@ -307,7 +307,7 @@ struct nn_xmsg *writer_hbcontrol_piggyback (struct writer *wr, const struct whc_
(hbc->tsched.v == T_NEVER) ? INFINITY : (double) (hbc->tsched.v - tnow.v) / 1e9,
ddsrt_avl_is_empty (&wr->readers) ? -1 : root_rdmatch (wr)->min_seq,
ddsrt_avl_is_empty (&wr->readers) || root_rdmatch (wr)->all_have_replied_to_hb ? "" : "!",
whcst->max_seq, READ_SEQ_XMIT(wr));
whcst->max_seq, writer_read_seq_xmit (wr));
}
return msg;
@ -354,7 +354,7 @@ void add_Heartbeat (struct nn_xmsg *msg, struct writer *wr, const struct whc_sta
seqno_t seq_xmit;
min = whcst->min_seq;
max = wr->seq;
seq_xmit = READ_SEQ_XMIT(wr);
seq_xmit = writer_read_seq_xmit (wr);
assert (min <= max);
/* Informing readers of samples that haven't even been transmitted makes little sense,
but for transient-local data, we let the first heartbeat determine the time at which
@ -1125,7 +1125,7 @@ static int write_sample_eot (struct thread_state1 * const ts1, struct nn_xpack *
(Note that no network destination is very nearly the same as no
matching proxy readers. The exception is the SPDP writer.) */
UPDATE_SEQ_XMIT_LOCKED (wr, seq);
writer_update_seq_xmit (wr, seq);
ddsrt_mutex_unlock (&wr->e.lock);
if (plist != NULL)
{

View file

@ -622,7 +622,7 @@ static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, nn_mt
(t_next.v == T_NEVER) ? INFINITY : (double)(t_next.v - tnow.v) / 1e9,
ddsrt_avl_is_empty (&wr->readers) ? (seqno_t) -1 : ((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->min_seq,
ddsrt_avl_is_empty (&wr->readers) || ((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->all_have_replied_to_hb ? "" : "!",
whcst.max_seq, READ_SEQ_XMIT(wr));
whcst.max_seq, writer_read_seq_xmit (wr));
resched_xevent_if_earlier (ev, t_next);
wr->hbcontrol.tsched = t_next;
ddsrt_mutex_unlock (&wr->e.lock);

View file

@ -223,13 +223,6 @@ struct nn_xpack
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
uint32_t encoderId;
#endif /* DDSI_INCLUDE_NETWORK_PARTITIONS */
#ifdef DDSI_INCLUDE_ENCRYPTION
/* each partion is associated with a SecurityPolicy, this codecset will serve */
/* all of them, different cipher for each partition */
q_securityEncoderSet codec;
PT_InfoContainer_t SecurityHeader;
#endif /* DDSI_INCLUDE_ENCRYPTION */
};
static size_t align4u (size_t x)
@ -868,7 +861,7 @@ static void nn_xmsg_chain_release (struct q_globals *gv, struct nn_xmsg_chain *c
assert (m->kindspecific.data.wrseq != 0);
wrguid = m->kindspecific.data.wrguid;
if ((wr = ephash_lookup_writer_guid (gv->guid_hash, &m->kindspecific.data.wrguid)) != NULL)
UPDATE_SEQ_XMIT_UNLOCKED(wr, m->kindspecific.data.wrseq);
writer_update_seq_xmit (wr, m->kindspecific.data.wrseq);
}
}
@ -1001,16 +994,6 @@ struct nn_xpack * nn_xpack_new (ddsi_tran_conn_t conn, uint32_t bw_limit, bool a
if (xp->gv->thread_pool)
ddsi_sem_init (&xp->sem, 0);
#ifdef DDSI_INCLUDE_ENCRYPTION
if (q_security_plugin.new_encoder)
{
xp->codec = (q_security_plugin.new_encoder) ();
xp->SecurityHeader.smhdr.submessageId = SMID_PT_INFO_CONTAINER;
xp->SecurityHeader.smhdr.flags = (DDSRT_LITTLE_ENDIAN ? SMFLAG_ENDIANNESS : 0);
xp->SecurityHeader.smhdr.octetsToNextHeader = 4;
xp->SecurityHeader.id = PTINFO_ID_ENCRYPT;
}
#endif
#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING
nn_bw_limit_init (&xp->limiter, bw_limit);
#else
@ -1023,12 +1006,6 @@ void nn_xpack_free (struct nn_xpack *xp)
{
assert (xp->niov == 0);
assert (xp->included_msgs.latest == NULL);
#ifdef DDSI_INCLUDE_ENCRYPTION
if (q_security_plugin.free_encoder)
{
(q_security_plugin.free_encoder) (xp->codec);
}
#endif
if (xp->gv->thread_pool)
ddsi_sem_destroy (&xp->sem);
ddsrt_free (xp->iov);
@ -1059,16 +1036,6 @@ static ssize_t nn_xpack_send1 (const nn_locator_t *loc, void * varg)
}
}
#ifdef DDSI_INCLUDE_ENCRYPTION
if (q_security_plugin.send_encoded && xp->encoderId != 0 && (q_security_plugin.encoder_type) (xp->codec, xp->encoderId) != Q_CIPHER_NONE)
{
struct iovec iov[NN_XMSG_MAX_MESSAGE_IOVECS];
memcpy (iov, xp->iov, sizeof (iov));
nbytes = (q_security_plugin.send_encoded) (xp->conn, loc, xp->niov, iov, &xp->codec, xp->encoderId, xp->call_flags);
}
else
#endif
{
if (!gv->mute)
{
nbytes = ddsi_conn_write (xp->conn, loc, xp->niov, xp->iov, xp->call_flags);
@ -1087,7 +1054,6 @@ static ssize_t nn_xpack_send1 (const nn_locator_t *loc, void * varg)
GVTRACE ("(dropped)");
nbytes = (ssize_t) xp->msg_len.length;
}
}
/* Clear call flags, as used on a per call basis */
@ -1352,16 +1318,6 @@ static int nn_xpack_mayaddmsg (const struct nn_xpack *xp, const struct nn_xmsg *
payload_size = m->refd_payload ? (unsigned) m->refd_payload_iov.iov_len : 0;
#ifdef DDSI_INCLUDE_ENCRYPTION
if (xp->encoderId)
{
unsigned security_header;
security_header = (q_security_plugin.header_size) (xp->codec, xp->encoderId);
assert (security_header < max_msg_size);
max_msg_size -= security_header;
}
#endif
/* Check if max message size exceeded */
if (xp->msg_len.length + m->sz + payload_size > max_msg_size)
@ -1477,17 +1433,6 @@ int nn_xpack_addmsg (struct nn_xpack *xp, struct nn_xmsg *m, const uint32_t flag
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
xp->encoderId = m->encoderid;
#endif
#ifdef DDSI_INCLUDE_ENCRYPTION
if (xp->encoderId > 0 && (q_security_plugin.encoder_type) (xp->codec, xp->encoderId) != Q_CIPHER_NONE)
{
/* Insert a reference to the security header
the correct size will be set upon encryption in q_xpack_sendmsg_encoded */
xp->iov[niov].iov_base = (void*) &xp->SecurityHeader;
xp->iov[niov].iov_len = sizeof (xp->SecurityHeader);
sz += xp->iov[niov].iov_len;
niov++;
}
#endif
xp->last_src = &xp->hdr.guid_prefix;
xp->last_dst = NULL;

View file

@ -12,13 +12,13 @@
#ifndef DDSRT_ATTRIBUTES_H
#define DDSRT_ATTRIBUTES_H
#if __clang__
#if __GNUC__
# define ddsrt_gnuc (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#else
# define ddsrt_gnuc (0)
#endif
#if __GNUC__
#if __clang__
# define ddsrt_clang (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
#else
# define ddsrt_clang (0)

View file

@ -28,20 +28,20 @@ typedef int32_t dds_return_t;
* @name DDS_Error_Type
* @{
*/
#define DDS_RETCODE_OK 0 /**< Success */
#define DDS_RETCODE_ERROR -1 /**< Non specific error */
#define DDS_RETCODE_UNSUPPORTED -2 /**< Feature unsupported */
#define DDS_RETCODE_BAD_PARAMETER -3 /**< Bad parameter value */
#define DDS_RETCODE_PRECONDITION_NOT_MET -4 /**< Precondition for operation not met */
#define DDS_RETCODE_OUT_OF_RESOURCES -5 /**< When an operation fails because of a lack of resources */
#define DDS_RETCODE_NOT_ENABLED -6 /**< When a configurable feature is not enabled */
#define DDS_RETCODE_IMMUTABLE_POLICY -7 /**< When an attempt is made to modify an immutable policy */
#define DDS_RETCODE_INCONSISTENT_POLICY -8 /**< When a policy is used with inconsistent values */
#define DDS_RETCODE_ALREADY_DELETED -9 /**< When an attempt is made to delete something more than once */
#define DDS_RETCODE_TIMEOUT -10 /**< When a timeout has occurred */
#define DDS_RETCODE_NO_DATA -11 /**< When expected data is not provided */
#define DDS_RETCODE_ILLEGAL_OPERATION -12 /**< When a function is called when it should not be */
#define DDS_RETCODE_NOT_ALLOWED_BY_SECURITY -13 /**< When credentials are not enough to use the function */
#define DDS_RETCODE_OK (0) /**< Success */
#define DDS_RETCODE_ERROR (-1) /**< Non specific error */
#define DDS_RETCODE_UNSUPPORTED (-2) /**< Feature unsupported */
#define DDS_RETCODE_BAD_PARAMETER (-3) /**< Bad parameter value */
#define DDS_RETCODE_PRECONDITION_NOT_MET (-4) /**< Precondition for operation not met */
#define DDS_RETCODE_OUT_OF_RESOURCES (-5) /**< When an operation fails because of a lack of resources */
#define DDS_RETCODE_NOT_ENABLED (-6) /**< When a configurable feature is not enabled */
#define DDS_RETCODE_IMMUTABLE_POLICY (-7) /**< When an attempt is made to modify an immutable policy */
#define DDS_RETCODE_INCONSISTENT_POLICY (-8) /**< When a policy is used with inconsistent values */
#define DDS_RETCODE_ALREADY_DELETED (-9) /**< When an attempt is made to delete something more than once */
#define DDS_RETCODE_TIMEOUT (-10) /**< When a timeout has occurred */
#define DDS_RETCODE_NO_DATA (-11) /**< When expected data is not provided */
#define DDS_RETCODE_ILLEGAL_OPERATION (-12) /**< When a function is called when it should not be */
#define DDS_RETCODE_NOT_ALLOWED_BY_SECURITY (-13) /**< When credentials are not enough to use the function */
/* Extended return codes are not in the DDS specification and are meant

View file

@ -27,6 +27,7 @@ typedef struct {
} ddsrt_thread_t;
typedef UBaseType_t ddsrt_tid_t;
typedef TaskHandle_t ddsrt_thread_list_id_t;
#define PRIdTID "lu"
#if defined(__cplusplus)

View file

@ -64,7 +64,7 @@ static void default_sink (void *ptr, const dds_log_data_t *data)
static struct ddsrt_log_cfg_impl logconfig = {
.c = {
.mask = DDS_LC_ERROR | DDS_LC_WARNING,
.mask = DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_FATAL,
.tracemask = 0,
.domid = UINT32_MAX
},

View file

@ -30,6 +30,7 @@ static const char *retcodes[] = {
};
static const char *xretcodes[] = {
"Unknown return code",
"Operation in progress",
"Try again",
"Interrupted",
@ -50,7 +51,11 @@ const char *dds_strretcode (dds_return_t rc)
/* Retcodes used to be positive, but return values from the API would be a negative
and so there are/were/may be places outside the core library where dds_strretcode
is called with a -N for N a API return value, so ... play it safe and use the
magnitude */
magnitude. Specially handle INT32_MIN to avoid undefined behaviour on integer
overflow. */
if (rc == INT32_MIN)
return xretcodes[0];
if (rc < 0)
rc = -rc;
if (rc >= 0 && rc < nretcodes)
@ -58,5 +63,5 @@ const char *dds_strretcode (dds_return_t rc)
else if (rc >= (-DDS_XRETCODE_BASE) && rc < (-DDS_XRETCODE_BASE) + nxretcodes)
return xretcodes[rc - (-DDS_XRETCODE_BASE)];
else
return "Unknown return code";
return xretcodes[0];
}

View file

@ -66,13 +66,13 @@ rusage_self(ddsrt_rusage_t *usage)
}
static dds_return_t
rusage_thread(ddsrt_rusage_t *usage)
rusage_thread(ddsrt_thread_list_id_t tid, ddsrt_rusage_t *usage)
{
TaskStatus_t states;
memset(usage, 0, sizeof(*usage));
memset(&states, 0, sizeof(states));
vTaskGetInfo(xTaskGetCurrentTaskHandle(), &states, pdFALSE, eInvalid);
vTaskGetInfo(tid, &states, pdFALSE, eInvalid);
usage->stime = states.ulRunTimeCounter * DDSRT_NSECS_IN_RUSAGE_TIME_BASE;
return DDS_RETCODE_OK;
@ -97,7 +97,7 @@ ddsrt_getrusage(enum ddsrt_getrusage_who who, ddsrt_rusage_t *usage)
assert(usage != NULL);
if (who == DDSRT_RUSAGE_THREAD) {
rc = rusage_thread_anythread(xTaskGetCurrentTaskHandle(), usage);
rc = ddsrt_getrusage_anythread(xTaskGetCurrentTaskHandle(), usage);
} else {
rc = rusage_self(usage);
}

View file

@ -13,8 +13,9 @@
#include <errno.h>
#include <time.h>
#include <sys/time.h>
#include <AvailabilityMacros.h>
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12
#if !(defined MAC_OS_X_VERSION_10_12 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12)
#include <mach/mach_time.h>
#endif
@ -22,7 +23,7 @@
dds_time_t dds_time(void)
{
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
#if defined MAC_OS_X_VERSION_10_12 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
return (int64_t) clock_gettime_nsec_np (CLOCK_REALTIME);
#else
struct timeval tv;
@ -33,7 +34,7 @@ dds_time_t dds_time(void)
dds_time_t ddsrt_time_monotonic(void)
{
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
#if defined MAC_OS_X_VERSION_10_12 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
return (int64_t) clock_gettime_nsec_np (CLOCK_UPTIME_RAW);
#else
static mach_timebase_info_data_t timeInfo;
@ -62,7 +63,7 @@ dds_time_t ddsrt_time_monotonic(void)
dds_time_t ddsrt_time_elapsed(void)
{
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
#if defined MAC_OS_X_VERSION_10_12 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
return (int64_t) clock_gettime_nsec_np (CLOCK_MONOTONIC_RAW);
#else
/* Elapsed time clock not (yet) supported on this platform. */

View file

@ -26,6 +26,7 @@ list(APPEND sources
"string.c"
"log.c"
"random.c"
"retcode.c"
"strlcpy.c"
"socket.c"
"select.c")

View file

@ -16,9 +16,11 @@
#ifdef __APPLE__
#include <pthread.h>
#include <AvailabilityMacros.h>
#endif /* __APPLE__ */
#include "CUnit/Test.h"
#include "CUnit/Theory.h"
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/log.h"
#include "dds/ddsrt/misc.h"
@ -27,7 +29,19 @@
#include "dds/ddsrt/threads.h"
#include "dds/ddsrt/time.h"
static FILE *fh = NULL;
/* On macOS, fmemopen was introduced in version 10.13. The hassle of providing
an alternative implementation of it just for running a few sanity checks on an
old version of macOS isn't worth the bother.
The CUnit.cmake boiler-plate generator doesn't recognize #ifdef'ing tests away
because it runs on the source rather than on the output of the C preprocessor
(a reasonable decision in itself). Therefore, just skip the body of each test. */
#if __APPLE__ && !(defined MAC_OS_X_VERSION_10_13 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_13)
#define HAVE_FMEMOPEN 0
#else
#define HAVE_FMEMOPEN 1
#endif
#ifdef _WIN32
#include <fcntl.h>
@ -104,6 +118,9 @@ FILE *fmemopen(void *buf, size_t size, const char *mode)
}
#endif /* _WIN32 */
#if HAVE_FMEMOPEN
static FILE *fh = NULL;
static void count(void *ptr, const dds_log_data_t *data)
{
(void)data;
@ -114,6 +131,7 @@ static void copy(void *ptr, const dds_log_data_t *data)
{
*(char **)ptr = ddsrt_strdup(data->message);
}
#endif
static void reset(void)
{
@ -125,14 +143,18 @@ static void reset(void)
static void setup(void)
{
#if HAVE_FMEMOPEN
fh = fmemopen(NULL, 1024, "wb+");
CU_ASSERT_PTR_NOT_NULL_FATAL(fh);
#endif
}
static void teardown(void)
{
reset();
#if HAVE_FMEMOPEN
(void)fclose(fh);
#endif
}
/* By default only DDS_LC_FATAL and DDS_LC_ERROR are set. This means setting a
@ -140,6 +162,7 @@ static void teardown(void)
enabled. The message should end up in the log file. */
CU_Test(dds_log, only_log_file, .init=setup, .fini=teardown)
{
#if HAVE_FMEMOPEN
char buf[1024], *ptr;
int cnt = 0;
size_t nbytes;
@ -157,6 +180,7 @@ CU_Test(dds_log, only_log_file, .init=setup, .fini=teardown)
/* No trace categories are enabled by default, verify trace callback was
not invoked. */
CU_ASSERT_EQUAL(cnt, 0);
#endif
}
/* Messages must be printed to the trace file if at least one trace category
@ -164,6 +188,7 @@ CU_Test(dds_log, only_log_file, .init=setup, .fini=teardown)
same as the log file. */
CU_Test(dds_log, same_file, .init=setup, .fini=teardown)
{
#if HAVE_FMEMOPEN
char buf[1024], *ptr;
size_t nbytes;
@ -182,6 +207,7 @@ CU_Test(dds_log, same_file, .init=setup, .fini=teardown)
occur again. */
ptr = strstr(ptr + 1, "foobar\n");
CU_ASSERT_PTR_NULL(ptr);
#endif
}
/* The sinks are considered to be the same only if the callback and userdata
@ -189,6 +215,7 @@ CU_Test(dds_log, same_file, .init=setup, .fini=teardown)
be called twice for log messages. */
CU_Test(dds_log, same_sink_function, .fini=reset)
{
#if HAVE_FMEMOPEN
int log_cnt = 0, trace_cnt = 0;
dds_set_log_mask(DDS_LC_ALL);
@ -197,10 +224,12 @@ CU_Test(dds_log, same_sink_function, .fini=reset)
DDS_ERROR("foo%s\n", "bar");
CU_ASSERT_EQUAL(log_cnt, 1);
CU_ASSERT_EQUAL(trace_cnt, 1);
#endif
}
CU_Test(dds_log, exact_same_sink, .fini=reset)
{
#if HAVE_FMEMOPEN
int cnt = 0;
dds_set_log_mask(DDS_LC_ALL);
@ -208,6 +237,7 @@ CU_Test(dds_log, exact_same_sink, .fini=reset)
dds_set_trace_sink(&count, &cnt);
DDS_ERROR("foo%s\n", "bar");
CU_ASSERT_EQUAL(cnt, 1);
#endif
}
/* The log file must be restored if the sink is unregistered, verify the log
@ -215,6 +245,7 @@ CU_Test(dds_log, exact_same_sink, .fini=reset)
restored again when the sink is unregistered. */
CU_Test(dds_log, no_sink, .init=setup, .fini=teardown)
{
#if HAVE_FMEMOPEN
int ret;
char buf[1024], *ptr = NULL;
size_t cnt[2] = {0, 0};
@ -267,6 +298,7 @@ CU_Test(dds_log, no_sink, .init=setup, .fini=teardown)
buf[cnt[1]] = '\0';
ptr = strstr(buf, "foobaz\n");
CU_ASSERT_PTR_NOT_NULL_FATAL(ptr);
#endif
}
/* A newline terminates the message. Until that a newline is encountered, the
@ -274,6 +306,7 @@ CU_Test(dds_log, no_sink, .init=setup, .fini=teardown)
NULL byte if it is flushed to a sink. */
CU_Test(dds_log, newline_terminates, .fini=reset)
{
#if HAVE_FMEMOPEN
char *msg = NULL;
dds_set_log_sink(&copy, &msg);
@ -285,11 +318,13 @@ CU_Test(dds_log, newline_terminates, .fini=reset)
CU_ASSERT_PTR_NOT_NULL_FATAL(msg);
CU_ASSERT(strcmp(msg, "foobarbaz\n") == 0);
ddsrt_free(msg);
#endif
}
/* Nothing must be written unless a category is enabled. */
CU_Test(dds_log, disabled_categories_discarded, .fini=reset)
{
#if HAVE_FMEMOPEN
char *msg = NULL;
dds_set_log_sink(&copy, &msg);
DDS_INFO("foobar\n");
@ -299,9 +334,10 @@ CU_Test(dds_log, disabled_categories_discarded, .fini=reset)
CU_ASSERT_PTR_NOT_NULL_FATAL(msg);
CU_ASSERT(strcmp(msg, "foobar\n") == 0);
ddsrt_free(msg);
#endif
}
#if HAVE_FMEMOPEN
static ddsrt_cond_t cond;
static ddsrt_mutex_t mutex;
@ -337,12 +373,14 @@ static uint32_t run(void *ptr)
return 0;
}
#endif
/* Log and trace sinks can be changed at runtime. However, the operation must
be synchronous! Verify the dds_set_log_sink blocks while other threads
reside in the log or trace sinks. */
CU_Test(dds_log, synchronous_sink_changes, .fini=reset)
{
#if HAVE_FMEMOPEN
struct arg arg;
ddsrt_thread_t tid;
ddsrt_threadattr_t tattr;
@ -364,4 +402,108 @@ CU_Test(dds_log, synchronous_sink_changes, .fini=reset)
CU_ASSERT(arg.before < arg.after);
CU_ASSERT(arg.after < dds_time());
#endif
}
/* Sanity checks that FATAL calls abort() -- this is very much platform
dependent code, so we only do it on Linux and macOS, assuming that
the logging implementation doesn't make any distinction between different
platforms and that abort() is correctly implemented by the C library.
macOS: abort causes abnormal termination unless the handler doesn't return,
hence the setjmp/longjmp. */
#if defined __linux || defined __APPLE__
#define TEST_DDS_LC_FATAL 1
#else
#define TEST_DDS_LC_FATAL 0
#endif
#if TEST_DDS_LC_FATAL
#include <signal.h>
static sigjmp_buf abort_jmpbuf;
static char abort_message[100];
static char abort_message_trace[100];
static ddsrt_log_cfg_t abort_logconfig;
static void abort_handler (int sig)
{
(void) sig;
siglongjmp (abort_jmpbuf, 1);
}
static void abort_log (void *arg, const dds_log_data_t *info)
{
(void) arg;
ddsrt_strlcpy (abort_message, info->message, sizeof (abort_message));
}
static void abort_trace (void *arg, const dds_log_data_t *info)
{
(void) arg;
ddsrt_strlcpy (abort_message_trace, info->message, sizeof (abort_message_trace));
}
CU_TheoryDataPoints(dds_log, fatal_aborts) = {
CU_DataPoints(bool, false, false, false, true, true, true), /* global/config */
CU_DataPoints(int, 0, 1, 2, 0, 1, 2), /* mask init mode */
CU_DataPoints(bool, false, false, true, false, false, true) /* expect in trace? */
};
#else
CU_TheoryDataPoints(dds_log, fatal_aborts) = {
CU_DataPoints(bool, false), /* global/config */
CU_DataPoints(int, 0), /* mask init mode */
CU_DataPoints(bool, false) /* expect in trace? */
};
#endif
CU_Theory((bool local, int mode, bool expect_in_trace), dds_log, fatal_aborts)
{
#if TEST_DDS_LC_FATAL
struct sigaction action, oldaction;
action.sa_flags = 0;
action.sa_handler = abort_handler;
if (sigsetjmp (abort_jmpbuf, 0) != 0)
{
sigaction (SIGABRT, &oldaction, NULL);
CU_ASSERT_STRING_EQUAL (abort_message, "oops\n");
CU_ASSERT_STRING_EQUAL (abort_message_trace, expect_in_trace ? "oops\n" : "");
}
else
{
memset (abort_message, 0, sizeof (abort_message));
memset (abort_message_trace, 0, sizeof (abort_message_trace));
dds_set_log_sink (abort_log, NULL);
dds_set_trace_sink (abort_trace, NULL);
sigaction (SIGABRT, &action, &oldaction);
if (local)
{
switch (mode)
{
case 0:
/* FALL THROUGH */
case 1: dds_log_cfg_init (&abort_logconfig, 0, 0, 0, 0); break;
case 2: dds_log_cfg_init (&abort_logconfig, 0, DDS_LC_TRACE, 0, 0); break;
}
DDS_CLOG (DDS_LC_FATAL, &abort_logconfig, "oops\n");
}
else
{
switch (mode)
{
case 0: break;
case 1: dds_set_log_mask (0); break;
case 2: dds_set_log_mask (DDS_LC_TRACE); break;
}
DDS_FATAL ("oops\n");
}
sigaction (SIGABRT, &oldaction, NULL);
CU_ASSERT (0);
}
#else
(void) local;
(void) mode;
(void) expect_in_trace;
#endif
}

59
src/ddsrt/tests/retcode.c Normal file
View file

@ -0,0 +1,59 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include <string.h>
#include "CUnit/Theory.h"
#include "dds/ddsrt/retcode.h"
CU_TheoryDataPoints(ddsrt_retcode, unknown) = {
CU_DataPoints(dds_return_t,
DDS_RETCODE_NOT_ALLOWED_BY_SECURITY-1,
-(DDS_RETCODE_NOT_ALLOWED_BY_SECURITY-1),
DDS_XRETCODE_BASE,
-DDS_XRETCODE_BASE,
DDS_RETCODE_NOT_FOUND-1,
-(DDS_RETCODE_NOT_FOUND-1),
INT32_MAX,
-INT32_MAX,
INT32_MIN)
};
CU_Theory((dds_return_t ret), ddsrt_retcode, unknown)
{
CU_ASSERT_STRING_EQUAL(dds_strretcode(ret), "Unknown return code");
}
CU_TheoryDataPoints(ddsrt_retcode, spotchecks) = {
CU_DataPoints(dds_return_t,
DDS_RETCODE_OK,
-DDS_RETCODE_OK,
DDS_RETCODE_NOT_ALLOWED_BY_SECURITY,
-DDS_RETCODE_NOT_ALLOWED_BY_SECURITY,
DDS_RETCODE_IN_PROGRESS,
-DDS_RETCODE_IN_PROGRESS,
DDS_RETCODE_NOT_FOUND,
-DDS_RETCODE_NOT_FOUND),
CU_DataPoints(const char *,
"Success",
"Success",
"Not Allowed By Security",
"Not Allowed By Security",
"Operation in progress",
"Operation in progress",
"Not found",
"Not found")
};
CU_Theory((dds_return_t ret, const char *exp), ddsrt_retcode, spotchecks)
{
CU_ASSERT_STRING_EQUAL(dds_strretcode(ret), exp);
}

View file

@ -115,7 +115,7 @@ CU_TheoryDataPoints(ddsrt_thread, create_and_join) = {
30303, 40404)
};
CU_Theory((ddsrt_sched_t sched, int32_t *prio, uint32_t exp), ddsrt_thread, create_and_join)
CU_Theory((ddsrt_sched_t sched, int32_t *prio, uint32_t exp), ddsrt_thread, create_and_join, .timeout=60)
{
int skip = 0;
uint32_t res = 50505;

View file

@ -11,9 +11,6 @@
#
set(CMAKE_INSTALL_TOOLSDIR "${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}/tools")
add_subdirectory(pubsub)
if(BUILD_CONFTOOL)
add_subdirectory(config)
endif()
add_subdirectory(ddsls)
if(BUILD_IDLC)
add_subdirectory(ddsperf)

View file

@ -1,29 +0,0 @@
#
# Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
# v. 1.0 which is available at
# http://www.eclipse.org/org/documents/edl-v10.php.
#
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#
find_package(Java 1.8 REQUIRED)
include(UseJava)
set(CONFJAR_TARGET "${CMAKE_PROJECT_NAME_SMALL}conf")
#set(CMAKE_JAVA_COMPILE_FLAGS "-source" "1.8" "-target" "1.8" -Xlint:deprecation)
file(GLOB_RECURSE JAVA_SOURCES LIST_DIRECTORIES true *.java)
set(RESOURCES metaconfig.xml metaconfig.xsd )
add_jar(${CONFJAR_TARGET} ${JAVA_SOURCES} ${RESOURCES} ENTRY_POINT org.eclipse.cyclonedds.config.CycloneConfig)
#add_test(NAME TestHelloWorld COMMAND ${Java_JAVA_EXECUTABLE} -cp ${_jarFile} HelloWorld)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/${CONFJAR_TARGET}.jar"
DESTINATION "${CMAKE_INSTALL_TOOLSDIR}"
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
COMPONENT dev)

View file

@ -1,471 +0,0 @@
: # -*- perl -*-
eval 'exec perl -w -S $0 "$@"'
if 0;
use strict;
# NOTES:
# - very fragile - and very sensitive to input formatting
# - default value may not contain a semicolon
#
# UGLINESSES:
# - knowledge of conversion functions in here
# - hard definitions of enums in here
# - negated_boolean is A BIT WEIRD and special-cased
# - some other hard-coded knowledge of the top level nodes
# - some hard-coded overrides for defaults
$|=1;
my %typehint2xmltype = ("____" => "____",
"networkAddress" => "String",
"partitionAddress" => "String",
"networkAddresses" => "String",
"ipv4" => "String",
"boolean" => "Boolean",
"negated_boolean" => "Boolean",
"boolean_default" => "Enum",
"string" => "String",
"tracingOutputFileName" => "String",
"verbosity" => "Enum",
"tracemask" => "String",
"peer" => "String",
"float" => "Float",
"int" => "Int",
"int32" => "Int",
"uint" => "Int",
"uint32" => "Int",
"natint" => "Int",
"natint_255" => "Int",
"domainId" => "String",
"participantIndex" => "String",
"port" => "Int",
"dyn_port" => "Int",
"duration_inf" => "String",
"duration_ms_1hr" => "String",
"duration_ms_1s" => "String",
"duration_100ms_1hr" => "String",
"duration_us_1s" => "String",
"memsize" => "String",
"bandwidth" => "String",
"standards_conformance" => "Enum",
"locators" => "Enum",
"service_name" => "String",
"sched_class" => "Enum",
"cipher" => "Enum",
"besmode" => "Enum",
"retransmit_merging" => "Enum",
"sched_prio_class" => "Enum",
"sched_class" => "Enum",
"maybe_int32" => "String",
"maybe_memsize" => "String",
"maybe_duration_inf" => "String",
"allow_multicast" => "String",
"transport_selector" => "String",
"many_sockets_mode" => "Enum",
"xcheck" => "String",
"min_tls_version" => "String");
my %typehint2unit = ("duration_inf" => "duration_inf",
"duration_ms_1hr" => "duration",
"duration_100ms_1hr" => "duration",
"duration_ms_1s" => "duration",
"duration_us_1s" => "duration",
"bandwidth" => "bandwidth",
"memsize" => "memsize",
"maybe_memsize" => "memsize",
"maybe_duration_inf" => "duration_inf");
my %enum_values = ("locators" => "local;none",
"standards_conformance" => "lax;strict;pedantic",
"verbosity" => "finest;finer;fine;config;info;warning;severe;none",
"besmode" => "full;writers;minimal",
"retransmit_merging" => "never;adaptive;always",
"sched_prio_class" => "relative;absolute",
"sched_class" => "realtime;timeshare;default",
"cipher" => "null;blowfish;aes128;aes192;aes256",
"boolean_default" => "false;true;default",
"many_sockets_mode" => "false;true;single;none;many");
my %range = ("port" => "1;65535",
"dyn_port" => "-1;65535",
"general_cfgelems/startupmodeduration" => "0;60000",
"natint_255" => "0;255",
"duration_ms_1hr" => "0;1hr",
"duration_100ms_1hr" => "100ms;1hr",
"duration_ms_1s" => "0;1s",
"duration_us_1s" => "0;1s");
my %unit_blurb = ("bandwidth" => "\n<p>The unit must be specified explicitly. Recognised units: <i>X</i>b/s, <i>X</i>bps for bits/s or <i>X</i>B/s, <i>X</i>Bps for bytes/s; where <i>X</i> is an optional prefix: k for 10<sup>3</sup>, Ki for 2<sup>10</sup>, M for 10<sup>6</sup>, Mi for 2<sup>20</sup>, G for 10<sup>9</sup>, Gi for 2<sup>30</sup>.</p>",
"memsize" => "\n<p>The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2<sup>10</sup> bytes), MB & MiB (2<sup>20</sup> bytes), GB & GiB (2<sup>30</sup> bytes).</p>",
"duration" => "\n<p>The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.</p>",
"duration_inf" => "\n<p>Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.</p>");
while (my ($k, $v) = each %typehint2xmltype) {
die "script error: values of enum type $k unknown\n" if $v eq "Enum" && $enum_values{$k} eq "";
}
# Configurator can't handle UINT32_MAX ... instead of fixing it, just use a different
# default for the rare ones that have a problem (that works as long as there is no
# practical difference between the two)
my %default_overrides = ("multiple_recv_threads_attrs/maxretries" => 2000000000);
my ($name, $table, $kind, $subtable, $multiplicity, $defaultvalue, $typehint, $description);
my %tab2elems;
my %elem;
my %desc;
my %typehint_seen;
my $gobbling_description;
my $skip_lite;
my $in_table;
my $rest;
my $deprecated;
############################
sub clean_description {
my ($desc) = @_;
$desc =~ s/^\s*BLURB\s*\(\s*//s;
$desc =~ s/^\s*"//s;
$desc =~ s/\s*"(\s*\))? *(\}\s*,\s*$)?$//s;
$desc =~ s/\\"/"/g;
$desc =~ s/\\n\s*\\/\n/g;
$desc =~ s/\\\\/\\/g;
$desc =~ s/\n\n/\n/g;
# should fix the source ...
$desc =~ s/DDSI2E?/Cyclone DDS/g;
return $desc;
}
sub store_entry {
$name =~ s/\|.*//; # aliases are not visible in osplconf
my $ltable = lc $table;
my $lname = lc $name;
if (not exists $tab2elems{$ltable}) {
$tab2elems{$ltable} = $name;
} else {
$tab2elems{$ltable} .= ";$name";
}
$elem{"$ltable/$lname"} = "$kind;$subtable;$multiplicity;$defaultvalue;$typehint";
my $ub = exists $typehint2unit{$typehint} && exists $unit_blurb{$typehint2unit{$typehint}} ? $unit_blurb{$typehint2unit{$typehint}} : "";
$desc{"$ltable/$lname"} = clean_description($description).$ub;
die "error: no mapping defined for type $typehint\n" if $typehint2xmltype{$typehint} eq "";
$typehint_seen{$typehint} = 1;
#printf "%s - $s\n", "$ltable/$lname", $elem{"$ltable/lname"};
#$typehint = "";
}
sub print_description {
my ($desc, $indent) = @_;
print "$indent <comment><![CDATA[\n";
print "$desc\n";
print "$indent ]]></comment>\n";
}
sub kind_to_kstr {
my ($kind, $typehint, $table, $name, $isroot) = @_;
if ($isroot) {
die unless $kind eq "GROUP";
return "rootElement";
} elsif ($kind eq "GROUP" || $kind eq "MGROUP") {
return "element";
} elsif ($kind eq "ATTR") {
return "attribute$typehint2xmltype{$typehint}";
} elsif ($kind eq "LEAF") {
return "leaf$typehint2xmltype{$typehint}";
} else {
die "error: $kind unrecognized kind ($table/$name)\n";
}
}
sub transform_default {
my (@fs) = @_;
(my $tmp = $fs[3]) =~ s/^"(.*)"$/$1/;
if ($fs[4] ne "negated_boolean") {
return $tmp;
} else {
my %map = ("true" => "false", "false" => "true");
return $map{lc $tmp};
}
}
sub conv_to_xml {
my ($table, $name, $indent, $prefix, $isroot, $force_min_occ_1) = @_;
#, fs,vs,vsn,kstr,ts,tsi,tsn,i,min_occ,max_occ,rr,req) { # fs,vs,kstr,... are locals
my $lctn = lc "$table/$name";
my @fs = split /;/, $elem{$lctn};
#print "$table/$name - \n"; for (my $i = 0; $i < @fs; $i++) { print " - $i $fs[$i]\n" }
my $kstr = kind_to_kstr($fs[0], $fs[4], $table, $name, $isroot);
my ($min_occ, $max_occ);
if ($fs[2] =~ /MAX/) {
$min_occ = $max_occ = 0;
} elsif ($fs[2] == 0 || $fs[2] == 1) {
# multiplicity = 0 => special case, treat as-if 1
# multiplicity = 1 => required if no default
# force_min_occ_1 so we can mark "Domain" as required and have it
# show up in the config editor when creating a new file
if ($force_min_occ_1) {
$min_occ = 1;
} elsif ($fs[0] eq "GROUP" || $fs[0] eq "MGROUP") {
$min_occ = 0;
} elsif ($fs[3] eq "" || $fs[3] eq "NULL") {
$min_occ = 1;
} else {
$min_occ = 0;
}
$max_occ = 1;
} else {
$min_occ = 0; $max_occ = $fs[2];
}
if ($fs[0] eq "ATTR") {
my $req = ($min_occ == 0) ? "false" : "true";
print "$indent<$kstr name=\"$name\" required=\"$req\">\n";
} else {
print "$indent<$kstr name=\"$name\" minOccurrences=\"$min_occ\" maxOccurrences=\"$max_occ\">\n";
}
print_description ("$prefix$desc{$lctn}", $indent);
# enum, int ranges
if (exists $enum_values{$fs[4]}) {
my @vs = split /;/, $enum_values{$fs[4]};
print "$indent <value>$_</value>\n" for @vs;
}
my $rr = exists $range{$lctn} ? $range{$lctn} : "";
if ($rr eq "" && exists $range{$fs[4]}) { $rr = $range{$fs[4]}; }
if ($rr ne "") {
my @vs = split /;/, $rr;
print "$indent <minimum>$vs[0]</minimum>\n";
print "$indent <maximum>$vs[1]</maximum>\n";
}
# remarkably, osplconf can't deal with strings for which no maximum
# length is specified, even though it accepts unlimited length
# strings ...
if ($typehint2xmltype{$fs[4]} eq "String") {
print "$indent <maxLength>0</maxLength>\n";
}
# default not applicable to GROUPs
if ($fs[0] ne "GROUP" && $fs[0] ne "MGROUP") {
my $defover = exists $default_overrides{$lctn} ? $default_overrides{$lctn} : "";
if ($defover ne "") {
print "$indent <default>$defover</default>\n";
} elsif ($fs[3] eq "" || $fs[3] eq "NULL") {
print "$indent <default></default>\n";
} else {
print "$indent <default>".transform_default(@fs)."</default>\n";
}
}
# recurse into subtables if any (except when it is the root: rootElement needs
# special treatment
if (!$isroot && $fs[1] ne "") {
my @ts = sort (split /,/, $fs[1]);
conv_table_to_xml($_, "$indent ", $prefix, 0, 0) for @ts;
}
print "$indent</$kstr>\n";
}
sub conv_table_to_xml {
my ($table, $indent, $prefix, $isroot, $force_min_occ_1) = @_;
return unless exists $tab2elems{$table};
my @ns = sort (split /;/, $tab2elems{$table});
conv_to_xml($table, $_, $indent, ($table eq "unsupp_cfgelems") ? "<b>Internal</b>" : $prefix, $isroot, $force_min_occ_1) for @ns;
}
while (<>) {
if ($gobbling_description) {
$description .= $_;
#print " .. $_\n";
}
if ($gobbling_description && /(^|")(\s*\)) *\} *, *$/) {
$gobbling_description = 0;
store_entry() unless $deprecated;
next;
}
if ($gobbling_description) {
next;
}
if (/^[ \t]*(#[ \t]*(if|ifdef|ifndef|else|endif).*)?$/) { # skip empty lines, preproc
next;
}
if (/^ *END_MARKER *$/) {
if (!$in_table) {
warn "END_MARKER seen while not in a table";
}
$in_table = 0;
#print "END_MARKER $table\n";
next;
}
if (/^static +const +struct +cfgelem +([A-Za-z_0-9]+)\s*\[/) {
$in_table = 1;
$table = $1;
#print "TABLE $table\n";
next;
}
if ($in_table && /^ *WILDCARD *, *$|^ *\{ *(MOVED) *\(/) {
next;
}
# Recognise all "normal" entries: attributes, groups, leaves and
# leaves with attributes. This doesn't recognise the ones used for the
# root groups: those are dealt with by the next pattern
if ($in_table && /^ *\{ *((?:DEPRECATED_)?(?:ATTR|GROUP|GROUP_W_ATTRS|MGROUP|LEAF|LEAF_W_ATTRS)) *\(/) {
$rest = $_;
# extract kind
$rest =~ s/^ *\{ *((?:DEPRECATED_)?(?:ATTR|GROUP|GROUP_W_ATTRS|MGROUP|LEAF|LEAF_W_ATTRS)) *\( *(.*)/$2/;
$kind = $1;
$deprecated = ($kind =~ s/^DEPRECATED_//);
# extract name + reference to subtable
$rest =~ s/\"([A-Za-z_0-9|]+)\" *(.*)/$2/;
$name = $1;
my ($subelems, $subattrs) = ("", "");
if ($kind eq "GROUP" || $kind eq "GROUP_W_ATTRS" || $kind eq "MGROUP") {
$rest =~ s/, *([A-Za-z_0-9]+) *(.*)/$2/;
$subelems = $1;
}
if ($kind eq "LEAF_W_ATTRS" || $kind eq "GROUP_W_ATTRS" || $kind eq "MGROUP") {
$rest =~ s/, *([A-Za-z_0-9]+) *(.*)/$2/;
$subattrs = $1;
}
$subtable = "";
if ($subelems ne "") { $subtable = $subelems; }
if ($subattrs ne "") {
if ($subtable ne "") { $subtable = "$subtable,$subattrs"; }
else { $subtable = $subattrs; }
}
$rest =~ s/ *\) *, *//;
#print " kind $kind name $name subtable $subtable -- $rest\n";
# don't care about the distinction between GROUP/LEAF and
# GROUP/LEAF_W_ATTRS in the remainer of the code: we simply
# rely on subtable.
$kind =~ s/_W_ATTRS//;
}
# Root groups: use a special trick, which allows them to do groups
# with attributes. Which the DDSI2 proper doesn't use, but which the
# service configuration stuff does rely on.
if ($in_table && /^ *\{ *"([A-Za-z_0-9|]+)" *, */) {
$rest = $_;
# root elements are all groups, formatted as: <name>, <subelems>,
# <attrs>, NODATA, description. They're therefore pretty easy to
# parse.
$kind = "GROUP";
$rest =~ s/^ *\{ *\"([A-Za-z_0-9|]+)\" *, *(.*)/$2/;
$name = $1;
# then follow the sub-elements and the attributes
$rest =~ s/([A-Za-z_0-9]+) *, *(.*)/$2/;
my $subelems = $1;
$rest =~ s/([A-Za-z_0-9]+) *, *(.*)/$2/;
my $subattrs = $1;
# then we require NODATA (could do this in the pattern also)
die "error: NODATA expected" unless $rest =~ /^NODATA *,/;
# multiplicity is hard coded: we want to allow multiple ddsi2 services
$multiplicity = 0;
$subtable = "";
if ($subelems ne "NULL") { $subtable = $subelems; }
if ($subattrs ne "NULL") {
if ($subtable ne "") { $subtable = "$subtable,$subattrs"; }
else { $subtable = $subattrs; }
}
$rest =~ s/([A-Za-z_0-9]+) *, *(.*)/$2/;
}
# Extract stuff specific to ATTRs, LEAFs and MGROUPs
if ($in_table && ($kind eq "ATTR" || $kind eq "LEAF" || $kind eq "MGROUP")) {
# extract multiplicity
$rest =~ s/([0-9]+|U?INT(?:16|32|64)?_MAX) *, *(.*)/$2/;
$multiplicity = $1;
# extract default value
$rest =~ s/(\"(?:[^\"]*)\"|NULL|0) *, *(.*)/$2/;
$defaultvalue = $1;
if ($defaultvalue eq "0") { $defaultvalue = "NULL"; }
# skip reference to internal name (either ABSOFF(field),
# RELOFF(field,field) or <int>,<int> (the latter being used by
# "verbosity")
$rest =~ s/(ABSOFF *\( *[A-Za-z_0-9.]+ *\)|RELOFF *\( *[A-Za-z_0-9.]+ *, *[A-Za-z_0-9]+ *\)|[0-9]+ *, *[0-9]+) *, *//;
# skip init function
$rest =~ s/([A-Za-z_0-9]+|0) *, *//;
# type hint from conversion function
$rest =~ s/(uf_(?:[A-Za-z_0-9]+)|NULL|0) *, *(.*)/$2/;
$typehint = $1;
$typehint =~ s/^uf_//;
# accept typehint = NULL for a LEAF_WITH_ATTRS: there is no defined
# "syntax" for groups that have only attributes, pretending it is a
# group because that causes us to emit an "element" and not a
# "leaf".
if ($typehint eq "0" || $typehint eq "NULL") {
$kind = "GROUP";
$typehint = "____";
}
# skip free, print functions
$rest =~ s/([A-Za-z_0-9]+|0) *, *([A-Za-z_0-9]+|0) *, *//;
#print " .. multiplicity $multiplicity default $defaultvalue typehint $typehint\n";
}
# Extract description (or NULL, if not to be included in the configurator XML)
if ($in_table) {
#print " .. $rest\n";
# description or NULL
if ($rest =~ /NULL *\} *, *$/) {
# no description - discard this one/simply continue with next one
} elsif ($rest =~ /(?:BLURB\s*\(\s*)?(".*")(?:\s*\))? *\} *, *$/) {
# description ending on same line
$description = $1;
store_entry() unless $deprecated;
} else {
# strip the quotes &c. once the full text has been gathered
$description = $rest;
$gobbling_description = 1;
}
#print " .. gobbling $gobbling_description";
next;
}
}
#print "$tab2elems{cyclonedds_root_cfgelems}\n";
my @rootnames = split /;/, $tab2elems{cyclonedds_root_cfgelems};
die "error: cyclonedds_root_cfgelems has no or multiple entries\n" if @rootnames != 1;
die "error: root_cfgelems doesn't exist\n" unless exists $tab2elems{root_cfgelems};
# Override the type for ControlTopic/Deaf, .../Mute so that an empty
# string is allowed by the configuration validation in spliced
# (easier than adding a boolean_or_empty to DDSI2 for a quick hack)
#if (elem["control_topic_cfgelems/deaf"] == "" || elem["control_topic_cfgelems/mute"] == "") {
# print FILENAME": error: control_topic_cfgelems/{deaf,mute} missing" > "/dev/stderr";
# exit 1;
#}
#elem["control_topic_cfgelems/deaf"] = "LEAF;;1;\"false\";string";
#elem["control_topic_cfgelems/mute"] = "LEAF;;1;\"false\";string";
print << 'EOT';
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright(c) 2006 to 2019 ADLINK Technology Limited and others
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0 which is available at
http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
v. 1.0 which is available at
http://www.eclipse.org/org/documents/edl-v10.php.
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
===
generated from src/core/ddsi/src/q_config.c using excx.pl
-->
<splice_meta_config version="1.0">
<!--xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.splice-dds.org/splice_metaconfig.xsd"-->
EOT
conv_table_to_xml("cyclonedds_root_cfgelems", " ", "", 1, 0);
conv_table_to_xml("root_cfgelems", " ", "", 0, 1);
print << 'EOT';
</splice_meta_config>
EOT
while (my ($k, $v) = each %typehint_seen) {
warn "script warning: type mapping defined for $k but not used" if $v == 0;
}

File diff suppressed because it is too large Load diff

View file

@ -1,289 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0 which is available at
http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
v. 1.0 which is available at
http://www.eclipse.org/org/documents/edl-v10.php.
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="attributeLong">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="comment"/>
<xs:element minOccurs="0" name="minimum" type="xs:long"/>
<xs:element minOccurs="0" name="maximum" type="xs:long"/>
<xs:element name="default" type="xs:long"/>
</xs:all>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="required" type="xs:boolean" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="attributeSize">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="comment"/>
<xs:element minOccurs="0" name="minimum" type="xs:string"/>
<xs:element minOccurs="0" name="maximum" type="xs:string"/>
<xs:element name="default" type="xs:string"/>
</xs:all>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="required" type="xs:boolean" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="attributeString">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="comment"/>
<xs:element name="maxLength" type="xs:unsignedInt"/>
<xs:element name="default" type="xs:string"/>
</xs:all>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="required" type="xs:boolean" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="attributeBoolean">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="comment"/>
<xs:element name="default" type="xs:boolean"/>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="attributeEnum">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element minOccurs="0" ref="comment"/>
<xs:element maxOccurs="unbounded" name="value" type="xs:string"/>
<xs:element name="default" type="xs:string"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="attributeDouble">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="comment"/>
<xs:element minOccurs="0" name="minimum" type="xs:double"/>
<xs:element minOccurs="0" name="maximum" type="xs:double"/>
<xs:element name="default" type="xs:double"/>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="attributeFloat">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="comment"/>
<xs:element minOccurs="0" name="minimum" type="xs:float"/>
<xs:element minOccurs="0" name="maximum" type="xs:float"/>
<xs:element name="default" type="xs:float"/>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="attributeInt">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="comment"/>
<xs:element minOccurs="0" name="minimum" type="xs:int"/>
<xs:element minOccurs="0" name="maximum" type="xs:int"/>
<xs:element name="default" type="xs:int"/>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="comment" type="xs:string"/>
<xs:element name="element">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element minOccurs="0" ref="comment"/>
<xs:element ref="attributeString"/>
<xs:element ref="leafSize"/>
<xs:element ref="leafEmpty"/>
<xs:element ref="leafString"/>
<xs:element ref="leafEnum"/>
<xs:element ref="leafBoolean"/>
<xs:element ref="leafInt"/>
<xs:element ref="element"/>
<xs:element ref="leafFloat"/>
</xs:choice>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="minOccurrences" type="xs:unsignedInt" use="optional"/>
<xs:attribute name="maxOccurrences" type="xs:unsignedInt" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="leafBoolean">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="comment"/>
<xs:element name="default" type="xs:boolean"/>
</xs:all>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="minOccurrences" type="xs:unsignedInt" use="optional"/>
<xs:attribute name="maxOccurrences" type="xs:unsignedInt" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="leafEmpty">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element minOccurs="0" ref="comment"/>
<xs:element ref="attributeLong"/>
<xs:element ref="attributeString"/>
<xs:element ref="attributeBoolean"/>
<xs:element ref="attributeDouble"/>
<xs:element ref="attributeEnum"/>
<xs:element ref="attributeFloat"/>
<xs:element ref="attributeInt"/>
<xs:element ref="attributeSize"/>
</xs:choice>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="minOccurrences" type="xs:unsignedInt" use="optional"/>
<xs:attribute name="maxOccurrences" type="xs:unsignedInt" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="leafEnum">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element minOccurs="0" ref="comment"/>
<xs:element maxOccurs="unbounded" name="value" type="xs:string"/>
<xs:element name="default" type="xs:string"/>
</xs:choice>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="minOccurrences" type="xs:unsignedInt" use="optional"/>
<xs:attribute name="maxOccurrences" type="xs:unsignedInt" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="leafFloat">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="comment"/>
<xs:element minOccurs="0" name="minimum" type="xs:decimal"/>
<xs:element minOccurs="0" name="maximum" type="xs:decimal"/>
<xs:element name="default" type="xs:decimal"/>
</xs:all>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="minOccurrences" type="xs:unsignedInt" use="optional"/>
<xs:attribute name="maxOccurrences" type="xs:unsignedInt" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="leafDouble">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="comment"/>
<xs:element minOccurs="0" name="minimum" type="xs:double"/>
<xs:element minOccurs="0" name="maximum" type="xs:double"/>
<xs:element name="default" type="xs:double"/>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="leafLong">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="comment"/>
<xs:element minOccurs="0" name="minimum" type="xs:long"/>
<xs:element minOccurs="0" name="maximum" type="xs:long"/>
<xs:element name="default" type="xs:long"/>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="leafSize">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="comment"/>
<xs:element minOccurs="0" name="minimum" type="xs:string"/>
<xs:element minOccurs="0" name="maximum" type="xs:string"/>
<xs:element name="default" type="xs:string"/>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="leafInt">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="comment"/>
<xs:element minOccurs="0" name="minimum" type="xs:unsignedInt"/>
<xs:element minOccurs="0" name="maximum" type="xs:unsignedInt"/>
<xs:element name="default" type="xs:unsignedInt"/>
</xs:all>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="minOccurrences" type="xs:unsignedInt" use="optional"/>
<xs:attribute name="maxOccurrences" type="xs:unsignedInt" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="leafString">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="comment"/>
<xs:element name="maxLength" type="xs:unsignedInt"/>
<xs:element name="default" type="xs:string"/>
</xs:all>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="minOccurrences" type="xs:unsignedInt" use="optional"/>
<xs:attribute name="maxOccurrences" type="xs:unsignedInt" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="rootElement">
<xs:complexType>
<xs:all minOccurs="1" maxOccurs="1">
<xs:element ref="element"/>
</xs:all>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="service">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element minOccurs="0" ref="comment"/>
<xs:element ref="attributeLong"/>
<xs:element ref="attributeString"/>
<xs:element ref="leafInt"/>
<xs:element ref="leafFloat"/>
<xs:element ref="leafString"/>
<xs:element ref="leafEnum"/>
<xs:element ref="leafEmpty"/>
<xs:element ref="leafSize"/>
<xs:element ref="element"/>
</xs:choice>
<xs:attribute name="type" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="CMSOAPService"/>
<xs:enumeration value="DurabilityService"/>
<xs:enumeration value="NetworkingService"/>
<xs:enumeration value="SpliceService"/>
<xs:enumeration value="UserClockService"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="minOccurrences" type="xs:unsignedInt" use="optional"/>
<xs:attribute name="maxOccurrences" type="xs:unsignedInt" use="optional"/>
<xs:attribute name="isRootService" type="xs:boolean"/>
</xs:complexType>
</xs:element>
<xs:element name="serviceCommon">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element minOccurs="0" ref="comment"/>
<xs:element ref="attributeLong"/>
<xs:element ref="attributeString"/>
<xs:element ref="leafInt"/>
<xs:element ref="leafFloat"/>
<xs:element ref="leafString"/>
<xs:element ref="leafEnum"/>
<xs:element ref="leafEmpty"/>
<xs:element ref="leafSize"/>
<xs:element ref="element"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="splice_meta_config">
<xs:complexType>
<xs:sequence>
<xs:element ref="rootElement"/>
<xs:element ref="serviceCommon"/>
<xs:element maxOccurs="unbounded" ref="service"/>
</xs:sequence>
<xs:attribute name="version" type="xs:decimal" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>

View file

@ -1,51 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.common.controller;
/**
* Represents a result for assignment of a value to a certain field.
*
* @date Nov 25, 2004
*/
public class AssignmentResult{
private boolean valid;
private String errorMessage;
/**
* Constructs a new AssignMentResult.
*
* @param _success true if validation succeeded, false otherwise.
* @param _errorMessage null when validation succeeded, the failure
* reason otherwise.
*/
public AssignmentResult(boolean _success, String _errorMessage){
valid = _success;
errorMessage = _errorMessage;
}
/**
* Provides access to errorMessage.
*
* @return Returns the errorMessage.
*/
public String getErrorMessage() {
return errorMessage;
}
/**
* Provides access to valid.
*
* @return Returns the valid.
*/
public boolean isValid() {
return valid;
}
}

View file

@ -1,404 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
/**
* Contains all SPLICE DDS C&M Tooling utilities.
*/
package org.eclipse.cyclonedds.common.util;
import java.awt.Color;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Iterator;
import java.util.Properties;
import org.eclipse.cyclonedds.common.view.CommonFileChooser;
/**
* Supplies a generic configuration utility for all kinds of applications.
* Before using the load or loadDefault function must be called.
*
* @date Oct 25, 2004
*/
public class Config {
/**
* The current configuration.
*/
private Properties config = null;
/**
* The location of the configuration.
*/
private File configFile = null;
/**
* The validator.
*/
private ConfigValidator validator = null;
private CommonFileChooser chooser = null;
private static volatile Config instance = null;
private static Color warningColor = null;
private static Color errorColor = null;
private static Color sensitiveColor = null;
private static Color inactiveColor = null;
private static Color activeColor = null;
private static Color inputColor = null;
private static Color incorrectColor = null;
private Config(){}
public static Config getInstance(){
if(instance == null){
instance = new Config();
}
return instance;
}
/**
* Assigns the supplied validator to the configuration. It will use this
* validator when calling: - load --> call validateValue on each found key.
* - loadDefault --> call validateValue on each found key. - getProperty ->
* call getDefaultValue when a supplied kay has no value. - setProperty -->
* call isValueValid on the supplied key/value combination.
*
* @param _validator
* The validator to assign.
*/
public void setValidator(ConfigValidator _validator){
validator = _validator;
}
/**
* Provides access to the current configuration validator.
*
* @return The current validator or null if none has been assigned.
*/
public ConfigValidator getValidator(){
return validator;
}
/**
* Provides access to the current configuration properties.
*
* @return The current config properties or null if none has been assigned.
*/
public Properties getConfig() {
return config;
}
/**
* Loads the configuration from the supplied URI.
*
* @param uri
* The URI to load the configuration from.
* @return true if the configuration was successfully loaded, false
* otherwise.
*/
public boolean load(String uri) {
String value;
boolean result = false;
FileInputStream fis = null;
try {
uri = uri.replaceAll(" ", "%20");
URI location = new URI(uri);
configFile = new File(location);
config = new Properties();
fis = new FileInputStream(configFile);
config.load(fis);
Properties newConfig = new Properties();
if(validator != null){
for (Object key : config.keySet()) {
value = config.getProperty((String) key);
value = validator.getValidatedValue((String) key, value);
if (value != null) {
newConfig.setProperty((String) key, value);
}
}
}
config.putAll(newConfig);
result = true;
} catch (FileNotFoundException e1) {
Report.getInstance().writeErrorLog("Configuration file could not be found.");
} catch (IOException e1) {
Report.getInstance().writeErrorLog("Configuration file could not be read.");
} catch (URISyntaxException e) {
Report.getInstance().writeErrorLog("Supplied URI not valid.");
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException ie) {
Report.getInstance().writeErrorLog("Configuration file could not be read.");
}
}
}
return result;
}
/**
* Provides access to the value of the supplied property.
*
* @param key
* The name of the property.
* @return The value of the property or null if it was not available.
*/
public String getProperty(String key){
String result = null;
if(config != null){
if(config.containsKey(key)){
result = config.getProperty(key);
} else if(validator != null){
result = validator.getDefaultValue(key);
if(result != null){
config.setProperty(key, result);
}
}
}
return result;
}
/**
* Assigns the supplied value to the supplied property.
*
* @param key
* The name of the property.
* @param value
* The value of the property.
* @return true if it could be assigned, false otherwise.
*/
public boolean setProperty(String key, String value){
boolean result = false;
if(config != null){
if(validator != null){
result = validator.isValueValid(key, value);
if(result){
config.setProperty(key, value);
this.store();
}
} else {
config.setProperty(key, value);
this.store();
}
result = true;
}
return result;
}
public boolean isPropertyValid(String key, String value){
boolean result = false;
if((config != null) && (validator != null)){
result = validator.isValueValid(key, value);
}
return result;
}
/**
* Removes the supplied property from the configuration.
*
* @param key
* The name of the property to remove.
* @return true if succeeded, false otherwise.
*/
public boolean removeProperty(String key){
boolean result = false;
if(config != null){
Object value = config.remove(key);
if(value != null){
result = true;
}
}
return result;
}
/**
* Prints the configuration to screen.
*/
public void list(){
if(config != null){
config.list(System.out);
}
}
/**
* Stores the configuration to disk.
*
* @return true if succeeded, false otherwise.
*/
public boolean store(){
boolean result = false;
FileOutputStream fos = null;
if(config != null){
try {
fos = new FileOutputStream(configFile);
config.store(fos, null);
result = true;
} catch (IOException e) {
Report.getInstance().writeErrorLog("Configuration could not be saved.");
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException ie) {
Report.getInstance().writeErrorLog("Configuration could not be saved.");
}
}
}
}
return result;
}
/**
* Stores the configuration to the supplied uri.
*
* @return true if succeeded, false otherwise.
*/
public boolean store(String uri){
boolean result = false;
FileOutputStream fos = null;
if(config != null){
try {
Report.getInstance().writeInfoLog("Storing configuration to URI: " +
configFile.toURI().getScheme() +
configFile.toURI().getPath() + ".");
uri = uri.replaceAll(" ", "%20");
URI outURI = new URI(uri);
File outFile = new File(outURI);
boolean fileCreated = true;
if(!(outFile.exists())){
fileCreated = outFile.createNewFile();
}
if (fileCreated) {
fos = new FileOutputStream(outFile);
config.store(fos, null);
} else {
Report.getInstance().writeErrorLog("Configuration could not be saved. file could not be created");
result = false;
}
} catch (IOException e) {
Report.getInstance().writeErrorLog("Configuration could not be saved.");
} catch (URISyntaxException e) {
Report.getInstance().writeErrorLog("Configuration could not be saved.");
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException ie) {
Report.getInstance().writeErrorLog("Configuration could not be saved.");
}
}
}
}
return result;
}
public CommonFileChooser getFileChooser(){
if(this.chooser == null){
this.chooser = new CommonFileChooser(".");
}
return this.chooser;
}
public static Color getErrorColor(){
if(errorColor == null){
int r = Integer.parseInt("a0", 16);
int g = Integer.parseInt("20", 16);
int b = Integer.parseInt("20", 16);
r = Integer.parseInt("ff", 16);
g = Integer.parseInt("40", 16);
b = Integer.parseInt("40", 16);
errorColor = new Color(r, g, b);
}
return errorColor;
}
public static Color getWarningColor(){
if(warningColor == null){
int r = Integer.parseInt("c0", 16);
int g = Integer.parseInt("80", 16);
int b = Integer.parseInt("00", 16);
warningColor = new Color(r, g, b);
}
return warningColor;
}
public static Color getSensitiveColor(){
if(sensitiveColor == null){
int r = Integer.parseInt("70", 16);
int g = Integer.parseInt("e0", 16);
int b = Integer.parseInt("70", 16);
sensitiveColor = new Color(r, g, b);
}
return sensitiveColor;
}
public static Color getInactiveColor(){
if(inactiveColor == null){
int r = Integer.parseInt("70", 16);
int g = Integer.parseInt("70", 16);
int b = Integer.parseInt("7a", 16);
inactiveColor = new Color(r, g, b);
}
return inactiveColor;
}
public static Color getActiveColor(){
if(activeColor == null){
int r = Integer.parseInt("50", 16);
int g = Integer.parseInt("90", 16);
int b = Integer.parseInt("50", 16);
activeColor = new Color(r, g, b);
}
return activeColor;
}
public static Color getInputColor(){
if(inputColor == null){
int r = Integer.parseInt("f0", 16);
int g = Integer.parseInt("90", 16);
int b = Integer.parseInt("00", 16);
inputColor = new Color(r, g, b);
}
return inputColor;
}
public static Color getIncorrectColor(){
if(incorrectColor == null){
int r = Integer.parseInt("ff", 16);
int g = Integer.parseInt("40", 16);
int b = Integer.parseInt("40", 16);
incorrectColor = new Color(r, g, b);
}
return incorrectColor;
}
}

View file

@ -1,55 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.common.util;
/**
* Interface that provides routines for validating configuration.
* Implementations of this interface can guarantee that the configuration for
* an application will be correct.
*
* @date Jan 12, 2005
*/
public interface ConfigValidator {
/**
* Returns the correct value for the supplied key. This function
* checks if the supplied value is valid. If so, return that value. If not
* return a valid one. The Config component calls this routine for each
* key it finds when loading a configuration file.
*
* @param key The key in the configuration.
* @param value The value as it has been found in the confuration file.
* @return A correct value for that key. If null is returned, the Config
* component will remove the key from the configuration.
*/
public String getValidatedValue(String key, String value);
/**
* Returns the default value for the supplied key. This function is called
* by the Config component when an application asks for a property that has
* not been defined.
*
* @param key The key where to resolve the default value of.
* @return The default value for the supplied key.
*/
public String getDefaultValue(String key);
/**
* Checks whether the supplied key/value combination is valid. The Config
* component calls this function when an application sets a property in the
* configuration.
*
* @param key The key of the property.
* @param value The value of the property.
* @return If the combination is valid; true and false otherwise.
*/
public boolean isValueValid(String key, String value);
}

View file

@ -1,89 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.common.util;
import java.awt.Component;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.StringTokenizer;
import java.util.logging.LogManager;
import javax.swing.JOptionPane;
/**
* Base class for tooling initializers. Its responsibilities are to initialize
* logging facilities according to commandline parameters.
*
* @date Sep 1, 2004
*/
public class Initializer {
/**
* Initializes the application, using the configuration that is supplied as
* argument. If the supplied file does not exist or no argument was
* supplied, the default is used. The default is:
* <USER_HOME>/.splice_tooling.properties.
*
* @param args
* The list of arguments supplied by the user. Only the first
* argument is used, the rest will be ignored. The first argument
* must supply the location of a java properties file.
*/
public void initializeConfig(String[] args, ConfigValidator validator){
boolean result = false;
Config.getInstance().setValidator(validator);
if(args.length > 0){
Report.getInstance().writeInfoLog("Reading configuration from " + args[0] + ".");
result = Config.getInstance().load(args[0]);
}
if(!result){
Report.getInstance().writeInfoLog("Default configuration could not be read.");
} else {
String loggingFileName = Config.getInstance().getProperty("logging");
if(loggingFileName != null){
FileInputStream is = null;
try {
is = new FileInputStream(loggingFileName);
LogManager.getLogManager().readConfiguration(is);
}
catch (FileNotFoundException e) {
Report.getInstance().writeInfoLog("Specified logging config file not found. Logging is disabled.");
LogManager.getLogManager().reset();
}
catch (SecurityException e) {
Report.getInstance().writeInfoLog("Specified logging config file not valid. Logging is disabled.");
LogManager.getLogManager().reset();
}
catch (IOException e) {
Report.getInstance().writeInfoLog("Specified logging config file not valid. Logging is disabled.");
LogManager.getLogManager().reset();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ie) {
Report.getInstance().writeInfoLog("Specified logging config file not valid. Logging is disabled.");
LogManager.getLogManager().reset();
}
}
}
} else {
LogManager.getLogManager().reset();
}
}
}
}

View file

@ -1,124 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.common.util;
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
public class Report {
private static Report reportObject = new Report();
static Logger errorLog;
static Logger infoLog;
private String errorLogFile = null;
private int errorSize = 0;
private int errorCount = 0;
private boolean errorAppend = false;
private String infoLogFile = null;
private int infoSize = 0;
private int infoCount = 0;
private boolean infoAppend = false;
private Handler errorHandler;
private Handler infoHandler;
private boolean consoleOutput = false;
/**
* A private Constructor prevents any other class from instantiating.
*
* @return
*/
private Report() {
errorLog = Logger.getAnonymousLogger();
infoLog = Logger.getAnonymousLogger();
}
public static Report getInstance() {
return reportObject;
}
public void initializeInfo(String infoLogFile, int size, int nrOfLogFiles, boolean append) {
this.infoLogFile = infoLogFile;
this.infoSize = size;
this.infoCount = nrOfLogFiles;
this.infoAppend = append;
}
public void initializeError(String errorLogFile, int size, int nrOfLogFiles, boolean append) {
this.errorLogFile = errorLogFile;
this.errorSize = size;
this.errorCount = nrOfLogFiles;
this.errorAppend = append;
}
public void initializeConsole() {
consoleOutput = true;
}
public void writeInfoLog(String message) {
if (!consoleOutput) {
if (infoHandler == null && infoLogFile != null) {
try {
infoHandler = new FileHandler(infoLogFile, infoSize, infoCount, infoAppend);
infoHandler.setFormatter(new SimpleFormatter());
infoLog.addHandler(infoHandler);
LogManager logManager = LogManager.getLogManager();
logManager.reset();
} catch (IOException e) {
System.err.println("Could not redirect error and/or info output.");
}
}
infoLog.info(message);
} else {
System.out.println(message);
}
}
public void writeErrorLog(String message) {
if (!consoleOutput) {
if (errorHandler == null && errorLogFile != null) {
try {
errorHandler = new FileHandler(errorLogFile, errorSize, errorCount, errorAppend);
errorHandler.setFormatter(new SimpleFormatter());
errorLog.addHandler(errorHandler);
LogManager logManager = LogManager.getLogManager();
logManager.reset();
} catch (IOException e) {
System.err.println("Could not redirect error and/or info output.");
}
}
errorLog.log(Level.SEVERE, message);
} else {
System.err.println(message);
}
}
public void CloseHandlers() {
if (errorHandler != null) {
errorHandler.close();
}
if (infoHandler != null) {
infoHandler.close();
}
}
}

View file

@ -1,88 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.common.view;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
/**
*
*
* @date Apr 14, 2005
*/
public class CommonFileChooser extends JFileChooser {
private static final long serialVersionUID = -1440579455652851165L;
private int returnCode;
private JDialog dialog = null;
public CommonFileChooser(String path){
super(path);
}
private JDialog getDialog(){
if(this.dialog == null){
JFrame f = null;
this.dialog = new JDialog(f, "", true);
Container contentPane = this.dialog.getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(this, BorderLayout.CENTER);
this.dialog.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
returnCode = CANCEL_OPTION;
dialog.setVisible(false);
}
});
this.dialog.pack();
}
return this.dialog;
}
@Override
protected void fireActionPerformed(String command) {
super.fireActionPerformed(command);
JDialog myDialog = this.getDialog();
if(APPROVE_SELECTION.equals(command)){
returnCode = APPROVE_OPTION;
myDialog.setVisible(false);
} else if(CANCEL_SELECTION.equals(command)){
returnCode = CANCEL_OPTION;
myDialog.setVisible(false);
}
}
@Override
public int showDialog(Component parent, String title){
JDialog myDialog = this.getDialog();
if(parent != null){
myDialog.setLocationRelativeTo(parent);
}
if(title != null){
myDialog.setTitle(title);
}
myDialog.setVisible(true);
myDialog.toFront();
return returnCode;
}
}

View file

@ -1,324 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
/**
* Contains all SPLICE DDS C&M Tooling common view components.
*/
package org.eclipse.cyclonedds.common.view;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.FlowLayout;
import java.awt.event.*;
import java.util.*;
/**
* This class represents a generic dialog window and is meant to provide a fast and
* simple way of constructing dialog windows.
*
* The window contains a status bar and
* 'OK' and 'Cancel' buttons. By providing NameValuePanel objects, the user can
* fill the dialog window with as many fields as he wishes.
*/
public class DialogWindow extends JFrame {
private static final long serialVersionUID = -4875672779193998620L;
/**
* The constructor of this object. It initializes the window.
*
* @param _controller The controller where to sent actions to. 'cancel'
* for the Cancel button and _action for the OK button
* @param _fields Array of name/value pairs that must be showed in the dialog window.
* @param _action The action that the controller expects when the user clicks th OK button.
* @param _title The title of the dialog window that will be shown in the top.
*/
public DialogWindow(ActionListener _controller, NameValuePanel[] _fields, String _action, String _title) {
super();
controller = _controller;
action = _action;
fields = _fields;
title = _title;
fieldNameMapping = new HashMap<String, NameValuePanel>(_fields.length);
initialize();
}
DialogWindow(ActionListener _controller, String _action, String _title){
super();
controller = _controller;
action = _action;
title = _title;
fields = null;
fieldNameMapping = new HashMap<String, NameValuePanel>();
initialize();
}
/**
* This method initializes the dialog window.
*/
void initialize() {
this.setSize(1200, 1600);
this.setContentPane(getJContentPane());
this.setResizable(false);
this.setTitle(title);
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
controller.actionPerformed(
new ActionEvent(cancelButton, 0, "cancel"));
}
});
this.pack();
}
/**
* This method initializes the root content pane
*
* @return The created or already existing content pane.
*/
JPanel getJContentPane() {
if (jContentPane == null) {
jContentPane = new JPanel();
java.awt.GridLayout layGridLayout15 = new java.awt.GridLayout();
if(fields != null){
layGridLayout15.setRows(fields.length);
}
layGridLayout15.setColumns(1);
layGridLayout15.setHgap(0);
layGridLayout15.setVgap(5);
JPanel inputPanel = new JPanel();
inputPanel.setLayout(layGridLayout15);
jContentPane.setLayout(new java.awt.BorderLayout());
if(fields != null){
for(int i=0; i<fields.length; i++){
String label = fields[i].getName();
JComponent editor = fields[i].getField();
if(editor instanceof JTextField){
((JTextField)editor).setActionCommand(action);
((JTextField)editor).addActionListener(controller);
editor.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
JTextField source = (JTextField)(e.getSource());
source.selectAll();
}
@Override
public void focusLost(FocusEvent e) {
JTextField source = (JTextField)(e.getSource());
source.select(0, 0);
}
});
}
fieldNameMapping.put(label, fields[i]);
inputPanel.add(fields[i], null);
}
}
jContentPane.add(inputPanel, java.awt.BorderLayout.NORTH);
jContentPane.add(getButtonPanel(), java.awt.BorderLayout.CENTER);
jContentPane.add(getStatusPanel(), java.awt.BorderLayout.SOUTH);
}
return jContentPane;
}
/**
* This method initializes the status panel
*
* @return The created or already existing status panel.
*/
StatusPanel getStatusPanel() {
if(statusPanel == null) {
statusPanel = new StatusPanel(250, "Please provide input.", false, false);
}
return statusPanel;
}
/**
* This method initializes the buttonPanel that contains the OK and Cancel button.
*
* @return The created or already existing buttonPanel.
*/
JPanel getButtonPanel() {
if(buttonPanel == null) {
buttonPanel = new JPanel();
FlowLayout layFlowLayout = new FlowLayout(FlowLayout.RIGHT);
buttonPanel.setLayout(layFlowLayout);
buttonPanel.add(getOkButton(), null);
buttonPanel.add(getCancelButton(), null);
}
return buttonPanel;
}
/**
* This method initializes the cancelButton
*
* @return The created or already existing Cancel button.
*/
JButton getCancelButton() {
if(cancelButton == null) {
cancelButton = new JButton();
cancelButton.setText("Cancel");
cancelButton.setMnemonic('C');
cancelButton.setActionCommand("cancel");
cancelButton.addActionListener(controller);
cancelButton.setPreferredSize(new java.awt.Dimension(100, 20));
}
return cancelButton;
}
/**
* This method initializes the OK button.
*
* @return The created or already existing OK button.
*/
JButton getOkButton() {
if(okButton == null) {
okButton = new JButton();
okButton.setText("Ok");
okButton.setMnemonic('O');
okButton.setActionCommand(action);
okButton.addActionListener(controller);
okButton.setPreferredSize(new java.awt.Dimension(100, 20));
this.getRootPane().setDefaultButton(okButton);
}
return okButton;
}
/**
* Sets the status message in the status panel of the dialog window.
*
* @param message The message to show in the status panel.
* @param persistent true if the message should be shown until the next
* call to this operation, false if it should disappear after a few seconds.
*/
public void setStatus(String message, boolean persistent){
statusPanel.setStatus(message, persistent);
}
/**
* Provides access to all values in the input fields.
*
* @return The map of values. The key is the name of the field <fieldName, value>.
*/
public HashMap<String, Object> getValues() {
HashMap<String, Object> values = new HashMap<String, Object>();
for(int i=0; i<fields.length; i++){
values.put(fields[i].getName(), fields[i].getValue());
}
return values;
}
/**
* Provides access to the value of a field.
*
* @param fieldName The fieldName of the field to get the value of.
* @return The value of the field.
*/
public Object getValue(String fieldName){
NameValuePanel nv = fieldNameMapping.get(fieldName);
if(nv == null){
return "";
}
return nv.getValue();
}
/**
* Checks if all fields have compatible values in.
*
* @return true if all fields have a compatible value, false otherwise.
*/
public boolean isInputValid(){
NameValuePanel nvp = null;
Object test = null;
Collection<NameValuePanel> f = fieldNameMapping.values();
Iterator<NameValuePanel> fIter = f.iterator();
while(fIter.hasNext()){
nvp = fIter.next();
test = nvp.getValue();
if(test == null || test.equals("")){
if(!(nvp.isEmptyInputAllowed())){
return false;
}
}
}
return true;
}
public NameValuePanel getField(String name){
return fieldNameMapping.get(name);
}
public NameValuePanel[] getFields(){
return fields;
}
/**
* The root pane of the dialog window.
*/
javax.swing.JPanel jContentPane = null;
/**
* The status panel.
*/
StatusPanel statusPanel = null;
/**
* The panel where the 'OK' and 'Cancel' buttons are placed on.
*/
JPanel buttonPanel = null;
/**
* The 'Cancel' button.
*/
JButton cancelButton = null;
/**
* The 'OK' button.
*/
JButton okButton = null;
/**
* The controller (mvC), where the action command will be sent to when the
* user clicks the OK button.
*/
ActionListener controller = null;
/**
* The title of the dialog window.
*/
String title = null;
/**
* The action string that must be sent to the controller
* when the 'OK' button is clicked.
*/
String action = null;
/**
* The name/value pairs that are shown in the window.
*/
NameValuePanel[] fields = null;
/**
* Fields in the window <String, NameValuePanel>
*/
HashMap<String, NameValuePanel> fieldNameMapping = null;
}

View file

@ -1,106 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.common.view;
import javax.swing.JFrame;
import javax.swing.ToolTipManager;
/**
* Abstract class that is typically extended from by main windows of an
* application. It offers a StatusPanel, which is capable of displaying
* the current status and implements the ModelListener interface to be able
* to be attached to ModelRegister components and receive updates from it. This
* class has been defined abstract because only descendants of this class may
* exist.
*
* @date Sep 1, 2004
*/
public abstract class MainWindow extends JFrame {
private static final long serialVersionUID = 5540350112074790669L;
protected StatusPanel statusPanel = null;
/**
* This is the default constructor
*/
public MainWindow() {
super();
ToolTipManager tm = ToolTipManager.sharedInstance();
tm.setInitialDelay(100);
this.setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
this.setSize(800, 600);
}
/**
* This method initializes statusPanel.
*
* @return The status panel of the window.
*/
protected StatusPanel getStatusPanel() {
if (statusPanel == null) {
statusPanel = new StatusPanel(300, "Ready", true, true);
}
return statusPanel;
}
/**
* Sends a message to the statusPanel and sets the progress.
*
* @param message The message to show in the statusbar.
* @param persistent true if the message must be shown until a new call to
* this function, or false when it should automatically be
* removed after certain amount of time.
* @param busy Sets the progress monitor of the statusbar.
*/
public void setStatus(String message, boolean persistent, boolean busy){
statusPanel.setStatus(message, persistent, busy);
}
/**
* Sends a message to the statusPanel.
*
* @param message The message to show in the statusbar.
* @param persistent true if the message must be shown until a new call to
* this function, or false when it should automatically be
* removed after certain amount of time.
*/
public void setStatus(String message, boolean persistent){
statusPanel.setStatus(message, persistent);
}
/**
* Provides access to the current status.
*
* @return The currently shown status.
*/
public String getStatus(){
return statusPanel.getStatus();
}
/**
* Disables the view component.
*
* This is done when a dialog is shown and the user must
* provide input before proceeding.
*/
public void disableView(){
this.setEnabled(false);
this.setFocusable(false);
}
/**
* Enables the view component.
*/
public void enableView(){
this.setFocusable(true);
this.setEnabled(true);
}
}

View file

@ -1,149 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.common.view;
import javax.swing.*;
import java.awt.Dimension;
import java.awt.FlowLayout;
/**
* This class is meant to provide a standard generic input panel that
* contains a label and a input field.
*
* Input fields that are currently supported are:
* - textfields
* - comboboxes.
*/
public abstract class NameValuePanel extends JPanel {
private static final long serialVersionUID = 8693880375019883969L;
/**
* Creates an input panel with a label and a textfield.
* @param _fieldName The name of the field that is also used as label.
* @param _emptyInputAllowed Boolean that specifies if empty input is allowed when
* submitted.
*/
public NameValuePanel(
String fieldName,
Object defaultValue,
boolean emptyInputAllowed,
Dimension labelDim,
Dimension fieldDim)
{
super();
if(labelDim != null){
this.labelDim = labelDim;
if(this.labelDim.height != 20){
this.labelDim.height = 20;
}
} else {
this.labelDim = new Dimension(100, 20);
}
if(fieldDim != null){
this.fieldDim = fieldDim;
if(this.fieldDim.height != 20){
this.fieldDim.height = 20;
}
} else {
this.fieldDim = new Dimension(230, 20);
}
this.fieldName = fieldName;
this.emptyInputAllowed = emptyInputAllowed;
this.defaultValue = defaultValue;
this.initLayout();
this.initLabel();
}
/**
* Initializes the layout (FlowLayout is used).
*/
protected void initLayout(){
FlowLayout layFlowLayout = new FlowLayout(FlowLayout.LEFT);
layFlowLayout.setVgap(0);
this.setLayout(layFlowLayout);
}
/**
* Initializes the label.
*
* The fieldName is also used as label text.
*/
protected void initLabel(){
JLabel label = new JLabel();
label.setText(fieldName);
label.setPreferredSize(labelDim);
this.add(label);
}
/**
* Provides access to the name of the field.
*
* @return The name of the field.
*/
@Override
public String getName(){
return fieldName;
}
/**
* Provides access to the emptyInputIsAllowed boolean.
*
* @return true if the field may be empty when submitted, false otherwise.
*/
public boolean isEmptyInputAllowed(){
return emptyInputAllowed;
}
/**
* Provides access to the editor component for the field value.
*
* @return The editor component for the field value.
*/
public JComponent getField(){
return field;
}
public abstract Object getValue();
@Override
public abstract void setEnabled(boolean enabled);
/**
* The name of the field.
*/
protected String fieldName = null;
/**
* The input field.
*/
protected JComponent field = null;
/**
* The label Dimension.
*/
protected Dimension labelDim = null;
/**
* The field Dimension.
*/
protected Dimension fieldDim = null;
/**
* Boolean that specifies if empy input is allowed for this field.
*/
protected boolean emptyInputAllowed;
protected Object defaultValue = null;
}

View file

@ -1,392 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.common.view;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import org.eclipse.cyclonedds.common.util.Config;
/**
* This class provides a standard statusbar that can be placed in a window at
* any place.
*/
public class StatusPanel extends JPanel {
private static final long serialVersionUID = -6861447244439379176L;
/**
* Creates a new StatusPanel that can be used to provide information about
* the status of the application of a certain action. The StatusPanel
* optionally provides a connection light and a progressbar.
*
* @param width
* The width of the panel.
* @param _defaultText
* The default text of the panel.
* @param showConnectionLight
* Whether or not to display a connection light.
* @param showProgressBar
* Whether or not to display a progressbar.
*/
public StatusPanel(int width, String _defaultText,
boolean showConnectionLight, boolean showProgressBar) {
super();
this.setLayout(new java.awt.BorderLayout());
defaultText = _defaultText;
if (defaultText == null) {
defaultText = "";
}
defaultBg = this.getBackground();
status = new JLabel();
status.setText(defaultText);
status.setToolTipText(defaultText);
java.awt.GridLayout layGridLayout2 = new java.awt.GridLayout();
layGridLayout2.setRows(1);
layGridLayout2.setColumns(1);
if (showConnectionLight && showProgressBar) {
progressBar = new JProgressBar(0, 10);
progressBar.setBorderPainted(false);
progressBar.setPreferredSize(new java.awt.Dimension(
width / 10 + 10, 10));
JPanel temp = new JPanel();
temp.setLayout(new java.awt.BorderLayout());
temp.setBorder(javax.swing.BorderFactory
.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
statusPanel = new JPanel();
statusPanel.setLayout(layGridLayout2);
statusPanel.setPreferredSize(new java.awt.Dimension(width - 20
- (width / 10) - 10, 20));
statusPanel.setMinimumSize(new java.awt.Dimension(50, 20));
statusPanel.add(status);
temp.add(statusPanel, java.awt.BorderLayout.CENTER);
temp.add(progressBar, java.awt.BorderLayout.EAST);
connectionPanel = new JPanel();
connectionPanel.setPreferredSize(new java.awt.Dimension(20, 10));
connectionPanel
.setBorder(javax.swing.BorderFactory.createCompoundBorder(
javax.swing.BorderFactory
.createCompoundBorder(
javax.swing.BorderFactory
.createLineBorder(
connectionPanel
.getBackground(),
2),
javax.swing.BorderFactory
.createEtchedBorder(javax.swing.border.EtchedBorder.RAISED)),
javax.swing.BorderFactory
.createBevelBorder(javax.swing.border.BevelBorder.LOWERED)));
connectionPanel.setBackground(disconnectedColor);
connectionPanel.setToolTipText("Not connected.");
this.add(temp, java.awt.BorderLayout.CENTER);
this.add(connectionPanel, java.awt.BorderLayout.EAST);
this.setPreferredSize(new java.awt.Dimension(width, 20));
} else if (showProgressBar) {
progressBar = new JProgressBar(0, 10);
progressBar.setBorderPainted(false);
progressBar.setPreferredSize(new java.awt.Dimension(
width / 10 + 10, 10));
statusPanel = new JPanel();
statusPanel.setLayout(layGridLayout2);
statusPanel.setPreferredSize(new java.awt.Dimension(width
- (width / 10) - 10, 20));
statusPanel.setMinimumSize(new java.awt.Dimension(50, 20));
statusPanel.add(status);
this.setBorder(javax.swing.BorderFactory
.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
this.setPreferredSize(new java.awt.Dimension(width, 20));
this.add(statusPanel, java.awt.BorderLayout.CENTER);
this.add(progressBar, java.awt.BorderLayout.EAST);
} else if (showConnectionLight) {
statusPanel = new JPanel();
statusPanel.setLayout(layGridLayout2);
statusPanel.setBorder(javax.swing.BorderFactory
.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
statusPanel
.setPreferredSize(new java.awt.Dimension(width - 20, 20));
statusPanel.setMinimumSize(new java.awt.Dimension(50, 20));
statusPanel.add(status);
connectionPanel = new JPanel();
connectionPanel.setPreferredSize(new java.awt.Dimension(20, 10));
connectionPanel
.setBorder(javax.swing.BorderFactory.createCompoundBorder(
javax.swing.BorderFactory
.createCompoundBorder(
javax.swing.BorderFactory
.createLineBorder(
connectionPanel
.getBackground(),
2),
javax.swing.BorderFactory
.createEtchedBorder(javax.swing.border.EtchedBorder.RAISED)),
javax.swing.BorderFactory
.createBevelBorder(javax.swing.border.BevelBorder.LOWERED)));
connectionPanel.setBackground(disconnectedColor);
connectionPanel.setToolTipText("Not connected.");
this.add(statusPanel, java.awt.BorderLayout.CENTER);
this.add(connectionPanel, java.awt.BorderLayout.EAST);
this.setPreferredSize(new java.awt.Dimension(width, 20));
} else {
this.setLayout(layGridLayout2);
this.setBorder(javax.swing.BorderFactory
.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
this.setPreferredSize(new java.awt.Dimension(width, 20));
this.setMinimumSize(new java.awt.Dimension(100, 20));
this.add(status);
}
}
/**
* Sets the connection light to green when connected and to red if not.
*
* @param connected
* Whether or not the application has a connection.
* @param toolTip
* The tooltip that must be displayed when the user moves the
* mouse over the connection light.
*/
public synchronized void setConnected(boolean connected, String toolTip) {
if (connectionPanel != null) {
final boolean con = connected;
final String tt = toolTip;
Runnable runner = new Runnable() {
@Override
public void run() {
if (con) {
connectionPanel.setBackground(connectedColor);
} else {
connectionPanel.setBackground(disconnectedColor);
}
connectionPanel.setToolTipText(tt);
}
};
SwingUtilities.invokeLater(runner);
}
}
/**
* Sets the status message to the supplied message and sets the progressbar
* to indeterminate mode or resets it. This is done by calling the
* setStatus(String, boolean) method as well as the setBusy method.
*
* @param message
* The message to set.
* @param persistent
* Whether or not the message should never be removed or not.
* @param busy
* Whether or not the progressbar must be set in indeterminate
* mode or not.
*/
public synchronized void setStatus(String msg, boolean persistent,
boolean busy) {
if (msg == null) {
msg = "";
}
final String message = msg;
final boolean b = busy;
final boolean p = persistent;
/*
* Runnable runner = new Runnable() { public void run(){
*/
String myMsg = message;
if ("".equals(message)) {
myMsg = defaultText;
}
if (message.startsWith("Error:")) {
if (statusPanel != null) {
statusPanel.setBackground(errorColor);
if (progressBar != null) {
progressBar.setBackground(errorColor);
}
} else {
setBackground(errorColor);
}
myMsg = message.substring(6);
} else if (message.startsWith("Warning:")) {
if (statusPanel != null) {
statusPanel.setBackground(warningColor);
if (progressBar != null) {
progressBar.setBackground(warningColor);
}
} else {
setBackground(warningColor);
}
myMsg = message.substring(8);
} else { // Standard message
if (statusPanel != null) {
statusPanel.setBackground(defaultBg);
if (progressBar != null) {
progressBar.setBackground(defaultBg);
}
} else {
setBackground(defaultBg);
}
}
status.setText(" " + myMsg);
status.setToolTipText(myMsg);
setBusy(b);
synchronized (this) {
if (!p) {
Timer persistentTimer = new Timer(persistentTime,
new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
long currentTime = System.currentTimeMillis();
synchronized (org.eclipse.cyclonedds.common.view.StatusPanel.this) {
if (((currentTime - lastMessageTime) < persistentTime)
|| (!lastPersistent)) {
/*
* New message has arrived, ignore
* reset.
*/
} else {
setStatus(defaultText, false, false);
}
}
}
});
persistentTimer.setRepeats(false);
lastMessageTime = System.currentTimeMillis();
persistentTimer.start();
lastPersistent = true;
} else {
lastPersistent = false;
}
}
/*
* }
*
* }; runner.run(); SwingUtilities.invokeLater(runner);
*/
}
/**
* Changes the status message. If the message starts with "Error:" the
* background color will become red and the "Error:" part of the string will
* not be shown. If the message starts with "Warning:" the background color
* will become yellow and the "Warning:" part of the string will not be
* displayed.
*
* @param message
* The new status message.
* @param persistent
* If true, the message will not be changed into the standard
* text after a few seconds, but stay there until this function
* is called again.
*/
public synchronized void setStatus(String message, boolean persistent) {
this.setStatus(message, persistent, false);
}
/**
* Sets the progressbar status. When true, the progressbar will go into
* inderminate mode and display 'busy...', when false the progressbar will
* leave indeterminate mode and display 'ready'
*
* @param busy
* When true, the progressbar will go into inderminate mode
*/
private synchronized void setBusy(boolean busy) {
if (progressBar != null) {
if (busy) {
progressBar.setBorderPainted(true);
progressBar.setStringPainted(true);
progressBar.setString("busy..");
} else {
progressBar.setBorderPainted(false);
progressBar.setStringPainted(false);
progressBar.setString(null);
}
progressBar.setIndeterminate(busy);
}
}
/**
* Provides access to the current status.
*
* @return The currently displayed status.
*/
public synchronized String getStatus() {
return status.getText();
}
private static final int persistentTime = 4000;
private long lastMessageTime;
private boolean lastPersistent = false;
/**
* The current status message.
*/
private JLabel status = null;
/**
* The default message.
*/
private String defaultText = null;
/**
* The default background color
*/
private Color defaultBg = null;
/**
* Panel that holds the connection light. Green if connected, red if not
* connected.
*/
private JPanel connectionPanel = null;
/**
* Progressbar that can be used to provide the user with progress
* information.
*/
private JProgressBar progressBar = null;
/**
* Panel that holds the status label.
*/
private JPanel statusPanel = null;
private final Color connectedColor = Config.getActiveColor();
private final Color errorColor = Config.getErrorColor();
private final Color warningColor = Config.getWarningColor();
private final Color disconnectedColor = Config.getErrorColor();
}

View file

@ -1,75 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config;
import org.eclipse.cyclonedds.common.util.Initializer;
import org.eclipse.cyclonedds.common.util.Report;
import org.eclipse.cyclonedds.config.swing.ConfigWindow;
public class CycloneConfig extends Initializer {
/**
* Starts configuration. This function is the main class.
*
* - It passes on the commandline arguments. Arguments that are supported
* are:
* -# <java_properties_file>
*
* @param args These are passed on to the initialize function
*/
public static void main(String[] args) {
boolean redirect = true;
boolean uriSet = false;
String[] args2;
String uri = null;
CycloneConfig t = new CycloneConfig();
for (int i = 0; i < args.length; i++) {
if ("-noredirect".equals(args[i])) {
redirect = false;
} else if (args[i].toLowerCase().startsWith("-uri=")) {
uri = args[i].substring(5); /* '-uri=' is 5 characters */
uriSet = true;
} else {
args2 = new String[1];
args2[0] = args[i];
}
}
if (redirect) {
/*
* initialize logging with a max size of 10M with a max history of
* 10 runs and do not append
*/
Report.getInstance().initializeInfo("cycloneddsconf-info.log", 10000000, 10, false);
Report.getInstance().initializeError("cycloneddsconf-error.log", 10000000, 10, false);
} else {
Report.getInstance().initializeConsole();
System.out.println("No redirect.");
}
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
Report.getInstance().CloseHandlers();
}
});
ConfigWindow cw = null;
if (uriSet) {
cw = new ConfigWindow(uri);
} else {
cw = new ConfigWindow();
}
cw.setVisible(true);
}
}

View file

@ -1,70 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.data;
import org.w3c.dom.Attr;
import org.eclipse.cyclonedds.config.meta.MetaAttribute;
public class DataAttribute extends DataNode {
private DataValue value;
public DataAttribute(MetaAttribute metadata, Attr node, Object value) throws DataException {
super(metadata, node);
if(!node.getNodeName().equals(metadata.getName())){
throw new DataException("Metadata and data do not match.");
}
this.value = new DataValue(metadata.getValue(), node, value);
this.value.setParent(this);
this.value.setOwner(this.getOwner());
}
public DataAttribute(MetaAttribute metadata, Attr node) throws DataException {
super(metadata, node);
if(!node.getNodeName().equals(metadata.getName())){
throw new DataException("Metadata and data do not match.");
}
Object defaultValue = metadata.getValue().getDefaultValue();
this.value = new DataValue(metadata.getValue(), node, defaultValue);
this.value.setParent(this);
this.value.setOwner(this.getOwner());
}
@Override
public void setOwner(DataConfiguration owner) {
super.setOwner(owner);
this.value.setOwner(owner);
}
public DataValue getDataValue(){
return this.value;
}
public void testSetValue(Object value) throws DataException{
this.value.testSetValue(value);
}
public void setValue(Object value) throws DataException{
DataValue tmpValue = this.value;
this.value.setValue(value);
tmpValue.setParent(null);
tmpValue.setOwner(null);
this.value.setParent(this);
this.value.setOwner(this.owner);
}
public Object getValue(){
return this.value.getValue();
}
}

View file

@ -1,21 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.data;
public interface DataConfigurationListener {
public void valueChanged(DataValue data, Object oldValue, Object newValue);
public void nodeAdded(DataElement parent, DataNode nodeAdded);
public void nodeRemoved(DataElement parent, DataNode nodeRemoved);
}

View file

@ -1,197 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.data;
import java.util.ArrayList;
import org.eclipse.cyclonedds.config.meta.MetaAttribute;
import org.eclipse.cyclonedds.config.meta.MetaElement;
import org.eclipse.cyclonedds.config.meta.MetaNode;
import org.eclipse.cyclonedds.config.meta.MetaValue;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
public class DataElement extends DataNode {
private ArrayList<DataNode> children = null;
public DataElement(MetaElement metadata, Element node) throws DataException {
super(metadata, node);
if(!node.getNodeName().equals(metadata.getName())){
throw new DataException("Metadata and data do not match.");
}
this.children = new ArrayList<DataNode>();
}
protected DataNode addChild(DataNode node, int addToDOM, String value) throws DataException {
/*
* addToDOM values: 0 = do not add (false) 1 = append (true) 2 = replace
* (this is done when the user choose to repair the value)
*/
int count;
MetaNode nodeMeta;
if(node == null){
throw new DataException("Cannot add null child.");
} else if(this.children.contains(node)){
throw new DataException("Element already contains this child.");
} else if(!this.isNodeChildCandidate(node)){
throw new DataException("Node cannot be added to this element.");
}
nodeMeta = node.getMetadata();
count = 0;
for(DataNode child: this.children){
if(child instanceof DataValue){
if(node instanceof DataValue){
throw new DataException("Element " +
((MetaElement)this.metadata).getName() +
" already contains this child: " +
((DataValue)node).getValue() + " with value: " +
((DataValue)child).getValue());
}
} else if(child instanceof DataElement){
if(node instanceof DataElement){
if(child.getMetadata().equals(nodeMeta)){
count++;
}
}
} else if(child instanceof DataAttribute){
if(node instanceof DataAttribute){
if(child.getMetadata().equals(nodeMeta)){
throw new DataException("Element already contains attribute: "
+ ((MetaAttribute)nodeMeta).getName());
}
}
}
}
if(nodeMeta instanceof MetaElement){
if(count == ((MetaElement)nodeMeta).getMaxOccurrences()){
throw new DataException("Maximum number of occurrences for " +
((MetaElement)nodeMeta).getName()+ " reached.");
} else if (addToDOM == 1) {
((Element) this.node).appendChild(node.getNode());
Text textNode = this.owner.getDocument().createTextNode("\n");
this.node.appendChild(textNode);
} else if (addToDOM == 2) {
replaceChild(node.getNode(), value);
Text textNode = this.owner.getDocument().createTextNode("\n");
this.node.appendChild(textNode);
}
} else if(nodeMeta instanceof MetaAttribute){
if (addToDOM == 1) {
((Element)this.node).setAttributeNode((Attr)node.getNode());
}
} else if(nodeMeta instanceof MetaValue){
if (addToDOM == 1) {
((Element)this.node).appendChild(node.getNode());
assert this.owner != null;
assert this.owner.getDocument() != null;
} else if (addToDOM == 2) {
replaceChild(node.getNode(), value);
Text textNode = this.owner.getDocument().createTextNode("\n");
this.node.appendChild(textNode);
}
}
this.children.add(node);
node.setParent(this);
node.setOwner(this.owner);
return node;
}
public void replaceChild(Node node, String value) {
NodeList nodeList = ((Element) this.node).getChildNodes();
boolean finished = false;
for (int i = 0, len = nodeList.getLength(); i < len && !finished; i++) {
Node n = nodeList.item(i);
if (n.getNodeValue().equals(value)) {
((Element) this.node).replaceChild(node, n);
finished = true;
}
}
}
@Override
public void setOwner(DataConfiguration owner) {
super.setOwner(owner);
for(DataNode child: this.children){
child.setOwner(owner);
}
}
public DataNode addChild(DataNode node) throws DataException{
return addChild(node, 1, null);
}
public void removeChild(DataNode node) throws DataException{
int count;
MetaNode nodeMeta;
if(node == null){
throw new DataException("Cannot remove null child.");
} else if(!(this.children.contains(node))){
throw new DataException("Element does not contain this child.");
}
nodeMeta = node.getMetadata();
count = 0;
for(DataNode child: this.children){
if(child.getMetadata().equals(nodeMeta)){
count++;
}
}
if(nodeMeta instanceof MetaElement){
if(count == ((MetaElement)nodeMeta).getMinOccurrences()){
throw new DataException("Minimum number of occurrences for " +
((MetaElement)nodeMeta).getName()+ " reached.");
} else
((Element) this.node).removeChild(node.getNode());
} else if(nodeMeta instanceof MetaAttribute){
if(((MetaAttribute)nodeMeta).isRequired()){
throw new DataException("Cannot remove required attribute " +
((MetaAttribute)nodeMeta).getName()+ ".");
} else {
((Element) this.node)
.removeAttributeNode((Attr) node.getNode());
}
} else {
((Element)this.node).removeChild(node.getNode());
}
this.children.remove(node);
return;
}
public DataNode[] getChildren(){
return this.children.toArray(new DataNode[this.children.size()]);
}
private boolean isNodeChildCandidate(DataNode node){
MetaNode nodeMeta = node.getMetadata();
MetaNode[] metaNodes = ((MetaElement)this.metadata).getChildren();
for(MetaNode mn: metaNodes){
if(mn.equals(nodeMeta)){
return true;
}
}
return false;
}
}

View file

@ -1,20 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.data;
public class DataException extends Exception {
private static final long serialVersionUID = 7787444897071114498L;
public DataException(String message){
super(message);
}
}

View file

@ -1,73 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.data;
import java.util.HashSet;
import org.eclipse.cyclonedds.config.meta.MetaNode;
import org.w3c.dom.Node;
public abstract class DataNode {
protected MetaNode metadata;
protected Node node;
protected DataNode parent;
protected DataConfiguration owner;
private HashSet<DataNode> dependencies = null;
public DataNode(MetaNode metadata, Node node) throws DataException {
if(metadata == null){
throw new DataException("Invalid metadata.");
} else if(node == null){
throw new DataException("Invalid data.");
}
this.metadata = metadata;
this.node = node;
this.parent = null;
this.owner = null;
}
public void addDependency(DataNode dv) {
if (dependencies == null) {
dependencies = new HashSet<DataNode>();
}
dependencies.add(dv);
}
public HashSet<DataNode> getDependencies() {
return dependencies;
}
public MetaNode getMetadata() {
return this.metadata;
}
public Node getNode() {
return this.node;
}
public DataConfiguration getOwner() {
return this.owner;
}
public void setOwner(DataConfiguration owner) {
this.owner = owner;
}
protected void setParent(DataNode node){
this.parent = node;
}
public DataNode getParent(){
return this.parent;
}
}

View file

@ -1,296 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.data;
import java.util.HashSet;
import org.eclipse.cyclonedds.config.meta.MetaConfiguration;
import org.eclipse.cyclonedds.config.meta.MetaValue;
import org.eclipse.cyclonedds.config.meta.MetaValueBoolean;
import org.eclipse.cyclonedds.config.meta.MetaValueDouble;
import org.eclipse.cyclonedds.config.meta.MetaValueEnum;
import org.eclipse.cyclonedds.config.meta.MetaValueFloat;
import org.eclipse.cyclonedds.config.meta.MetaValueInt;
import org.eclipse.cyclonedds.config.meta.MetaValueLong;
import org.eclipse.cyclonedds.config.meta.MetaValueNatural;
import org.eclipse.cyclonedds.config.meta.MetaValueSize;
import org.eclipse.cyclonedds.config.meta.MetaValueString;
import org.w3c.dom.Attr;
import org.w3c.dom.Text;
public class DataValue extends DataNode {
private Object value;
private HashSet<DataValue> DVdependencies = null;
public DataValue(MetaValue metadata, Attr parent, Object value) throws DataException {
super(metadata, parent);
this.setValue(value);
}
public DataValue(MetaValue metadata, Text text) throws DataException {
super(metadata, text);
this.setValue(this.node.getNodeValue());
}
public Object getValue(){
return this.value;
}
public void addDataValueDependency(DataValue dv) {
if (DVdependencies == null) {
DVdependencies = new HashSet<DataValue>();
}
DVdependencies.add(dv);
}
public HashSet<DataValue> getDataValueDependencies() {
return DVdependencies;
}
public void testSetValue(Object value) throws DataException {
try{
if (!isEnvironmentVar(value)) {
if(this.metadata instanceof MetaValueBoolean){
if(value instanceof String){
this.value = Boolean.parseBoolean((String)value);
} else if(!(value instanceof Boolean)){
throw new NumberFormatException();
}
} else if(this.metadata instanceof MetaValueDouble){
Double tempValue;
MetaValueNatural mv = (MetaValueNatural)this.metadata;
if(value instanceof String){
tempValue = Double.parseDouble((String)value);
} else if(!(value instanceof Double)){
throw new NumberFormatException();
} else {
tempValue = (Double)value;
}
Object min = mv.getMinValue();
Object max = mv.getMaxValue();
if(tempValue.compareTo((Double)min) < 0){
throw new DataException("<" + this.node.getParentNode().getNodeName() + "> Value: " + tempValue
+ "<" + min);
} else if(tempValue.compareTo((Double)max) > 0){
throw new DataException("<" + this.node.getParentNode().getNodeName() + "> Value: " + tempValue
+ ">" + max);
}
} else if(this.metadata instanceof MetaValueEnum){
if(value instanceof String){
String tmp;
String[] values = ((MetaValueEnum)this.metadata).getPosValues();
boolean valid = false;
for(int i=0; i<values.length && !valid; i++){
tmp = values[i];
if(tmp.equalsIgnoreCase((String)value)){
valid = true;
}
}
if(!valid){
throw new DataException("Illegal Enum value found: " + value);
}
} else {
throw new NumberFormatException();
}
} else if(this.metadata instanceof MetaValueFloat){
Float tempValue;
MetaValueNatural mv = (MetaValueNatural)this.metadata;
if(value instanceof String){
tempValue = Float.parseFloat((String)value);
} else if(!(value instanceof Float)){
throw new NumberFormatException();
} else {
tempValue = (Float)value;
}
Object min = mv.getMinValue();
Object max = mv.getMaxValue();
if(tempValue.compareTo((Float)min) < 0){
throw new DataException("<" + this.node.getParentNode().getNodeName() + "> Value: " + tempValue
+ " < " + min);
} else if(tempValue.compareTo((Float)max) > 0){
throw new DataException("<" + this.node.getParentNode().getNodeName() + "> Value: " + tempValue
+ " > " + max);
}
} else if(this.metadata instanceof MetaValueInt){
Integer tempValue;
MetaValueNatural mv = (MetaValueNatural)this.metadata;
if(value instanceof String){
tempValue = Integer.parseInt((String)value);
} else if(!(value instanceof Integer)){
throw new NumberFormatException();
} else {
tempValue = (Integer)value;
}
Object min = mv.getMinValue();
Object max = mv.getMaxValue();
if(tempValue.compareTo((Integer)min) < 0){
throw new DataException("<" + this.node.getParentNode().getNodeName() + "> Value: " + tempValue
+ "<" + min);
} else if(tempValue.compareTo((Integer)max) > 0){
throw new DataException("<" + this.node.getParentNode().getNodeName() + "> Value: " + tempValue
+ ">" + max);
}
} else if(this.metadata instanceof MetaValueLong){
Long tempValue;
MetaValueNatural mv = (MetaValueNatural)this.metadata;
if(value instanceof String){
tempValue = Long.parseLong((String)value);
} else if(!(value instanceof Long)){
throw new NumberFormatException();
} else {
tempValue = (Long)value;
}
Object min = mv.getMinValue();
Object max = mv.getMaxValue();
if(tempValue.compareTo((Long)min) < 0){
throw new DataException("<" + this.node.getParentNode().getNodeName() + "> Value: " + tempValue
+ "<" + min);
} else if(tempValue.compareTo((Long)max) > 0){
throw new DataException("<" + this.node.getParentNode().getNodeName() + "> Value: " + tempValue
+ ">" + max);
}
} else if(this.metadata instanceof MetaValueSize){
Long tempValue;
MetaValueNatural mv = (MetaValueNatural)this.metadata;
if(value instanceof String){
tempValue = MetaConfiguration.createLongValuefromSizeValue((String)value);
} else if(!(value instanceof Long)){
throw new NumberFormatException();
} else {
tempValue = (Long)value;
}
Object min = mv.getMinValue();
Object max = mv.getMaxValue();
if(tempValue.compareTo((Long)min) < 0){
throw new DataException("<" + this.node.getParentNode().getNodeName() + "> Value: " + tempValue
+ "<" + min);
} else if(tempValue.compareTo((Long)max) > 0){
throw new DataException("<" + this.node.getParentNode().getNodeName() + "> Value: " + tempValue
+ ">" + max);
}
} else if(this.metadata instanceof MetaValueString){
if(value instanceof String){
String strValue = (String)value;
if(strValue.startsWith("${") && strValue.endsWith("}")){
/*Environment variable, this is ok*/
} else {
int length = strValue.length();
int maxLength = ((MetaValueString)this.metadata).getMaxLength();
if((maxLength != 0) && (length > maxLength)){
throw new DataException("<" + this.node.getParentNode().getNodeName() + "> String length: "
+ length + ">" + maxLength);
}
}
/*
* check if we got a domain service name element of service
* tag name element
*/
if (this.getOwner() != null && this.getOwner().getServiceNames().contains(this)) {
if (!this.getValue().equals(value)) {
for (DataValue dv : this.getOwner().getServiceNames()) {
if (dv.getValue().equals(value)) {
throw new DataException("Name [" + value + "] is already used by another service");
}
}
}
}
} else if(value == null){
throw new DataException("Null pointer string");
} else {
throw new NumberFormatException();
}
} else {
throw new DataException("Found unknown metadata." +
this.metadata.getClass().toString().substring(
this.metadata.getClass().toString().lastIndexOf(
'.') + 10));
}
}
} catch(NumberFormatException nfe){
if(value == null){
throw new DataException("Found null pointer for data.");
}
throw new DataException("Expected '"
+ this.metadata
.getClass()
.toString()
.substring(
this.metadata.getClass().toString()
.lastIndexOf('.') + 10)
+ "', but found '"
+ value.getClass()
.toString()
.substring(
value.getClass().toString()
.lastIndexOf('.') + 1) + "'.");
}
}
public boolean isEnvironmentVar(Object value) {
boolean result = false;
if (value instanceof String && ((String) value).startsWith("${") && ((String) value).endsWith("}")) {
result = true;
}
return result;
}
public void setValue(Object value) throws DataException {
this.testSetValue(value);
this.value = value;
/*testSetValue succeeded*/
if(this.node instanceof Attr){
((Attr)this.node).setValue(this.value.toString());
} else if(this.node instanceof Text){
((Text)this.node).replaceWholeText(this.value.toString());
}
if (DVdependencies != null) {
for (DataValue dv : DVdependencies) {
Object oldValue = dv.getValue();
dv.value = value;
/* testSetValue succeeded */
if (dv.node instanceof Attr) {
((Attr) dv.node).setValue(dv.value.toString());
} else if (dv.node instanceof Text) {
((Text) dv.node).replaceWholeText(dv.value.toString());
}
dv.getOwner().notifyValueChanged(dv, oldValue, value);
}
}
}
public void resetValue(){
try {
this.setValue(((MetaValue)this.metadata).getDefaultValue());
} catch (DataException e) {
assert false: "Default value cannot be applied.";
}
}
}

View file

@ -1,95 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.meta;
public class MetaAttribute extends MetaNode {
private String name;
private boolean required;
private MetaValue value;
public MetaAttribute(String doc, String name, boolean required,
MetaValue value, String dimension) {
super(doc, dimension);
this.name = name;
this.required = required;
this.value = value;
}
public boolean isRequired(){
return this.required;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public MetaValue getValue() {
return this.value;
}
public void setValue(MetaValue value) {
this.value = value;
}
@Override
public boolean equals(Object object){
MetaAttribute ma;
boolean result;
if(object instanceof MetaAttribute){
ma = (MetaAttribute)object;
if(this.name.equals(ma.getName())){
if(this.required == ma.isRequired()){
if(this.value.equals(ma.getValue())){
result = true;
} else {
result = false;
}
} else {
result = false;
}
} else {
result = false;
}
} else {
result = false;
}
return result;
}
@Override
public int hashCode() {
int var_gen_code;
int hash = 13;
var_gen_code = required ? 1 : 0;
var_gen_code += (null == value ? 0 : value.hashCode());
var_gen_code += (null == name ? 0 : name.hashCode());
hash = 31 * hash + var_gen_code;
return hash;
}
@Override
public String toString(){
String result = "";
result += "\nAttribute\n";
result += "-Name: " + this.name + "\n";
result += "-Required: " + this.required + "\n";
result += "-Value: " + value.toString();
return result;
}
}

View file

@ -1,137 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.meta;
import java.util.ArrayList;
public class MetaElement extends MetaNode {
private String name;
private int minOccurrences;
private int maxOccurrences;
private ArrayList<MetaNode> children;
public MetaElement(String doc, String name, int minOccurrences,
int maxOccurrences, ArrayList<MetaNode> children,
String dimension) {
super(doc, dimension);
this.name = name;
this.minOccurrences = minOccurrences;
this.maxOccurrences = maxOccurrences;
this.children = children;
}
public int getMaxOccurrences() {
return this.maxOccurrences;
}
public int getMinOccurrences() {
return this.minOccurrences;
}
public String getName() {
return this.name;
}
public boolean addChild(MetaNode child){
return this.children.add(child);
}
public boolean removeChild(MetaNode child){
return this.children.remove(child);
}
public MetaNode[] getChildren(){
return this.children.toArray(new MetaNode[this.children.size()]);
}
@Override
public boolean equals(Object object){
boolean result;
MetaElement me;
if(object instanceof MetaElement){
me = (MetaElement)object;
if(this.name.equals(me.getName())){
MetaNode[] meChildren = me.getChildren();
MetaNode[] children = this.getChildren();
if(this.maxOccurrences != me.getMaxOccurrences()){
result = false;
} else if(this.minOccurrences != me.getMinOccurrences()){
result = false;
} else if(meChildren.length != children.length){
result = false;
} else {
result = true;
for(int i=0; i<children.length && result; i++){
if(!(meChildren[i].equals(children[i]))){
result = false;
}
}
}
} else {
result = false;
}
} else {
result = false;
}
return result;
}
@Override
public int hashCode() {
int var_gen_code;
int hash = 13;
var_gen_code = minOccurrences;
var_gen_code += maxOccurrences;
var_gen_code += (null == children ? 0 : children.hashCode());
var_gen_code += (null == name ? 0 : name.hashCode());
hash = 31 * hash + var_gen_code;
return hash;
}
@Override
public String toString(){
StringBuffer buf = new StringBuffer();
buf.append("\nElement\n");
buf.append("-Name: " + this.name + "\n");
buf.append("-MinOcccurrences: " + this.minOccurrences + "\n");
buf.append("-MaxOcccurrences: " + this.maxOccurrences + "\n");
if(this.children.size() > 0){
buf.append("-Children: ");
for(MetaNode child: children){
buf.append(child.toString().replaceAll("\n", "\n\t"));
}
}
return buf.toString();
}
public boolean hasElementChildren(){
for(MetaNode mn: this.getChildren()){
if(mn instanceof MetaElement){
return true;
}
}
return false;
}
public boolean hasValueChildren(){
for(MetaNode mn: this.getChildren()){
if(mn instanceof MetaValue){
return true;
}
}
return false;
}
}

View file

@ -1,31 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.meta;
public class MetaException extends Exception {
private static final long serialVersionUID = 4459748108068852410L;
private MetaExceptionType type;
public MetaException(String message, MetaExceptionType type) {
super(message);
this.type = type;
}
public MetaException(String message) {
super(message);
this.type = MetaExceptionType.META_ERROR;
}
public MetaExceptionType getType() {
return this.type;
}
}

View file

@ -1,16 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.meta;
public enum MetaExceptionType {
META_ERROR, META_UNSUPPORTED, META_CONFIG_PARSE_ERROR
}

View file

@ -1,34 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.meta;
public abstract class MetaNode {
String doc;
String dimension;
public MetaNode(String doc, String dimension) {
this.doc = doc;
this.dimension = dimension;
}
public String getDoc() {
return doc;
}
public void setDoc(String doc) {
this.doc = doc;
}
public String getDimension() {
return this.dimension;
}
}

View file

@ -1,65 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.meta;
public abstract class MetaValue extends MetaNode {
Object defaultValue;
public MetaValue(String doc, Object defaultValue, String dimension) {
super(doc, dimension);
this.defaultValue = defaultValue;
}
public Object getDefaultValue() {
return this.defaultValue;
}
public abstract boolean setDefaultValue(Object defaultValue);
@Override
public String toString(){
return "Value (" + defaultValue.getClass().toString().substring(defaultValue.getClass().toString().lastIndexOf('.') + 1) + ") DefaultValue: " + defaultValue.toString();
}
@Override
public boolean equals(Object object){
boolean result;
MetaValue mv;
if(object instanceof MetaValue){
mv = (MetaValue)object;
if((this.defaultValue == null) || (mv.getDefaultValue() == null)){
if(this.defaultValue != mv.getDefaultValue()){
result = false;
} else {
result = true;
}
} else if(this.defaultValue.equals(mv.getDefaultValue())){
result = true;
} else {
result = false;
}
} else {
result = false;
}
return result;
}
@Override
public int hashCode() {
int var_gen_code;
int hash = 13;
var_gen_code = (null == defaultValue ? 0 : defaultValue.hashCode());
hash = 31 * hash + var_gen_code;
return hash;
}
}

View file

@ -1,30 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.meta;
public class MetaValueBoolean extends MetaValue {
public MetaValueBoolean(String doc, Boolean defaultValue, String dimension) {
super(doc, defaultValue, dimension);
}
@Override
public boolean setDefaultValue(Object defaultValue) {
boolean result = false;
if(defaultValue instanceof Boolean){
this.defaultValue = defaultValue;
result = true;
}
return result;
}
}

View file

@ -1,58 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.meta;
public class MetaValueDouble extends MetaValueNatural {
public MetaValueDouble(String doc, Double defaultValue, Double maxValue,
Double minValue, String dimension) {
super(doc, defaultValue, maxValue, minValue, dimension);
}
@Override
public boolean setMaxValue(Object maxValue) {
boolean result;
if(maxValue instanceof Double){
this.maxValue = maxValue;
result = true;
} else {
result = false;
}
return result;
}
@Override
public boolean setMinValue(Object minValue) {
boolean result;
if(minValue instanceof Double){
this.minValue = minValue;
result = true;
} else {
result = false;
}
return result;
}
@Override
public boolean setDefaultValue(Object defaultValue) {
boolean result;
if(defaultValue instanceof Double){
this.defaultValue = defaultValue;
result = true;
} else {
result = false;
}
return result;
}
}

View file

@ -1,96 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.meta;
import java.util.ArrayList;
public class MetaValueEnum extends MetaValue {
private ArrayList<String> posValues;
public MetaValueEnum(String doc, String defaultValue,
ArrayList<String> posValues, String dimension) {
super(doc, defaultValue, dimension);
assert(defaultValue != null);
this.posValues = new ArrayList<String>();
if(posValues != null){
this.posValues.addAll(posValues);
}
if(!this.posValues.contains(defaultValue)){
this.posValues.add(defaultValue);
}
}
public String[] getPosValues() {
return this.posValues.toArray(new String[this.posValues.size()]);
}
public boolean setPosValues(ArrayList<String> posValues) {
boolean result;
if((posValues != null) && (posValues.size() > 0)){
this.posValues.clear();
this.posValues.addAll(posValues);
if(!posValues.contains(defaultValue)){
this.defaultValue = this.posValues.get(0);
}
result = true;
} else {
result = false;
}
return result;
}
public boolean addPosValue(String value){
return this.posValues.add(value);
}
public boolean removePosValue(String value){
boolean result;
if(!defaultValue.equals(value)){
result = this.posValues.remove(value);
} else {
result = false;
}
return result;
}
@Override
public boolean setDefaultValue(Object defaultValue) {
boolean result = false;
if(defaultValue instanceof String){
this.defaultValue = defaultValue;
if(!this.posValues.contains(defaultValue)){
result = this.addPosValue((String)defaultValue);
}
} else {
result = false;
}
return result;
}
@Override
public int hashCode() {
int var_gen_code;
int hash = 13;
var_gen_code = (null == defaultValue ? 0 : defaultValue.hashCode());
var_gen_code += (null == posValues ? 0 : posValues.hashCode());
hash = 31 * hash + var_gen_code;
return hash;
}
}

View file

@ -1,58 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.meta;
public class MetaValueFloat extends MetaValueNatural {
public MetaValueFloat(String doc, Float defaultValue, Float maxValue,
Float minValue, String dimension) {
super(doc, defaultValue, maxValue, minValue, dimension);
}
@Override
public boolean setMaxValue(Object maxValue) {
boolean result;
if(maxValue instanceof Float){
this.maxValue = maxValue;
result = true;
} else {
result = false;
}
return result;
}
@Override
public boolean setMinValue(Object minValue) {
boolean result;
if(minValue instanceof Float){
this.minValue = minValue;
result = true;
} else {
result = false;
}
return result;
}
@Override
public boolean setDefaultValue(Object defaultValue) {
boolean result;
if(defaultValue instanceof Float){
this.defaultValue = defaultValue;
result = true;
} else {
result = false;
}
return result;
}
}

View file

@ -1,59 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.meta;
public class MetaValueInt extends MetaValueNatural {
public MetaValueInt(String doc, Integer defaultValue, Integer maxValue,
Integer minValue, String dimension) {
super(doc, defaultValue, maxValue, minValue, dimension);
}
@Override
public boolean setMaxValue(Object maxValue) {
boolean result;
if(maxValue instanceof Integer){
this.maxValue = maxValue;
result = true;
} else {
result = false;
}
return result;
}
@Override
public boolean setMinValue(Object minValue) {
boolean result;
if(minValue instanceof Integer){
this.minValue = minValue;
result = true;
} else {
result = false;
}
return result;
}
@Override
public boolean setDefaultValue(Object defaultValue) {
boolean result;
if(defaultValue instanceof Integer){
this.defaultValue = defaultValue;
result = true;
} else {
result = false;
}
return result;
}
}

View file

@ -1,58 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.meta;
public class MetaValueLong extends MetaValueNatural {
public MetaValueLong(String doc, Long defaultValue, Long maxValue,
Long minValue, String dimension) {
super(doc, defaultValue, maxValue, minValue, dimension);
}
@Override
public boolean setMaxValue(Object maxValue) {
boolean result;
if(maxValue instanceof Long){
this.maxValue = maxValue;
result = true;
} else {
result = false;
}
return result;
}
@Override
public boolean setMinValue(Object minValue) {
boolean result;
if(minValue instanceof Long){
this.minValue = minValue;
result = true;
} else {
result = false;
}
return result;
}
@Override
public boolean setDefaultValue(Object defaultValue) {
boolean result;
if(defaultValue instanceof Long){
this.defaultValue = defaultValue;
result = true;
} else {
result = false;
}
return result;
}
}

View file

@ -1,92 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.meta;
public abstract class MetaValueNatural extends MetaValue {
Object maxValue;
Object minValue;
public MetaValueNatural(String doc, Object defaultValue, Object maxValue,
Object minValue, String dimension) {
super(doc, defaultValue, dimension);
this.minValue = minValue;
this.maxValue = maxValue;
}
public Object getMaxValue() {
return this.maxValue;
}
public Object getMinValue() {
return this.minValue;
}
@Override
public boolean equals(Object object){
MetaValueNatural mn;
boolean result = super.equals(object);
if(result){
if(object instanceof MetaValueNatural){
mn = (MetaValueNatural)object;
if((mn.getMaxValue() == null) && (this.maxValue != null)){
result = false;
} else if((mn.getMaxValue() != null) && (this.maxValue == null)){
result = false;
} else if( ((mn.getMaxValue() == null) && (this.maxValue == null)) ||
((mn.getMaxValue().equals(this.maxValue))))
{
if((mn.getMinValue() == null) && (this.minValue != null)){
result = false;
} else if((mn.getMinValue() != null) && (this.minValue == null)){
result = false;
} else if( ((mn.getMinValue() == null) && (this.minValue == null)) ||
((mn.getMinValue().equals(this.minValue))))
{
result = true;
} else {
result = false;
}
} else {
result = false;
}
} else {
result = false;
}
}
return result;
}
@Override
public int hashCode() {
int var_gen_code;
int hash = 13;
var_gen_code = (null == maxValue ? 0 : maxValue.hashCode());
var_gen_code += (null == minValue ? 0 : minValue.hashCode());
hash = 31 * hash + var_gen_code;
return hash;
}
public abstract boolean setMaxValue(Object maxValue);
public abstract boolean setMinValue(Object minValue);
@Override
public String toString(){
String result = super.toString();
result += ", MaxValue: " + maxValue.toString() + ", MinValue: " + minValue.toString();
return result;
}
}

View file

@ -1,58 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.meta;
public class MetaValueSize extends MetaValueNatural {
public MetaValueSize(String doc, Long defaultValue, Long maxValue,
Long minValue, String dimension) {
super(doc, defaultValue, maxValue, minValue, dimension);
}
@Override
public boolean setMaxValue(Object maxValue) {
boolean result;
if(maxValue instanceof Long){
this.maxValue = maxValue;
result = true;
} else {
result = false;
}
return result;
}
@Override
public boolean setMinValue(Object minValue) {
boolean result;
if(minValue instanceof Long){
this.minValue = minValue;
result = true;
} else {
result = false;
}
return result;
}
@Override
public boolean setDefaultValue(Object defaultValue) {
boolean result;
if(defaultValue instanceof Long){
this.defaultValue = defaultValue;
result = true;
} else {
result = false;
}
return result;
}
}

View file

@ -1,50 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.meta;
public class MetaValueString extends MetaValue {
private int maxLength;
public MetaValueString(String doc, String defaultValue, int maxLength,
String dimension) {
super(doc, defaultValue, dimension);
this.maxLength = maxLength;
}
public int getMaxLength() {
return this.maxLength;
}
public void setMaxLength(int maxLength) {
this.maxLength = maxLength;
}
@Override
public boolean setDefaultValue(Object defaultValue) {
boolean result = false;
if(defaultValue instanceof String){
this.defaultValue = defaultValue;
result = true;
}
return result;
}
@Override
public int hashCode() {
int var_gen_code;
int hash = 13;
var_gen_code = (null == defaultValue ? 0 : defaultValue.hashCode());
var_gen_code += maxLength;
hash = 31 * hash + var_gen_code;
return hash;
}
}

View file

@ -1,83 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.swing;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.io.File;
import java.net.URI;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.TransferHandler;
@SuppressWarnings("serial")
public class ConfigTransferHandler extends TransferHandler {
private final ConfigWindow view;
public ConfigTransferHandler(ConfigWindow view){
this.view = view;
}
@Override
public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
for(DataFlavor flavor: transferFlavors){
if(flavor.equals(DataFlavor.javaFileListFlavor)){
view.setStatus("Drag here to open " +
flavor.getHumanPresentableName() + " file.", false);
return true;
} else if(flavor.equals(DataFlavor.stringFlavor)){
view.setStatus("Drag here to open " +
flavor.getHumanPresentableName() + " file.", false);
return true;
}
}
view.setStatus("Warning: Unsupported type.", false);
return false;
}
@Override
public boolean importData(JComponent comp, Transferable t) {
if (!canImport(comp, t.getTransferDataFlavors())) {
view.setStatus("Warning: Unsupported type", false);
return false;
}
try{
if(t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)){
@SuppressWarnings("unchecked")
List<File> files = (List<File>) t.getTransferData(DataFlavor.javaFileListFlavor);
if(files.size() == 1){
File file = files.get(0);
view.getController().handleOpen(file);
} else {
return false;
}
} else if(t.isDataFlavorSupported(DataFlavor.stringFlavor)){
String str = (String) t.getTransferData(DataFlavor.stringFlavor);
if(str.startsWith("file:/")){
File f = new File(new URI(str));
view.getController().handleOpen(f);
} else {
view.setStatus("Warning: Unsupported file.", false);
}
} else {
view.setStatus("Warning: Unsupported drag-and-drop type", false);
}
} catch (Exception e) {
view.setStatus("Warning: " + e.getMessage(), false);
return false;
}
return true;
}
}

View file

@ -1,96 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.swing;
import org.eclipse.cyclonedds.config.data.DataAttribute;
import org.eclipse.cyclonedds.config.data.DataElement;
import org.eclipse.cyclonedds.config.data.DataNode;
import org.eclipse.cyclonedds.config.meta.MetaAttribute;
import org.eclipse.cyclonedds.config.meta.MetaElement;
import org.eclipse.cyclonedds.config.meta.MetaNode;
public class ConfigUtil {
public static String getExtendedDataElementString(DataElement element){
String firstAttrChild;
DataNode[] children;
String name;
String result = null;
if(element != null){
children = element.getChildren();
firstAttrChild = null;
for(int j=0; (j<children.length) && (firstAttrChild == null); j++){
if(children[j] instanceof DataAttribute){
name = ((MetaAttribute)children[j].getMetadata()).getName();
if("name".equalsIgnoreCase(name)){
firstAttrChild = "[" + ((MetaAttribute)children[j].getMetadata()).getName() + "=";
firstAttrChild += ((DataAttribute)children[j]).getValue() + "]";
}
}
}
for(int j=0; (j<children.length) && (firstAttrChild == null); j++){
if(children[j] instanceof DataAttribute){
firstAttrChild = "[" + ((MetaAttribute)children[j].getMetadata()).getName() + "=";
firstAttrChild += ((DataAttribute)children[j]).getValue() + "]";
}
}
if(firstAttrChild == null){
firstAttrChild = "";
}
result = ((MetaElement)element.getMetadata()).getName() + firstAttrChild;
}
return result;
}
public static String getDataElementString(DataElement element){
String result = null;
if(element != null){
result = ((MetaElement)element.getMetadata()).getName();
}
return result;
}
public static String getExtendedMetaElementString(MetaElement element){
String firstAttrChild;
MetaNode[] children;
String result = null;
if(element != null){
children = element.getChildren();
firstAttrChild = null;
for(int j=0; (j<children.length) && (firstAttrChild == null); j++){
if(children[j] instanceof MetaAttribute){
firstAttrChild = "[" + ((MetaAttribute)children[j]).getName() + "]";
}
}
if(firstAttrChild == null){
firstAttrChild = "";
}
result = element.getName() + firstAttrChild;
}
return result;
}
public static String getMetaElementString(MetaElement element){
String result = null;
if(element != null){
result = element.getName();
}
return result;
}
}

View file

@ -1,630 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.swing;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Event;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import org.eclipse.cyclonedds.common.view.MainWindow;
import org.eclipse.cyclonedds.common.view.StatusPanel;
import org.eclipse.cyclonedds.config.data.DataConfiguration;
import org.eclipse.cyclonedds.config.data.DataConfigurationListener;
import org.eclipse.cyclonedds.config.data.DataElement;
import org.eclipse.cyclonedds.config.data.DataNode;
import org.eclipse.cyclonedds.config.data.DataValue;
import org.eclipse.cyclonedds.config.meta.MetaElement;
import org.eclipse.cyclonedds.config.meta.MetaNode;
public class ConfigWindow extends MainWindow implements DataConfigurationListener {
private static final long serialVersionUID = 1L;
private JPanel jContentPane = null;
private ConfigWindowController controller = null;
private JMenuBar configMenuBar = null;
private JTabbedPane mainTabbedPane = null;
private JMenu fileMenu = null;
private JMenu editMenu = null;
private JMenu addServiceMenu = null;
private JMenu removeServiceMenu = null;
private JMenuItem newItem = null;
private JMenuItem openItem = null;
private JMenuItem saveItem = null;
private JMenuItem closeItem = null;
private JMenuItem saveAsItem = null;
private JMenuItem exitItem = null;
private JMenuItem printItem = null;
private JMenu helpMenu = null;
private JMenuItem helpContentsItem = null;
private DataConfiguration config = null;
private List<Image> appLogos = null;
private DataNodePopup popupSupport = null;
private ConfigTransferHandler transferHandler = null;
private String windowTitle = "Eclipse Cyclone DDS Configurator";
public static String SERVICE_LABEL = "Component";
public static String SERVICE_TEXT = "component";
/**
* This is the default constructor
*/
public ConfigWindow() {
super();
initialize();
}
public ConfigWindow(String uri) {
super();
initialize();
controller.handleOpenFromUri(uri);
}
public DataConfiguration getConfig() {
return config;
}
public void setDataConfiguration(DataConfiguration config){
DataElement[] services;
if(this.config != null){
this.config.removeDataConfigurationListener(this);
int count = mainTabbedPane.getComponentCount();
for(int i=0; i < count; i++){
mainTabbedPane.remove(0);
}
}
this.config = config;
if(this.config != null){
this.config.addDataConfigurationListener(this);
services = config.getServices();
for(int i=0; i < services.length; i++){
ServicePanel servicePanel = new ServicePanel(services[i], this.statusPanel);
servicePanel.setTransferHandler(transferHandler);
mainTabbedPane.addTab(
ConfigUtil.getExtendedDataElementString(services[i]),
servicePanel);
}
}
this.updateMenus();
}
@Override
public void nodeAdded(DataElement parent, DataNode nodeAdded) {
this.updateMenus();
if(parent.equals(this.config.getRootElement())){
if(nodeAdded instanceof DataElement){
final DataElement service = (DataElement)nodeAdded;
Runnable worker = new Runnable(){
@Override
public void run(){
ServicePanel servicePanel = new ServicePanel(service, statusPanel);
servicePanel.setTransferHandler(transferHandler);
mainTabbedPane.addTab(
ConfigUtil.getExtendedDataElementString(service),
servicePanel);
}
};
SwingUtilities.invokeLater(worker);
}
}
}
@Override
public void nodeRemoved(DataElement parent, DataNode nodeRemoved) {
this.updateMenus();
if(parent.equals(this.config.getRootElement())){
if(nodeRemoved instanceof DataElement){
final DataElement service = (DataElement)nodeRemoved;
Runnable worker = new Runnable(){
@Override
public void run(){
ServicePanel servicePanel;
boolean found = false;
for(int i=0; (i<mainTabbedPane.getTabCount()) && (!found); i++){
servicePanel = (ServicePanel)mainTabbedPane.getComponentAt(i);
if(servicePanel.getService().equals(service)){
mainTabbedPane.removeTabAt(i);
found = true;
}
}
}
};
SwingUtilities.invokeLater(worker);
}
}
}
@Override
public void valueChanged(DataValue data, Object oldValue, Object newValue) {
ServicePanel servicePanel;
for(int i=0; i<this.mainTabbedPane.getTabCount(); i++){
servicePanel = (ServicePanel)this.mainTabbedPane.getComponentAt(i);
this.mainTabbedPane.setTitleAt(i,
ConfigUtil.getExtendedDataElementString(
servicePanel.getService()));
}
this.updateMenus();
}
public DataConfiguration getDataConfiguration(){
return this.config;
}
@Override
public void disableView(){
ServicePanel sp;
this.setEnabled(false);
this.setFocusable(false);
for(int i=0; i<this.mainTabbedPane.getComponentCount(); i++){
sp = (ServicePanel)this.mainTabbedPane.getComponentAt(i);
sp.getConfigurationTable().getEditor().stopCellEditing();
}
}
public void setActionsEnabled(boolean enabled){
ServicePanel sp;
if(enabled){
this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
} else {
this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
}
for(int i=0; i<this.mainTabbedPane.getComponentCount(); i++){
sp = (ServicePanel)this.mainTabbedPane.getComponentAt(i);
sp.setEnabled(enabled);
}
this.updateMenus();
}
/**
* Enables the view component.
*/
@Override
public void enableView(){
this.setFocusable(true);
this.setEnabled(true);
this.toFront();
}
public ConfigWindowController getController(){
return this.controller;
}
public void setWindowTitle () {
super.setTitle(this.windowTitle);
}
private void updateMenus(){
this.getAddServiceMenu().removeAll();
this.getRemoveServiceMenu().removeAll();
if(this.config != null){
if(this.config.isUpToDate()){
this.getSaveItem().setEnabled(false);
} else {
this.getSaveItem().setEnabled(true);
}
this.getSaveAsItem().setEnabled(true);
this.getPrintItem().setEnabled(true);
this.getCloseItem().setEnabled(true);
this.getAddServiceMenu().setEnabled(true);
this.getRemoveServiceMenu().setEnabled(true);
MetaNode[] mn = ((MetaElement)config.getRootElement().getMetadata()).getChildren();
for(MetaNode m: mn){
if(m instanceof MetaElement){
this.getAddServiceMenu().add(this.getAddServiceItem((MetaElement)m));
}
}
for(DataElement e: config.getServices()){
this.getRemoveServiceMenu().add(this.getRemoveServiceItem(e));
}
} else {
this.getSaveItem().setEnabled(false);
this.getSaveAsItem().setEnabled(false);
this.getPrintItem().setEnabled(false);
this.getCloseItem().setEnabled(false);
this.getAddServiceMenu().setEnabled(false);
this.getRemoveServiceMenu().setEnabled(false);
}
this.updateTitle();
}
private void updateTitle(){
File f;
String title;
if(this.config != null){
f = config.getFile();
if(f != null){
title = this.windowTitle + " | " + f.getAbsolutePath();
} else {
title = this.windowTitle + " | <NoName>";
}
} else {
title = this.windowTitle;
}
this.setTitle(title);
}
private DataNodeMenuItem getAddServiceItem(MetaElement service){
int curOcc = 0;
DataNodeMenuItem item = new DataNodeMenuItem(
service.getName(),
this.config.getRootElement(), service);
for(DataElement s: config.getServices()){
if(s.getMetadata().equals(service)){
curOcc++;
}
}
if(curOcc < service.getMaxOccurrences()){
item.setEnabled(true);
} else {
item.setEnabled(false);
}
item.setActionCommand("addService");
item.addActionListener(this.popupSupport);
return item;
}
private DataNodeMenuItem getRemoveServiceItem(DataElement service){
int curOcc = 0;
MetaElement metaService = (MetaElement)service.getMetadata();
DataNodeMenuItem item = new DataNodeMenuItem(
ConfigUtil.getExtendedDataElementString(service),
service, null);
for(DataElement s: config.getServices()){
if(s.getMetadata().equals(metaService)){
curOcc++;
}
}
if(curOcc > metaService.getMinOccurrences()){
item.setEnabled(true);
} else {
item.setEnabled(false);
}
item.setActionCommand("removeService");
item.addActionListener(this.popupSupport);
return item;
}
/**
* This method initializes this
*
* @return void
*/
private void initialize() {
this.setSize(800, 600);
this.controller = new ConfigWindowController(this);
this.popupSupport = new DataNodePopup();
this.transferHandler = new ConfigTransferHandler(this);
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
this.setJMenuBar(getConfigMenuBar());
this.setLocationRelativeTo(this.getParent());
this.setContentPane(getJContentPane());
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
controller.actionPerformed(
new ActionEvent(exitItem, 0, "exit"));
}
});
this.updateMenus();
this.setAppLogo();
}
/**
* This method initializes jContentPane
*
* @return javax.swing.JPanel
*/
private JPanel getJContentPane() {
if (jContentPane == null) {
jContentPane = new JPanel();
jContentPane.setLayout(new BorderLayout());
jContentPane.add(getMainTabbedPane(), BorderLayout.CENTER);
jContentPane.add(getStatusPanel(), BorderLayout.SOUTH);
}
return jContentPane;
}
/**
* This method initializes statusPanel.
*
* @return The status panel of the window.
*/
@Override
protected StatusPanel getStatusPanel() {
if (statusPanel == null) {
statusPanel = new StatusPanel(300, "Ready", false, true);
}
return statusPanel;
}
/**
* This method initializes configMenuBar
*
* @return javax.swing.JMenuBar
*/
private JMenuBar getConfigMenuBar() {
if (configMenuBar == null) {
configMenuBar = new JMenuBar();
configMenuBar.add(getFileMenu());
configMenuBar.add(getEditMenu());
configMenuBar.add(getHelpMenu());
}
return configMenuBar;
}
/**
* This method initializes mainTabbedPane
*
* @return javax.swing.JTabbedPane
*/
private JTabbedPane getMainTabbedPane() {
if (mainTabbedPane == null) {
mainTabbedPane = new JTabbedPane();
mainTabbedPane.setTransferHandler(this.transferHandler);
}
return mainTabbedPane;
}
/**
* This method initializes fileMenu
*
* @return javax.swing.JMenu
*/
private JMenu getFileMenu() {
if (fileMenu == null) {
fileMenu = new JMenu();
fileMenu.setText("File");
fileMenu.setMnemonic(KeyEvent.VK_F);
fileMenu.add(getNewItem());
fileMenu.add(getOpenItem());
fileMenu.add(getCloseItem());
fileMenu.addSeparator();
fileMenu.add(getSaveItem());
fileMenu.add(getSaveAsItem());
fileMenu.addSeparator();
fileMenu.add(getPrintItem());
fileMenu.addSeparator();
fileMenu.add(getExitItem());
}
return fileMenu;
}
private JMenu getEditMenu(){
if (editMenu == null){
editMenu = new JMenu();
editMenu.setText("Edit");
editMenu.setMnemonic(KeyEvent.VK_E);
editMenu.add(getAddServiceMenu());
editMenu.add(getRemoveServiceMenu());
}
return editMenu;
}
private JMenu getHelpMenu(){
if (helpMenu == null){
helpMenu = new JMenu();
helpMenu.setText("Help");
helpMenu.setMnemonic(KeyEvent.VK_H);
helpMenu.add(getHelpContentsItem());
}
return helpMenu;
}
private JMenuItem getHelpContentsItem(){
if (helpContentsItem == null){
helpContentsItem = new JMenuItem();
helpContentsItem.setText("Help Contents");
helpContentsItem.setMnemonic(KeyEvent.VK_C);
helpContentsItem.setActionCommand("help");
helpContentsItem.addActionListener(getController());
helpContentsItem.setAccelerator(KeyStroke.getKeyStroke("control H"));
}
return helpContentsItem;
}
private JMenu getAddServiceMenu(){
if (addServiceMenu == null){
addServiceMenu = new JMenu();
addServiceMenu.setText("Add " + SERVICE_LABEL);
addServiceMenu.setMnemonic(KeyEvent.VK_A);
}
return addServiceMenu;
}
private JMenu getRemoveServiceMenu(){
if (removeServiceMenu == null){
removeServiceMenu = new JMenu();
removeServiceMenu.setText("Remove " + SERVICE_LABEL);
removeServiceMenu.setMnemonic(KeyEvent.VK_R);
}
return removeServiceMenu;
}
/**
* This method initializes newItem
*
* @return javax.swing.JMenuItem
*/
private JMenuItem getNewItem() {
if (newItem == null) {
newItem = new JMenuItem();
newItem.setText("New...");
newItem.setMnemonic(KeyEvent.VK_N);
newItem.setAccelerator(KeyStroke.getKeyStroke("control N"));
newItem.setActionCommand("new");
newItem.addActionListener(controller);
}
return newItem;
}
/**
* This method initializes openItem
*
* @return javax.swing.JMenuItem
*/
private JMenuItem getOpenItem() {
if (openItem == null) {
openItem = new JMenuItem();
openItem.setText("Open...");
openItem.setMnemonic(KeyEvent.VK_O);
openItem.setAccelerator(KeyStroke.getKeyStroke("control O"));
openItem.setActionCommand("open");
openItem.addActionListener(controller);
}
return openItem;
}
/**
* This method initializes saveItem
*
* @return javax.swing.JMenuItem
*/
private JMenuItem getSaveItem() {
if (saveItem == null) {
saveItem = new JMenuItem();
saveItem.setText("Save");
saveItem.setMnemonic(KeyEvent.VK_S);
saveItem.setAccelerator(KeyStroke.getKeyStroke("control S"));
saveItem.setActionCommand("save");
saveItem.addActionListener(controller);
}
return saveItem;
}
/**
* This method initializes closeItem
*
* @return javax.swing.JMenuItem
*/
private JMenuItem getCloseItem() {
if (closeItem == null) {
closeItem = new JMenuItem();
closeItem.setText("Close");
closeItem.setMnemonic(KeyEvent.VK_C);
closeItem.setActionCommand("close");
closeItem.addActionListener(controller);
}
return closeItem;
}
/**
* This method initializes saveAsItem
*
* @return javax.swing.JMenuItem
*/
private JMenuItem getSaveAsItem() {
if (saveAsItem == null) {
saveAsItem = new JMenuItem();
saveAsItem.setText("Save As...");
saveAsItem.setMnemonic(KeyEvent.VK_A);
saveAsItem.setActionCommand("save_as");
saveAsItem.addActionListener(controller);
}
return saveAsItem;
}
/**
* This method initializes exitItem
*
* @return javax.swing.JMenuItem
*/
private JMenuItem getExitItem() {
if (exitItem == null) {
exitItem = new JMenuItem();
exitItem.setText("Exit");
exitItem.setMnemonic(KeyEvent.VK_X);
exitItem.setAccelerator(KeyStroke.getKeyStroke("alt F4"));
exitItem.setActionCommand("exit");
exitItem.addActionListener(controller);
}
return exitItem;
}
/**
* This method initializes printItem
*
* @return javax.swing.JMenuItem
*/
private JMenuItem getPrintItem() {
if (printItem == null) {
printItem = new JMenuItem();
printItem.setText("Print...");
printItem.setMnemonic(KeyEvent.VK_P);
printItem.setAccelerator(KeyStroke.getKeyStroke("control P"));
printItem.setActionCommand("print");
printItem.addActionListener(controller);
}
return printItem;
}
/**
* Set the Logo image to be used in Configurator's window and taskbar button.
*/
private void setAppLogo() {
if (appLogos == null) {
try {
List<URL> imgUrls = new ArrayList<URL>(4);
// Expected location of the icons in tuner jar
//URL url = getClass().getResource("/resources/LOGO.png");
//imgUrls.add(url != null ? url : getClass().getResource("/ptlogoc16.png"));
appLogos = new ArrayList<Image>(4);
for (URL imgUrl : imgUrls) {
if (imgUrl != null) {
appLogos.add(Toolkit.getDefaultToolkit().getImage(imgUrl));
}
}
this.setIconImages(appLogos);
} catch (Exception e) {}
}
}
}

View file

@ -1,581 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.swing;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.PrinterJob;
import java.io.File;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.MediaSizeName;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;
import org.eclipse.cyclonedds.common.util.Report;
import org.eclipse.cyclonedds.config.data.DataConfiguration;
import org.eclipse.cyclonedds.config.data.DataException;
import org.eclipse.cyclonedds.config.meta.MetaConfiguration;
public class ConfigWindowController implements ActionListener {
private final ConfigWindow view;
private HelpWindow helpView;
private boolean closeInProgress;
private boolean exitInProgress;
private boolean newInProgress;
private boolean openInProgress;
private File curFile;
private final JFileChooser openFileChooser;
private final JFileChooser saveFileChooser;
public ConfigWindowController(ConfigWindow view){
this.view = view;
this.closeInProgress = false;
this.exitInProgress = false;
this.newInProgress = false;
this.openInProgress = false;
this.openFileChooser = new JFileChooser();
this.saveFileChooser = new JFileChooser();
this.curFile = null;
this.helpView = null;
// Initialize the MetaConfiguration. This is done so the Configurator can know for
// which product its meant for, according to the meta config file.
MetaConfiguration.getInstance();
view.setWindowTitle();
File f = null;
String fileSep = System.getProperty("file.separator");
f = new File(System.getProperty("user.dir") + fileSep);
this.openFileChooser.setCurrentDirectory(f);
this.openFileChooser.setDialogTitle("Open configuration");
this.openFileChooser.setMultiSelectionEnabled(false);
this.openFileChooser.setFileFilter(new ConfigChooseFilter());
this.openFileChooser.setAcceptAllFileFilterUsed(false);
this.openFileChooser.setApproveButtonText("Open");
this.saveFileChooser.setCurrentDirectory(f);
this.saveFileChooser.setDialogTitle("Save configuration");
this.saveFileChooser.setMultiSelectionEnabled(false);
this.saveFileChooser.setFileFilter(new ConfigChooseFilter());
this.saveFileChooser.setAcceptAllFileFilterUsed(false);
this.saveFileChooser.setApproveButtonText("Save");
}
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
try{
if("exit".equals(command)){
this.exitInProgress = true;
this.handleConditionalSave();
} else if("close".equals(command)){
this.closeInProgress = true;
this.handleConditionalSave();
} else if("save".equals(command)){
this.handleSave(false);
} else if("save_as".equals(command)){
this.handleSave(true);
} else if("new".equals(command)){
this.newInProgress = true;
this.handleConditionalSave();
} else if("open".equals(command)){
this.openInProgress = true;
this.handleConditionalSave();
} else if("print".equals(command)){
this.handlePrint();
} else if("help".equals(command)){
this.handleHelp();
} else if("cancel".equals(command)){
this.handleCancel();
} else {
this.handleSetStatus("Warning: Command '" + command + "' not implemented.", false, false);
}
} catch(Exception ex){
this.handleSetStatus("Error: " + ex.getMessage(), false, false);
this.printStackTrace(ex);
this.handleSetEnabled(true);
}
}
private void handleConditionalSave(){
DataConfiguration config = view.getDataConfiguration();
if(config == null){
this.handleNextAction();
} else if(config.isUpToDate()){
this.handleNextAction();
} else {
int answer = JOptionPane.showConfirmDialog(
this.view,
"Configuration has changed. Save changes?",
"Close configuration",
JOptionPane.YES_NO_CANCEL_OPTION);
if(answer == JOptionPane.YES_OPTION){
this.handleSave(false);
} else if(answer == JOptionPane.NO_OPTION){
this.handleNextAction();
} else {
this.handleCancel();
}
}
}
private void handlePrint(){
final DataConfiguration config = view.getDataConfiguration();
if(config == null){
this.handleSetStatus("No configuration to print.", false);
} else {
this.handleSetStatus("Printing configuration...", true);
this.handleSetEnabled(false);
Runnable worker = new Runnable(){
@Override
public void run(){
try {
PrinterJob pjob = PrinterJob.getPrinterJob();
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(MediaSizeName.ISO_A4);
aset.add(new Copies(1));
boolean doPrint = pjob.printDialog(aset);
if(doPrint){
/*
if(currentDialog != null){
currentDialog.setStatus(null, true);
}
DocFlavor flavor = DocFlavor.INPUT_STREAM.POSTSCRIPT;
Doc doc = new SimpleDoc(config.toString(), flavor, null);
DocPrintJob docPrintJob = pjob.getPrintService().createPrintJob();
docPrintJob.print(doc, aset);
handleSetStatus("Configuration printed.", true);
*/
view.setStatus("Warning: Printing not supported yet.", false);
handleSetEnabled(true);
} else {
handleCancel();
}
} catch (Exception e) {
view.setStatus("Error:" + e.getMessage(), false);
handleSetEnabled(true);
}
}
};
SwingUtilities.invokeLater(worker);
}
}
private void handleExit(){
this.exitInProgress = false;
view.dispose();
System.exit(0);
}
public void handleOpen(File file){
this.curFile = file;
this.openInProgress = true;
this.handleConditionalSave();
}
private void handleOpen(){
openInProgress = false;
File file = null;
if(this.curFile != null){
file = this.curFile;
} else {
int returnVal = this.openFileChooser.showOpenDialog(this.view);
if (returnVal == JFileChooser.APPROVE_OPTION) {
file = this.openFileChooser.getSelectedFile();
} else {
this.handleSetStatus("No file opened", false, false);
this.handleNextAction();
}
}
if(file != null){
final File f = file;
this.handleSetEnabled(false);
view.setStatus("Opening configuration from " + f.getAbsolutePath() + "...", true, true);
view.repaint();
Runnable worker = new Runnable(){
@Override
public void run(){
view.setDataConfiguration(null);
DataConfiguration config = null;
try {
config = new DataConfiguration(f, false);
} catch (DataException e) {
Report.getInstance().writeInfoLog("ConfigWindowController handleOpen\n" + e.getMessage());
}
if(config != null){
view.setDataConfiguration(config);
view.setStatus("Configuration opened.", false);
} else {
view.setStatus("Configuration could not be opened.", false);
}
handleNextAction();
}
};
SwingUtilities.invokeLater(worker);
}
this.curFile = null;
}
public void handleOpenFromUri(String uri) {
openInProgress = false;
File file = null;
if (uri.startsWith("file://")) {
/* strip off file:// */
uri = uri.substring(7);
}
file = new File(uri);
final File f = file;
this.handleSetEnabled(false);
view.setStatus("Opening configuration from " + f.getAbsolutePath()
+ "...", true, true);
view.repaint();
Runnable worker = new Runnable() {
@Override
public void run() {
view.setDataConfiguration(null);
DataConfiguration config = null;
try {
config = new DataConfiguration(f, false);
} catch (DataException e) {
Report.getInstance().writeInfoLog(
"ConfigWindowController handleOpen\n"
+ e.getMessage());
int answer = JOptionPane.showConfirmDialog(
view,
"The configuration is not valid.\nReason: "
+ e.getMessage()
+ "\nTry automatic repairing?",
"Invalid configuration", JOptionPane.YES_NO_OPTION);
if (answer == JOptionPane.YES_OPTION) {
try {
config = new DataConfiguration(f, true);
view.setStatus(
"Configuration repaired successfully.",
false);
} catch (DataException e1) {
JOptionPane.showMessageDialog(view,
"Configuration could not be repaired.\nReason: '"
+ e.getMessage() + "'", "Error",
JOptionPane.ERROR_MESSAGE);
handleSetStatus(
"Configuration could not be repaired.",
false);
handleNextAction();
}
} else if (answer == JOptionPane.NO_OPTION) {
handleSetStatus("Configuration not opened.", false);
handleNextAction();
}
}
if (config != null) {
view.setDataConfiguration(config);
view.setStatus("Configuration opened.", false);
handleNextAction();
}
}
};
SwingUtilities.invokeLater(worker);
this.curFile = null;
}
private void handleSave(boolean alwaysAskFile){
int returnVal;
File file;
int answer;
String path;
boolean proceed = false;
final DataConfiguration config = view.getDataConfiguration();
if(config == null){
this.handleCancel("Warning: No configuration to save.");
return;
}
this.handleSetEnabled(false);
if((!alwaysAskFile) && (config.getFile() != null)){
this.handleSetStatus("Saving configuration to: " + config.getFile().getAbsolutePath() + "...", true);
Runnable worker = new Runnable(){
@Override
public void run(){
try {
config.store(true);
view.setStatus("Configuration saved.", false, false);
handleNextAction();
} catch (DataException e) {
handleSetStatus("Error: Cannot save configuration to: " +
config.getFile().getAbsolutePath(),
false);
handleNextAction();
}
}
};
SwingUtilities.invokeLater(worker);
} else {
try{
do {
answer = JOptionPane.CANCEL_OPTION;
saveFileChooser.setSelectedFile(config.getFile());
returnVal = this.saveFileChooser.showSaveDialog(this.view);
if (returnVal == JFileChooser.APPROVE_OPTION) {
file = this.saveFileChooser.getSelectedFile();
path = file.getAbsolutePath();
if(!path.endsWith(ConfigChooseFilter.CONFIG_SUFFIX)){
path = path + ConfigChooseFilter.CONFIG_SUFFIX;
file = new File(path);
}
this.handleSetStatus("Saving configuration to: " + file.getAbsolutePath() + "...", true);
if(file.equals(config.getFile())){
proceed = true;
} else if (file.exists()){
answer = JOptionPane.showConfirmDialog(
this.view,
"The file '" + path + "' already exists. Overwrite?",
"File already exists",
JOptionPane.YES_NO_CANCEL_OPTION);
if(answer == JOptionPane.YES_OPTION){
proceed = true;
config.setFile(file);
} else if(answer == JOptionPane.NO_OPTION){
proceed = false;
} else {
proceed = false;
this.handleNextAction();
}
} else {
config.setFile(file);
proceed = true;
}
} else {
proceed = false;
this.handleNextAction();
}
} while(answer == JOptionPane.NO_OPTION);
if(proceed){
this.handleSetStatus("Saving configuration to: " + config.getFile().getAbsolutePath() + "...", true);
Runnable worker = new Runnable(){
@Override
public void run(){
try {
config.store(true);
view.setStatus("Configuration saved.", false, false);
handleNextAction();
} catch (DataException e) {
view.setStatus("Error:" + e.getMessage(), false);
handleSetEnabled(true);
}
}
};
SwingUtilities.invokeLater(worker);
}
} catch (DataException e) {
this.handleSetStatus("Error: " + e.getMessage(), false);
handleSetEnabled(true);
} catch(Exception exc){
this.handleSetStatus("Error: " + exc.getMessage(), false);
handleSetEnabled(true);
}
}
}
private void handleHelp(){
if(helpView != null){
helpView.toFront();
} else {
view.setStatus("Opening help for configuration...", true, true);
this.handleSetEnabled(false);
Runnable worker = new Runnable(){
@Override
public void run(){
MetaConfiguration metaConfig = MetaConfiguration.getInstance();
if (metaConfig != null) {
helpView = new HelpWindow(metaConfig);
helpView.setLocationRelativeTo(view);
view.setStatus("Help pane openened.", false, false);
handleSetEnabled(true);
helpView.addWindowListener(new WindowAdapter(){
@Override
public void windowClosed(WindowEvent e) {
helpView = null;
}
});
helpView.setVisible(true);
helpView.toFront();
} else {
view.setStatus("Failed to open the configuration help", true, false);
}
}
};
SwingUtilities.invokeLater(worker);
}
}
private void handleNew(){
view.setStatus("Creating new configuration...", true, true);
this.handleSetEnabled(false);
Runnable worker = new Runnable(){
@Override
public void run(){
view.setDataConfiguration(null);
newInProgress = false;
try {
DataConfiguration config = new DataConfiguration();
view.setDataConfiguration(config);
view.setStatus("New configuration created.", false, false);
} catch (DataException e) {
view.setStatus("Error: Could not create new configuration.", false, false);
}
handleSetEnabled(true);
}
};
SwingUtilities.invokeLater(worker);
}
private void handleClose(){
view.setStatus("Closing configuration...", true, true);
this.handleSetEnabled(false);
Runnable worker = new Runnable(){
@Override
public void run(){
view.setDataConfiguration(null);
closeInProgress = false;
view.setStatus("Configuration closed.", false);
handleSetEnabled(true);
}
};
SwingUtilities.invokeLater(worker);
}
private void handleNextAction(){
if(closeInProgress){
handleClose();
} else if(exitInProgress){
exitInProgress = false;
handleExit();
} else if(newInProgress){
handleNew();
} else if(openInProgress){
handleOpen();
} else {
handleSetEnabled(true);
}
}
private void handleCancel(){
view.setStatus("Action cancelled.", false);
this.handleSetEnabled(true);
}
private void handleCancel(String message){
view.setStatus(message, false);
this.handleSetEnabled(true);
}
private void handleSetEnabled(boolean enabled){
if(enabled){
this.view.enableView();
} else {
this.view.disableView();
}
this.view.setActionsEnabled(enabled);
}
private void handleSetStatus(String message, boolean persistent, boolean busy){
this.view.setStatus(message, persistent, busy);
}
private void handleSetStatus(String message, boolean persistent){
this.view.setStatus(message, persistent, false);
}
private void printStackTrace(Exception exception){
StackTraceElement[] elements = exception.getStackTrace();
StringBuffer buf = new StringBuffer();
buf.append("The following exception occurred: \n");
for(int i=0; i<elements.length; i++){
buf.append(elements[i].getFileName() + ", " +
elements[i].getMethodName() + ", " +
elements[i].getLineNumber() + "\n");
}
String error = buf.toString();
Report.getInstance().writeErrorLog(error);
}
private static class ConfigChooseFilter extends FileFilter{
private static String description = null;
public static final String CONFIG_SUFFIX = ".xml";
public ConfigChooseFilter(){
ConfigChooseFilter.description = "Eclipse Cyclone DDS config files (*" +
ConfigChooseFilter.CONFIG_SUFFIX + ")";
}
@Override
public boolean accept(File f) {
if (f.isDirectory()) {
return true;
}
if(f.getName().endsWith(ConfigChooseFilter.CONFIG_SUFFIX)){
return true;
}
return false;
}
@Override
public String getDescription() {
return ConfigChooseFilter.description;
}
}
}

View file

@ -1,84 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.swing;
import java.awt.Point;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import org.eclipse.cyclonedds.common.view.StatusPanel;
import org.eclipse.cyclonedds.config.data.DataElement;
import org.eclipse.cyclonedds.config.data.DataNode;
public class DataElementTable extends JTable implements DataNodePopupSupport {
private static final long serialVersionUID = 3904871676109190600L;
private final DataElementTableCellRenderer renderer;
private final DataElementTableModel model;
private final DataElementTableModelEditor editor;
private DataNodePopup popupController;
private final StatusPanel status;
public DataElementTable(DataNodePopup popup, DataElement element, StatusPanel status){
super();
this.model = new DataElementTableModel();
this.editor = new DataElementTableModelEditor(model);
this.renderer = new DataElementTableCellRenderer(model);
this.editor.setStatusListener(status);
this.model.setElement(element);
this.status = status;
this.setModel(model);
this.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
this.getTableHeader().setReorderingAllowed(false);
this.setSurrendersFocusOnKeystroke(true);
this.getColumnModel().getColumn(1).setCellEditor(editor);
this.getColumnModel().getColumn(1).setCellRenderer(renderer);
if(popup == null){
this.popupController = new DataNodePopup();
} else {
this.popupController = popup;
}
this.popupController.registerPopupSupport(this);
}
public void setStatusListener(StatusPanel status){
this.editor.setStatusListener(status);
}
public DataNode getDataNodeAt(int row){
this.getSelectionModel().setSelectionInterval(row, row);
return this.model.getNodeAt(row);
}
@Override
public DataNode getDataNodeAt(int x, int y) {
int row = this.rowAtPoint(new Point(x, y));
return this.getDataNodeAt(row);
}
@Override
public void showPopup(JPopupMenu popup, int x, int y) {
popup.show(this, x, y);
}
@Override
public void setStatus(String message, boolean persistent, boolean busy) {
if(this.status != null){
this.status.setStatus(message, persistent, busy);
}
}
public DataElementTableModelEditor getEditor() {
return this.editor;
}
}

View file

@ -1,50 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.swing;
import java.awt.Color;
import java.awt.Component;
import java.util.logging.Logger;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import org.eclipse.cyclonedds.config.data.DataNode;
public class DataElementTableCellRenderer extends DefaultTableCellRenderer {
private static final long serialVersionUID = 8091366819992773074L;
private DataElementTableModel tableModel = null;
public DataElementTableCellRenderer(DataElementTableModel tableModel){
this.tableModel = tableModel;
Logger.getLogger("org.eclipse.cyclonedds.config.swing");
}
@Override
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column){
Component comp = super.getTableCellRendererComponent (table,
value, isSelected, hasFocus, row, column);
DataNode node = tableModel.getNodeAt(row);
node = node.getParent();
table.setToolTipText(null);
comp.setBackground (Color.WHITE);
comp.setForeground (Color.BLACK);
table.setToolTipText(null);
return comp;
}
}

View file

@ -1,196 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.swing;
import java.util.ArrayList;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import org.eclipse.cyclonedds.config.data.DataAttribute;
import org.eclipse.cyclonedds.config.data.DataConfiguration;
import org.eclipse.cyclonedds.config.data.DataConfigurationListener;
import org.eclipse.cyclonedds.config.data.DataElement;
import org.eclipse.cyclonedds.config.data.DataNode;
import org.eclipse.cyclonedds.config.data.DataValue;
import org.eclipse.cyclonedds.config.meta.MetaAttribute;
import org.eclipse.cyclonedds.config.meta.MetaElement;
public class DataElementTableModel extends DefaultTableModel implements DataConfigurationListener {
private static final long serialVersionUID = -217503219724923467L;
private DataElement element;
private ArrayList<DataNode> nodes;
private DataConfiguration configuration;
public DataElementTableModel(){
super();
this.element = null;
this.configuration = null;
this.nodes = new ArrayList<DataNode>();
this.addColumn("Name");
this.addColumn("Value");
}
public void setElement(DataElement element){
if(this.element != null){
this.clear();
}
if(element != null){
this.element = element;
this.initElement();
if(!this.element.getOwner().equals(this.configuration)){
if(this.configuration != null){
this.configuration.removeDataConfigurationListener(this);
}
this.configuration = this.element.getOwner();
this.configuration.addDataConfigurationListener(this);
}
}
}
@Override
public void nodeAdded(DataElement parent, DataNode nodeAdded) {
DataNode parentParent;
if(parent.equals(this.element)){
this.clear();
this.initElement();
} else {
parentParent = parent.getParent();
if(this.element.equals(parentParent)){
this.clear();
this.initElement();
}
}
}
@Override
public void nodeRemoved(DataElement parent, DataNode nodeRemoved) {
if(nodeRemoved.equals(this.element)){
this.setElement(null);
} else if(this.nodes.contains(nodeRemoved)){
this.clear();
this.initElement();
} else if(this.containsNodeAsParent(nodeRemoved)){
this.clear();
this.initElement();
}
}
private boolean containsNodeAsParent(DataNode node){
for(DataNode n: this.nodes){
if(n.getParent().equals(node)){
return true;
}
}
return false;
}
@Override
public void valueChanged(DataValue data, Object oldValue, Object newValue) {
final int index = this.nodes.indexOf(data);
final Object v = newValue;
if(index != -1){
/*System.out.println("Value changed: data: " + data + ", oldValue: " + oldValue + " newValue: " + newValue + "(row=" + index +", col=1)");*/
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
setValueAt(v, index, 1);
}
});
}
}
public DataNode getNodeAt(int index){
DataNode result;
if(this.nodes.size() >= (index-1)){
result = this.nodes.get(index);
} else {
result = null;
}
return result;
}
@Override
public boolean isCellEditable(int row, int column) {
boolean result;
if(column == 1) {
result = true;
} else {
result = false;
}
return result;
}
private void initElement(){
String elName;
Object[] values = new Object[2];
for(DataNode dn: this.element.getChildren()){
if(dn instanceof DataAttribute){
values[0] = "@" + ((MetaAttribute)dn.getMetadata()).getName();
values[1] = ((DataAttribute)dn).getValue();
this.nodes.add(((DataAttribute)dn).getDataValue());
this.addRow(values);
}
}
for(DataNode dn: this.element.getChildren()){
if(dn instanceof DataValue){
values[0] = "";
values[1] = ((DataValue)dn).getValue();
this.nodes.add(dn);
this.addRow(values);
}
}
for(DataNode dn: this.element.getChildren()){
if(dn instanceof DataElement){
if(!((MetaElement)dn.getMetadata()).hasElementChildren() &&
((MetaElement)dn.getMetadata()).hasValueChildren())
{
elName = ((MetaElement)dn.getMetadata()).getName();
for(DataNode elNode: ((DataElement)dn).getChildren()){
if(elNode instanceof DataValue){
values[0] = elName;
values[1] = ((DataValue)elNode).getValue();
this.nodes.add(elNode);
this.addRow(values);
} else if(elNode instanceof DataAttribute){
values[0] = elName + "[@" + ((MetaAttribute)elNode.getMetadata()).getName() + "]";
values[1] = ((DataAttribute)elNode).getValue();
this.nodes.add(((DataAttribute)elNode).getDataValue());
this.addRow(values);
}
}
}
}
}
}
private void clear(){
int rows = super.getRowCount();
for(int i=0; i<rows; i++){
super.removeRow(0);
}
this.nodes.clear();
return;
}
}

View file

@ -1,224 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.swing;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.AbstractCellEditor;
import javax.swing.JComboBox;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.TableCellEditor;
import org.eclipse.cyclonedds.common.controller.AssignmentResult;
import org.eclipse.cyclonedds.common.util.Config;
import org.eclipse.cyclonedds.common.view.StatusPanel;
import org.eclipse.cyclonedds.config.data.DataException;
import org.eclipse.cyclonedds.config.data.DataValue;
import org.eclipse.cyclonedds.config.meta.MetaValue;
import org.eclipse.cyclonedds.config.meta.MetaValueBoolean;
import org.eclipse.cyclonedds.config.meta.MetaValueEnum;
import org.eclipse.cyclonedds.config.meta.MetaValueNatural;
import org.eclipse.cyclonedds.config.meta.MetaValueString;
public class DataElementTableModelEditor extends AbstractCellEditor implements TableCellEditor, ActionListener, KeyListener {
private static final long serialVersionUID = 805706250918260825L;
private Object curValue = null;
private StatusPanel status;
private final Color editColor = Config.getInputColor();
private final Color errorColor = Config.getIncorrectColor();
private int editRow, editColumn;
private Component curEditor = null;
private DataElementTableModel tableModel = null;
private DataValue editNode;
private MetaValue editType;
public DataElementTableModelEditor(DataElementTableModel tableModel){
this.tableModel = tableModel;
}
public void setStatusListener(StatusPanel status){
this.status = status;
}
@Override
public void cancelCellEditing(){
super.cancelCellEditing();
curEditor = null;
if(status != null){
status.setStatus("Editing cancelled", false, false);
}
}
@Override
public boolean stopCellEditing(){
boolean result = true;
if(curEditor != null){
result = this.assign().isValid();
if(result){
result = super.stopCellEditing();
curEditor = null;
} else {
this.cancelCellEditing();
}
}
return result;
}
@Override
public Object getCellEditorValue() {
return curValue;
}
public boolean isEditing(){
assert (editRow != -1) && (editColumn != -1): "Value of editRow || editColumn == null";
return (curEditor != null);
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
Component result = null;
editRow = row;
editColumn = column;
curValue = value;
editNode = (DataValue)tableModel.getNodeAt(editRow);
if (editNode != null) {
editType = (MetaValue)editNode.getMetadata();
}
if(editType instanceof MetaValueBoolean){
String[] values = { "true", "false" };
JComboBox<String> combo = new JComboBox<String>(values);
result = combo;
combo.setSelectedItem(curValue);
combo.addActionListener(this);
} else if(editType instanceof MetaValueEnum){
JComboBox<String> combo = new JComboBox<String>();
result = combo;
for(String posValue: ((MetaValueEnum)editType).getPosValues()){
combo.addItem(posValue);
}
combo.setSelectedItem(curValue);
combo.addActionListener(this);
} else {
result = new JTextField(curValue.toString());
}
curEditor = result;
curEditor.setBackground(editColor);
curEditor.addKeyListener(this);
return result;
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(curEditor)){
this.assign();
}
}
@Override
public void keyReleased(KeyEvent e) {
if(curEditor != null){
if(e.getSource() instanceof JTextField){
AssignmentResult test = this.testAssignment();
if(test.isValid()){
curEditor.setBackground(editColor);
if(status != null){
status.setStatus("Current input valid.", false, false);
}
} else {
curEditor.setBackground(errorColor);
if(status != null){
status.setStatus("Error: " + test.getErrorMessage(), false, false);
}
}
} else if(e.getSource() instanceof JComboBox){
/*Do nothing.*/
}
}
}
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyPressed(KeyEvent e) {}
public AssignmentResult testAssignment(){
AssignmentResult result = new AssignmentResult(true, null);
String value;
if(curEditor != null){
try {
if((editType instanceof MetaValueNatural) || (editType instanceof MetaValueString)) {
JTextField source = (JTextField)curEditor;
value = source.getText();
editNode.testSetValue(value);
} else {
// No validation required.
}
} catch(DataException ne){
result = new AssignmentResult(false, "Invalid input: " + (ne.getMessage()).toLowerCase());
}
}
return result;
}
@SuppressWarnings("rawtypes")
private AssignmentResult assign(){
Object value = null;
AssignmentResult test = this.testAssignment();
if(test.isValid()){
if(status != null){
status.setStatus("Input valid.", false, false);
}
if(curEditor instanceof JTextField){
value = ((JTextField)curEditor).getText();
} else if(curEditor instanceof JComboBox){
value = ((JComboBox) curEditor).getSelectedItem();
}
try {
if(!editNode.getValue().equals(value)){
assert editNode.getOwner() != null: "Owner == null (" + editNode.getMetadata() + ")";
editNode.getOwner().setValue(editNode, value);
}
} catch (DataException e) {
assert false: "this.testAssignment does not work properly";
}
curEditor.removeKeyListener(this);
curEditor = null;
editNode = null;
editType = null;
fireEditingStopped();
} else if(status != null){
status.setStatus("Error: Invalid input " + test.getErrorMessage().toLowerCase(), false, false);
}
return test;
}
}

View file

@ -1,223 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.swing;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.font.FontRenderContext;
import javax.swing.JLabel;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import org.eclipse.cyclonedds.common.view.StatusPanel;
import org.eclipse.cyclonedds.config.data.DataConfigurationListener;
import org.eclipse.cyclonedds.config.data.DataElement;
import org.eclipse.cyclonedds.config.data.DataNode;
import org.eclipse.cyclonedds.config.data.DataValue;
import org.eclipse.cyclonedds.config.meta.MetaElement;
public class DataElementTree extends JTree
implements DataConfigurationListener, TreeCellRenderer, DataNodePopupSupport
{
private static final long serialVersionUID = 5103341138480897742L;
private final DataElement rootElement;
private final DefaultMutableTreeNode rootNode;
private final DefaultTreeModel model;
private final DefaultTreeCellRenderer initialRenderer;
private DataNodePopup popupController;
private final StatusPanel status;
public DataElementTree(DataElement rootElement, DataNodePopup popup, StatusPanel status){
super();
this.initialRenderer = new DefaultTreeCellRenderer();
this.setCellRenderer(this);
this.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
this.setEditable(false);
this.setRootVisible(true);
this.setShowsRootHandles(true);
this.rootElement = rootElement;
this.status = status;
this.rootElement.getOwner().addDataConfigurationListener(this);
this.rootNode = new DefaultMutableTreeNode(this.rootElement);
this.model = ((DefaultTreeModel)this.treeModel);
this.model.setRoot(this.rootNode);
this.initElement(this.rootNode, this.rootElement);
if(this.rootNode.getChildCount() > 0){
this.scrollPathToVisible(
new TreePath(
((DefaultMutableTreeNode)this.rootNode.getFirstChild()).getPath()));
}
this.setSelectionPath(new TreePath(this.rootNode.getPath()));
if(popup == null){
this.popupController = new DataNodePopup();
} else {
this.popupController = popup;
}
this.popupController.registerPopupSupport(this);
}
private void initElement(DefaultMutableTreeNode parent, DataElement element){
DefaultMutableTreeNode node;
for(DataNode child: element.getChildren()){
if(child instanceof DataElement){
if(((MetaElement)child.getMetadata()).hasElementChildren()){
node = new DefaultMutableTreeNode(child);
this.model.insertNodeInto(node, parent, parent.getChildCount());
this.initElement(node, (DataElement)child);
} else if(!((MetaElement)child.getMetadata()).hasValueChildren()){
node = new DefaultMutableTreeNode(child);
this.model.insertNodeInto(node, parent, parent.getChildCount());
this.initElement(node, (DataElement)child);
}
}
}
}
@Override
public void nodeAdded(DataElement parent, DataNode nodeAdded) {
DefaultMutableTreeNode parentNode, childNode;
if(nodeAdded instanceof DataElement){
parentNode = this.lookupNode(this.rootNode, parent);
if(parentNode != null){
if(((MetaElement)nodeAdded.getMetadata()).hasElementChildren()){
childNode = new DefaultMutableTreeNode(nodeAdded);
this.model.insertNodeInto(childNode, parentNode, parentNode.getChildCount());
this.scrollPathToVisible(new TreePath(childNode.getPath()));
this.initElement(childNode, (DataElement)nodeAdded);
} else if(!((MetaElement)nodeAdded.getMetadata()).hasValueChildren()){
childNode = new DefaultMutableTreeNode(nodeAdded);
this.model.insertNodeInto(childNode, parentNode, parentNode.getChildCount());
this.scrollPathToVisible(new TreePath(childNode.getPath()));
this.initElement(childNode, (DataElement)nodeAdded);
}
}
}
this.repaint();
}
@Override
public void nodeRemoved(DataElement parent, DataNode nodeRemoved) {
DefaultMutableTreeNode node;
if(nodeRemoved instanceof DataElement){
node = this.lookupNode(this.rootNode, (DataElement)nodeRemoved);
if(node != null){
if(node.getParent() != null){
this.setSelectionPath(new TreePath(((DefaultMutableTreeNode)node.getParent()).getPath()));
}
if(node.getParent() != null){
this.model.removeNodeFromParent(node);
}
}
}
this.repaint();
}
@Override
public void valueChanged(DataValue data, Object oldValue, Object newValue) {
this.repaint();
}
private DefaultMutableTreeNode lookupNode(DefaultMutableTreeNode node, DataElement element){
DefaultMutableTreeNode result = null;
if(node.getUserObject().equals(element)){
result = node;
} else {
for(int i=0; (i<node.getChildCount()) && (result == null); i++){
result = this.lookupNode((DefaultMutableTreeNode)node.getChildAt(i), element);
}
}
return result;
}
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
Component result = null;
JLabel temp;
Object nodeValue;
if(value instanceof DefaultMutableTreeNode){
nodeValue = ((DefaultMutableTreeNode)value).getUserObject();
if(nodeValue instanceof DataElement){
temp = new JLabel(ConfigUtil.getExtendedDataElementString((DataElement)nodeValue));
if(selected){
temp.setForeground(UIManager.getColor("Tree.selectionForeground"));
temp.setBackground(UIManager.getColor("Tree.selectionBackground"));
temp.setOpaque(true);
} else {
temp.setForeground(UIManager.getColor("Tree.textForeground"));
temp.setBackground(UIManager.getColor("Tree.textBackground"));
}
temp.setFont(temp.getFont().deriveFont(Font.BOLD));
Dimension dim = temp.getPreferredSize();
if(dim != null){
FontRenderContext frc = new FontRenderContext(temp.getFont().getTransform(), false, false);
double width = temp.getFont().getStringBounds(temp.getText(), frc).getWidth();
dim.width = (int)width + 3;
temp.setPreferredSize(dim);
temp.setMinimumSize(dim);
}
temp.setComponentOrientation(this.getComponentOrientation());
result = temp;
}
}
if(result == null){
result = initialRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
}
return result;
}
@Override
public DataNode getDataNodeAt(int x, int y) {
DataNode retVal = null;
TreePath path = this.getClosestPathForLocation(x, y);
if (path != null) {
this.setSelectionPath(path);
retVal = (DataElement)((DefaultMutableTreeNode)path.getLastPathComponent()).getUserObject();
}
return retVal;
}
@Override
public void showPopup(JPopupMenu popup, int x, int y) {
popup.show(this, x, y);
}
@Override
public void setStatus(String message, boolean persistent, boolean busy) {
if(this.status != null){
this.status.setStatus(message, persistent, busy);
}
}
}

View file

@ -1,50 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.swing;
import javax.swing.JMenuItem;
import org.eclipse.cyclonedds.config.data.DataNode;
import org.eclipse.cyclonedds.config.meta.MetaNode;
public class DataNodeMenuItem extends JMenuItem {
private static final long serialVersionUID = -5909316541978936911L;
private DataNode data;
private MetaNode childMeta;
private DataNodePopupSupport source;
public DataNodeMenuItem(String name, DataNode data, MetaNode childMeta){
super(name);
this.data = data;
this.childMeta = childMeta;
this.source = null;
}
public DataNodeMenuItem(String name, DataNode data, MetaNode childMeta, DataNodePopupSupport source){
super(name);
this.data = data;
this.childMeta = childMeta;
this.source = source;
}
public DataNode getData(){
return this.data;
}
public MetaNode getChildMeta(){
return this.childMeta;
}
public DataNodePopupSupport getSource(){
return this.source;
}
}

View file

@ -1,399 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.swing;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JMenu;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import org.eclipse.cyclonedds.common.util.Report;
import org.eclipse.cyclonedds.config.data.DataAttribute;
import org.eclipse.cyclonedds.config.data.DataElement;
import org.eclipse.cyclonedds.config.data.DataException;
import org.eclipse.cyclonedds.config.data.DataNode;
import org.eclipse.cyclonedds.config.data.DataValue;
import org.eclipse.cyclonedds.config.meta.MetaAttribute;
import org.eclipse.cyclonedds.config.meta.MetaElement;
import org.eclipse.cyclonedds.config.meta.MetaNode;
import org.eclipse.cyclonedds.config.meta.MetaValue;
public class DataNodePopup implements MouseListener, ActionListener {
private final Set<DataNodePopupSupport> popupSupport;
public DataNodePopup() {
this.popupSupport = Collections.synchronizedSet(new HashSet<DataNodePopupSupport>());
}
public void unregisterPopupSupport(DataNodePopupSupport support){
synchronized(this.popupSupport){
if(this.popupSupport.contains(support)){
support.removeMouseListener(this);
this.popupSupport.remove(support);
}
}
}
public void registerPopupSupport(DataNodePopupSupport support){
synchronized(this.popupSupport){
if(!this.popupSupport.contains(support)){
support.addMouseListener(this);
this.popupSupport.add(support);
}
}
}
private void notifyStatus(String message, boolean persistent, boolean busy){
synchronized(this.popupSupport){
for(DataNodePopupSupport dp: this.popupSupport){
dp.setStatus(message, persistent, busy);
}
}
}
private int countOccurrences(DataElement parent, MetaNode metaChild){
int occurrences = 0;
for(DataNode child: parent.getChildren()){
if(metaChild.equals(child.getMetadata())){
occurrences++;
}
}
return occurrences;
}
private JPopupMenu getPopup(DataNodePopupSupport source, DataNode dn){
DataNode parent;
DataElement parentParent;
DataNodeMenuItem reset, remove, add;
MetaNode metaParent, meta;
JMenu addMenu;
int min, max, current;
JPopupMenu result = new JPopupMenu("Actions");
if (dn != null) {
parent = dn.getParent();
meta = dn.getMetadata();
} else {
parent = null;
meta = null;
}
if(parent != null){
metaParent = parent.getMetadata();
} else {
metaParent = null;
}
addMenu = null;
reset = null;
remove = null;
if(dn instanceof DataValue){
assert metaParent!=null: "Parent element == null";
reset = new DataNodeMenuItem("Reset to default", dn, null);
remove = new DataNodeMenuItem("Remove", parent, null);
if(parent instanceof DataElement){
addMenu = new JMenu("Add");
for(MetaNode child: ((MetaElement)metaParent).getChildren()){
if(child instanceof MetaAttribute){
current = this.countOccurrences((DataElement)parent, child);
add = new DataNodeMenuItem(((MetaAttribute)child).getName(), parent, child);
if(current == 1){
add.setEnabled(false);
} else {
add.setEnabled(true);
}
add.setActionCommand("add");
add.addActionListener(this);
addMenu.add(add);
}
}
parentParent = (DataElement)parent.getParent();
if(parentParent != null){
current = this.countOccurrences((DataElement)parent.getParent(), parent.getMetadata());
min = ((MetaElement)metaParent).getMinOccurrences();
if(min == 0){
remove.setEnabled(true);
} else if(current > min){
remove.setEnabled(true);
} else {
remove.setEnabled(false);
}
}
} else if(parent instanceof DataAttribute){
metaParent = parent.getMetadata();
if(((MetaAttribute)metaParent).isRequired()){
remove.setEnabled(false);
}
result.add(remove);
} else {
assert false: "Unexpected parent type found: " + (parent==null ? parent: parent.getClass());
}
} else if(dn instanceof DataElement){
addMenu = new JMenu("Add");
remove = new DataNodeMenuItem("Remove", dn, null);
min = ((MetaElement)meta).getMinOccurrences();
current = this.countOccurrences((DataElement)dn.getParent(), meta);
if(min < current){
remove.setEnabled(true);
} else {
remove.setEnabled(false);
}
for(MetaNode child: ((MetaElement)meta).getChildren()){
current = this.countOccurrences((DataElement)dn, child);
if(child instanceof MetaElement){
add = new DataNodeMenuItem(((MetaElement)child).getName(), dn, child);
max = ((MetaElement)child).getMaxOccurrences();
if((max == 0) || (current < max)){
add.setEnabled(true);
} else {
add.setEnabled(false);
}
} else if(child instanceof MetaAttribute){
add = new DataNodeMenuItem(((MetaAttribute)child).getName(), dn, child);
if(current == 1){
add.setEnabled(false);
} else {
add.setEnabled(true);
}
} else {
add = new DataNodeMenuItem("<NoName>", dn, child);
if(current == 1){
add.setEnabled(false);
} else {
add.setEnabled(true);
}
}
add.setActionCommand("add");
add.addActionListener(this);
addMenu.add(add);
}
}
if(addMenu != null){
if (addMenu.getItemCount() == 0){
addMenu.setEnabled(false);
}
result.add(addMenu);
}
if(remove != null){
remove.setActionCommand("remove");
remove.addActionListener(this);
result.add(remove);
}
if(reset != null){
result.addSeparator();
reset.setActionCommand("reset");
reset.addActionListener(this);
result.add(reset);
} else {
//result.addSeparator();
}
return result;
}
@Override
public void actionPerformed(ActionEvent e) {
DataNodeMenuItem item;
DataNode dataNode;
MetaNode metaNode;
DataElement dataDomain = null;
Object source = e.getSource();
String command = e.getActionCommand();
try{
if(source instanceof DataNodeMenuItem){
item = (DataNodeMenuItem)source;
if("remove".equals(command)){
dataNode = item.getData();
boolean remove = false;
if (dataNode.getOwner().isServiceElement(dataNode)) {
int value = JOptionPane.showConfirmDialog(null,
"Are you sure you want to remove this " + ConfigWindow.SERVICE_TEXT + "?", "Remove " + ConfigWindow.SERVICE_TEXT + " confirmation",
JOptionPane.YES_NO_OPTION);
if (value == JOptionPane.NO_OPTION) {
remove = true;
}
}
if (!remove && dataNode.getDependencies() != null) {
for (DataNode dn : dataNode.getDependencies()) {
if(dn instanceof DataElement){
if (dn.getOwner().isServiceElement(dn)) {
int value = JOptionPane.showConfirmDialog(null,
"Are you sure you want to remove this " + ConfigWindow.SERVICE_TEXT + "?",
"Remove " + ConfigWindow.SERVICE_TEXT + " confirmation", JOptionPane.YES_NO_OPTION);
if (value == JOptionPane.NO_OPTION) {
remove = true;
}
}
if (!remove) {
dn.getOwner().removeNode(dn);
}
}
}
}
if (!remove) {
dataNode.getOwner().removeNode(dataNode);
}
} else if ("removeService".equals(command)) {
boolean remove = false;
int value = JOptionPane.showConfirmDialog(null,
"Are you sure you want to remove this " + ConfigWindow.SERVICE_TEXT + "?",
"Remove " + ConfigWindow.SERVICE_TEXT + " confirmation", JOptionPane.YES_NO_OPTION);
if (value == JOptionPane.NO_OPTION) {
remove = true;
}
if (!remove) {
dataNode = item.getData();
dataDomain = dataNode.getOwner().findServiceDataElement(dataNode.getOwner().getRootElement(),
"Service", (DataElement) dataNode);
if (dataDomain != null) {
dataDomain.getOwner().removeNode(dataDomain);
} else {
this.notifyStatus("Error: failed to remove the " + ConfigWindow.SERVICE_TEXT + " ", false, false);
}
dataNode.getOwner().removeNode(dataNode);
}
} else if ("add".equals(command)) {
dataNode = item.getData();
metaNode = item.getChildMeta();
if (dataNode.getOwner().isServiceElement(dataNode)
&& ((MetaElement) metaNode).getName().equals("Service")) {
HashMap<String, MetaNode> service = new HashMap<String, MetaNode>();
for (MetaNode mn : ((MetaElement) dataNode.getOwner().getRootElement().getMetadata())
.getChildren()) {
if (!((MetaElement) mn).getName().equals("Domain")) {
service.put(((MetaElement) mn).getName(), mn);
}
}
String[] serviceNames = service.keySet().toArray(new String[service.keySet().size()]);
String name = (String) JOptionPane.showInputDialog(null, "Please select a service to add.",
"Service selection", JOptionPane.QUESTION_MESSAGE, null, serviceNames, serviceNames[0]);
if (name != null) {
addService(dataNode.getOwner().getRootElement(), service.get(name));
}
} else {
if (dataNode instanceof DataElement) {
dataNode.getOwner().addNode((DataElement) dataNode, metaNode);
} else {
this.notifyStatus("Error: Unexpected type of parent found: '" + dataNode.getClass() + "'.",
false, false);
}
}
} else if ("addService".equals(command)) {
addService(item.getData(), item.getChildMeta());
} else if("reset".equals(command)){
dataNode = item.getData();
dataNode.getOwner().setValue((DataValue)dataNode, ((MetaValue)dataNode.getMetadata()).getDefaultValue());
} else {
this.notifyStatus("Warning: Action for command '" + command + "' not implemented.", false, false);
}
}
} catch(DataException de){
Report.getInstance().writeErrorLog("DataNodePopup actionPerformed" + de.getMessage());
this.notifyStatus("Error: " + de.getMessage(), false, false);
StackTraceElement[] elements = de.getStackTrace();
String error = "";
for(int i=0; i<elements.length; i++){
error += elements[i].getFileName() + ", " +
elements[i].getMethodName() + ", "
+ elements[i].getLineNumber() + "\n";
if(i==0){
error = elements[i].getFileName() + ", " +
elements[i].getMethodName() + ", " + elements[i].getLineNumber();
}
}
Report.getInstance().writeErrorLog("DataNodePopup actionPerformed\n DataException occurred:\n" + error);
} catch(Exception ex){
StackTraceElement[] elements = ex.getStackTrace();
StringBuffer buf = new StringBuffer();
for(int i=0; i<elements.length; i++){
buf.append(elements[i].getFileName() + ", " +
elements[i].getMethodName() + ", "
+ elements[i].getLineNumber() + "\n");
}
String error = buf.toString();
Report.getInstance().writeErrorLog(
"DataNodePopup actionPerformed\n Unhandled exception occurred:\n" + error);
this.notifyStatus("Error: " + error, false, false);
ex.printStackTrace();
}
}
@Override
public void mouseClicked(MouseEvent e) {
DataNode dn;
DataNodePopupSupport support;
Object source = e.getSource();
synchronized(popupSupport){
if(popupSupport.contains(source)){
if((e.getClickCount() == 1)) {
if(e.getButton() == MouseEvent.BUTTON3) {
support = (DataNodePopupSupport)source;
if (support != null) {
dn = support.getDataNodeAt(e.getX(), e.getY());
support.showPopup(this.getPopup(support, dn), e.getX(), e.getY());
}
}
}
}
}
}
public void addService(DataNode dataNode, MetaNode metaNode) throws DataException {
if (dataNode instanceof DataElement) {
/* get the newly created service element */
dataNode.getOwner().addNode((DataElement) dataNode, metaNode);
} else {
this.notifyStatus("Error: Unexpected type of parent found: '" + dataNode.getClass() + "'.", false, false);
}
}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
}

View file

@ -1,29 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.swing;
import java.awt.event.MouseListener;
import javax.swing.JPopupMenu;
import org.eclipse.cyclonedds.config.data.DataNode;
public interface DataNodePopupSupport {
public DataNode getDataNodeAt(int x, int y);
public void showPopup(JPopupMenu popup, int x, int y);
public void setStatus(String message, boolean persistent, boolean busy);
public void addMouseListener(MouseListener listener);
public void removeMouseListener(MouseListener listener);
}

View file

@ -1,156 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.swing;
import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
import javax.swing.JSplitPane;
import org.eclipse.cyclonedds.common.view.StatusPanel;
import org.eclipse.cyclonedds.config.meta.MetaConfiguration;
import javax.swing.JScrollPane;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
public class HelpWindow extends JFrame implements TreeSelectionListener {
private static final long serialVersionUID = 11222322324L;
private JPanel jContentPane = null;
private JSplitPane eastWestSplitPane = null;
private StatusPanel statusPanel = null;
private MetaConfiguration metaConfiguration = null;
private MetaElementTree elementTree = null;
private JScrollPane elementTreeScrollPane = null;
private JScrollPane docScrollPane = null;
private MetaNodeDocPane docPane = null;
public static final String HELP_WINDOW_TITLE = "Eclipse Cyclone DDS Configurator | Help";
/**
* This is the default constructor
*/
public HelpWindow(MetaConfiguration metaConfiguration) {
super();
this.metaConfiguration = metaConfiguration;
initialize();
}
/**
* This method initializes this
*
* @return void
*/
private void initialize() {
this.setSize(640, 480);
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
this.setContentPane(getJContentPane());
setWindowTitle();
getElementTree().getSelectionModel().addTreeSelectionListener(this);
getDocPane().setNode(getElementTree().getSelectedMetaElement());
}
public void setWindowTitle () {
String windowTitle = HELP_WINDOW_TITLE;
this.setTitle(windowTitle);
}
/**
* This method initializes jContentPane
*
* @return javax.swing.JPanel
*/
private JPanel getJContentPane() {
if (jContentPane == null) {
jContentPane = new JPanel();
jContentPane.setLayout(new BorderLayout());
jContentPane.add(getEastWestSplitPane(), BorderLayout.CENTER);
jContentPane.add(getStatusPanel(), BorderLayout.SOUTH);
}
return jContentPane;
}
/**
* This method initializes eastWestSplitPane
*
* @return javax.swing.JSplitPane
*/
private JSplitPane getEastWestSplitPane() {
if (eastWestSplitPane == null) {
eastWestSplitPane = new JSplitPane();
eastWestSplitPane.setDividerSize(5);
eastWestSplitPane.setDividerLocation(250);
eastWestSplitPane.setLeftComponent(getElementTreeScrollPane());
eastWestSplitPane.setRightComponent(getDocScrollPane());
}
return eastWestSplitPane;
}
private StatusPanel getStatusPanel(){
if(this.statusPanel == null){
this.statusPanel = new StatusPanel(800, "", false, false);
}
return this.statusPanel;
}
private MetaElementTree getElementTree(){
if(this.elementTree == null){
this.elementTree = new MetaElementTree(metaConfiguration.getRootElement(), getStatusPanel());
}
return this.elementTree;
}
/**
* This method initializes elementTreeScrollPane
*
* @return javax.swing.JScrollPane
*/
private JScrollPane getElementTreeScrollPane() {
if (elementTreeScrollPane == null) {
elementTreeScrollPane = new JScrollPane();
elementTreeScrollPane.setViewportView(getElementTree());
}
return elementTreeScrollPane;
}
/**
* This method initializes docScrollPane
*
* @return javax.swing.JScrollPane
*/
private JScrollPane getDocScrollPane() {
if (docScrollPane == null) {
docScrollPane = new JScrollPane();
docScrollPane.setViewportView(getDocPane());
}
return docScrollPane;
}
/**
* This method initializes codPane
*
* @return javax.swing.JEditorPane
*/
private MetaNodeDocPane getDocPane() {
if (docPane == null) {
docPane = new MetaNodeDocPane();
}
return docPane;
}
@Override
public void valueChanged(TreeSelectionEvent e) {
getDocPane().setNode(getElementTree().getSelectedMetaElement());
}
}

View file

@ -1,139 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.swing;
import java.awt.Component;
import java.awt.Font;
import javax.swing.JLabel;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import org.eclipse.cyclonedds.common.view.StatusPanel;
import org.eclipse.cyclonedds.config.meta.MetaElement;
import org.eclipse.cyclonedds.config.meta.MetaNode;
@SuppressWarnings("serial")
public class MetaElementTree extends JTree implements TreeCellRenderer, TreeSelectionListener{
private final DefaultMutableTreeNode rootNode;
private final MetaElement rootElement;
private final DefaultTreeModel model;
private final DefaultTreeCellRenderer initialRenderer;
private final StatusPanel status;
public MetaElementTree(MetaElement rootElement, StatusPanel status){
super();
this.initialRenderer = new DefaultTreeCellRenderer();
this.rootElement = rootElement;
this.status = status;
this.rootNode = new DefaultMutableTreeNode(this.rootElement);
this.model = ((DefaultTreeModel)this.treeModel);
this.model.setRoot(this.rootNode);
this.setCellRenderer(this);
this.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
this.setEditable(false);
this.setRootVisible(true);
this.setShowsRootHandles(true);
this.initElement(this.rootNode, this.rootElement);
if(this.rootNode.getChildCount() > 0){
this.scrollPathToVisible(
new TreePath(
((DefaultMutableTreeNode)this.rootNode.getFirstChild()).getPath()));
}
this.getSelectionModel().addTreeSelectionListener(this);
this.setSelectionPath(new TreePath(this.rootNode.getPath()));
}
private void initElement(DefaultMutableTreeNode parent, MetaElement element){
DefaultMutableTreeNode node;
for(MetaNode child: element.getChildren()){
if(child instanceof MetaElement){
node = new DefaultMutableTreeNode(child);
this.model.insertNodeInto(node, parent, parent.getChildCount());
this.initElement(node, (MetaElement)child);
}
}
}
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
Component result = null;
JLabel temp;
Object nodeValue;
if(value instanceof DefaultMutableTreeNode){
nodeValue = ((DefaultMutableTreeNode)value).getUserObject();
if(nodeValue instanceof MetaElement){
temp = new JLabel(ConfigUtil.getMetaElementString((MetaElement)nodeValue));
if(selected){
temp.setForeground(UIManager.getColor("Tree.selectionForeground"));
temp.setBackground(UIManager.getColor("Tree.selectionBackground"));
temp.setOpaque(true);
} else {
temp.setForeground(UIManager.getColor("Tree.textForeground"));
temp.setBackground(UIManager.getColor("Tree.textBackground"));
}
//temp.setFont(temp.getFont().deriveFont(Font.PLAIN));
temp.setFont(temp.getFont().deriveFont(Font.BOLD));
result = temp;
}
}
if(result == null){
result = initialRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
}
return result;
}
public MetaElement getSelectedMetaElement(){
MetaElement result = null;
TreePath path = this.getSelectionPath();
if(path != null){
result = (MetaElement)
((DefaultMutableTreeNode)path.getLastPathComponent()).getUserObject();
}
return result;
}
public MetaElement getMetaNodeAt(int x, int y) {
MetaElement retVal = null;
TreePath path = this.getClosestPathForLocation(x, y);
if (path != null) {
this.setSelectionPath(path);
retVal = (MetaElement)((DefaultMutableTreeNode)path.getLastPathComponent()).getUserObject();
}
return retVal;
}
@Override
public void valueChanged(TreeSelectionEvent e) {
MetaElement me = this.getSelectedMetaElement();
if((me != null) && (status != null)){
status.setStatus("Element '" + me.getName() + "' selected.", true);
}
}
}

View file

@ -1,206 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.swing;
import java.io.StringWriter;
import javax.swing.JEditorPane;
import org.eclipse.cyclonedds.config.meta.MetaAttribute;
import org.eclipse.cyclonedds.config.meta.MetaElement;
import org.eclipse.cyclonedds.config.meta.MetaNode;
@SuppressWarnings("serial")
public class MetaNodeDocPane extends JEditorPane {
private boolean showElementName;
private boolean showChildrenAttributes;
private static final String fontStyle = "font-family:Sans-serif";
public MetaNodeDocPane(){
super("text/html", "No selection");
this.init(true, true);
}
public MetaNodeDocPane(boolean showElementName, boolean showChildrenAttributes){
super("text/html", "No selection");
this.init(showElementName, showChildrenAttributes);
}
private void init(boolean showElementName, boolean showChildrenAttributes){
this.setEditable(false);
this.showElementName = showElementName;
this.showChildrenAttributes = showChildrenAttributes;
}
public void setNode(MetaNode node){
String doc;
MetaNode[] children;
MetaAttribute attribute;
int attributeChildrenCount = 0;
StringWriter writer = new StringWriter();
if(node == null){
writer.write("No element selected.");
} else {
doc = this.layoutDoc(node.getDoc());
if(node instanceof MetaElement){
if(this.showElementName){
int maxOcc = ((MetaElement)node).getMaxOccurrences();
int minOcc = ((MetaElement)node).getMinOccurrences();
String occ;
if(maxOcc == Integer.MAX_VALUE){
occ = "occurrences: " + minOcc + " - " + "*";
} else {
occ = "occurrences: " + minOcc + " - " + maxOcc;
}
writer.write("<h1>" + ((MetaElement)node).getName());
String dimension = node.getDimension();
if (dimension != null) {
writer.write(" <font size=\"-1\">(" + occ
+ " and dimension: " + dimension
+ ")</font></h1>");
} else {
writer.write(" <font size=\"-1\">(" + occ
+ ")</font></h1>");
}
}
writer.write("<font style=\"" + MetaNodeDocPane.fontStyle + "\">" + doc + "</font>");
children = ((MetaElement)node).getChildren();
for(MetaNode mn: children){
if(mn instanceof MetaAttribute){
attributeChildrenCount++;
}
}
if(this.showChildrenAttributes){
if(attributeChildrenCount > 0){
writer.write("<h2>Attributes</h2>");
for(MetaNode mn: children){
if(mn instanceof MetaAttribute){
this.writeNode(writer, mn);
}
}
} else {
writer.write("<h2>Attributes</h2>Element has no attributes");
}
}
} else if(node instanceof MetaAttribute){
attribute = (MetaAttribute)node;
if(this.showElementName){
writer.write("<h1>" + attribute.getName() + "(");
if(attribute.isRequired()){
writer.write("required");
} else {
writer.write("optional");
}
String dimension = attribute.getDimension();
if (dimension != null) {
writer.write(" and dimension: ");
writer.write(dimension);
}
writer.write(")</h1> -");
}
writer.write("<font style=\"" + MetaNodeDocPane.fontStyle + "\">" + doc + "</font>");
} else {
writer.write("<font style=\"" + MetaNodeDocPane.fontStyle + "\">" + doc + "</font>");
}
}
this.setText(writer.toString());
this.setCaretPosition(0);
}
private void writeNode(StringWriter writer, MetaNode node){
MetaElement element;
MetaAttribute attribute;
String doc;
String dimension = node.getDimension();
if(node instanceof MetaElement){
element = (MetaElement)node;
writer.write("<h3>" + element.getName());
writer.write(" (occurrences : " + element.getMinOccurrences()
+ " - " + element.getMaxOccurrences());
if (dimension != null) {
writer.write(" dimension: " + dimension);
}
writer.write(")</h3>");
} else if(node instanceof MetaAttribute){
attribute = (MetaAttribute)node;
writer.write("<h3>" + attribute.getName() + " (");
if(attribute.isRequired()){
writer.write("required");
} else {
writer.write("optional");
}
if (dimension != null) {
writer.write(" and dimension: " + dimension);
}
writer.write(")</h3>");
}
doc = this.layoutDoc(node.getDoc());
writer.write("<font style=\"" + MetaNodeDocPane.fontStyle + "\">" + doc + "</font>");
}
private String layoutDoc(String doc){
String temp;
char c;
StringWriter writer = new StringWriter();
if(doc == null){
temp = "No description available.";
} else {
temp = doc;
}
temp = temp.trim();
if(temp.length() == 0){
temp = "No description available.";
} else {
if(temp.startsWith("<p>")){
temp = temp.substring(3);
temp = temp.replaceFirst("</p>", " ");
}
for(int i=0; i<temp.length(); i++){
c = temp.charAt(i);
if((c != '\n') && (c != '\t')){
if(c == ' '){
if((i+1)<temp.length()){
if(temp.charAt(i+1) != ' '){
writer.write(c);
}
} else {
writer.write(c);
}
} else {
writer.write(c);
}
}
}
}
return writer.toString();
}
}

View file

@ -1,273 +0,0 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.cyclonedds.config.swing;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.TransferHandler;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import org.eclipse.cyclonedds.common.view.StatusPanel;
import org.eclipse.cyclonedds.config.data.DataAttribute;
import org.eclipse.cyclonedds.config.data.DataElement;
import org.eclipse.cyclonedds.config.data.DataNode;
import org.eclipse.cyclonedds.config.data.DataValue;
import org.eclipse.cyclonedds.config.meta.MetaAttribute;
import org.eclipse.cyclonedds.config.meta.MetaElement;
import org.eclipse.cyclonedds.config.meta.MetaNode;
public class ServicePanel extends JPanel implements TreeSelectionListener, ListSelectionListener {
private static final long serialVersionUID = 1L;
private JSplitPane northSouthSplitPane = null;
private MetaNodeDocPane docPane = null;
private JScrollPane docScrollPane = null;
private JSplitPane eastWestSplitPane = null;
private JScrollPane elementTreeScrollPane = null;
private DataElementTree configurationElementTree = null;
private JScrollPane tableScrollPane = null;
private DataElementTable configurationTable = null;
private DataElement serviceElement = null;
private DataNodePopup popupController = null;
private StatusPanel status = null;
/**
* This is the default constructor
*/
public ServicePanel(DataElement serviceElement, StatusPanel status) {
super();
this.serviceElement = serviceElement;
this.popupController = new DataNodePopup();
this.status = status;
initialize();
}
public DataElement getService(){
return this.serviceElement;
}
public DataElementTable getConfigurationTable() {
if (configurationTable == null) {
configurationTable = new DataElementTable(this.popupController, serviceElement, this.status);
configurationTable.getSelectionModel().addListSelectionListener(this);
}
return configurationTable;
}
@Override
public void valueChanged(TreeSelectionEvent e) {
TreePath selectionPath = e.getNewLeadSelectionPath();
if(selectionPath != null){
this.getConfigurationTable().getSelectionModel().clearSelection();
DataElement selection = (DataElement)(
((DefaultMutableTreeNode)(
selectionPath.getLastPathComponent())).getUserObject());
this.configurationTable.getEditor().stopCellEditing();
((DataElementTableModel)this.configurationTable.getModel()).setElement(selection);
this.updateDocument(selection);
}
}
@Override
public void valueChanged(ListSelectionEvent e) {
if(!e.getValueIsAdjusting()){
int selectedRow = this.getConfigurationTable().getSelectedRow();
if(selectedRow != -1){
this.getConfigurationElementTree().getSelectionModel().clearSelection();
DataNode selection = this.getConfigurationTable().getDataNodeAt(selectedRow);
this.updateDocument(selection);
}
}
}
@Override
public void setTransferHandler(TransferHandler t){
super.setTransferHandler(t);
int count = this.getComponentCount();
for(int i=0; i<count; i++){
if(this.getComponent(i) instanceof JComponent){
((JComponent)this.getComponent(i)).setTransferHandler(t);
}
}
this.getConfigurationElementTree().setTransferHandler(t);
this.getConfigurationTable().setTransferHandler(t);
this.getDocPane().setTransferHandler(t);
}
/**
* This method initializes this
*
* @return void
*/
private void initialize() {
GridBagConstraints gridBagConstraints = new GridBagConstraints();
gridBagConstraints.fill = GridBagConstraints.BOTH;
gridBagConstraints.gridy = 0;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
gridBagConstraints.gridx = 0;
this.setSize(800, 540);
this.setLayout(new GridBagLayout());
this.add(getNorthSouthSplitPane(), gridBagConstraints);
}
private JSplitPane getNorthSouthSplitPane() {
if (northSouthSplitPane == null) {
northSouthSplitPane = new JSplitPane();
northSouthSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
northSouthSplitPane.setDividerLocation(300);
northSouthSplitPane.setBackground(Color.white);
northSouthSplitPane.setLeftComponent(getEastWestSplitPane());
northSouthSplitPane.setRightComponent(getDocScrollPane());
northSouthSplitPane.setDividerSize(5);
}
return northSouthSplitPane;
}
/**
* This method initializes mainSplitPane
*
* @return javax.swing.JSplitPane
*/
private JSplitPane getEastWestSplitPane() {
if (eastWestSplitPane == null) {
eastWestSplitPane = new JSplitPane();
eastWestSplitPane.setDividerLocation(330);
eastWestSplitPane.setBackground(Color.white);
eastWestSplitPane.setLeftComponent(getElementTreeScrollPane());
eastWestSplitPane.setRightComponent(getTableScrollPane());
eastWestSplitPane.setDividerSize(5);
}
return eastWestSplitPane;
}
/**
* This method initializes elementTreeScrollPane
*
* @return javax.swing.JScrollPane
*/
private JScrollPane getElementTreeScrollPane() {
if (elementTreeScrollPane == null) {
elementTreeScrollPane = new JScrollPane();
elementTreeScrollPane.setBorder(
BorderFactory.createTitledBorder(null, "Elements",
TitledBorder.LEFT, TitledBorder.BOTTOM,
new Font("Dialog", Font.BOLD, 12),
new Color(51, 51, 51)));
elementTreeScrollPane.setViewportView(getConfigurationElementTree());
elementTreeScrollPane.setBackground(Color.WHITE);
}
return elementTreeScrollPane;
}
/**
* This method initializes configurationElementTree
*
* @return javax.swing.JTree
*/
private DataElementTree getConfigurationElementTree() {
if (configurationElementTree == null) {
configurationElementTree = new DataElementTree(serviceElement, null, this.status);
configurationElementTree.addTreeSelectionListener(this);
this.updateDocument(serviceElement);
}
return configurationElementTree;
}
/**
* This method initializes tableScrollPane
*
* @return javax.swing.JScrollPane
*/
private JScrollPane getTableScrollPane() {
if (tableScrollPane == null) {
tableScrollPane = new JScrollPane();
tableScrollPane.setViewportView(getConfigurationTable());
tableScrollPane.setBorder(BorderFactory.createTitledBorder(null, "Attributes", TitledBorder.RIGHT, TitledBorder.BOTTOM, new Font("Dialog", Font.BOLD, 12), new Color(51, 51, 51)));
//tableScrollPane.setBackground(Color.WHITE);
}
return tableScrollPane;
}
private JScrollPane getDocScrollPane() {
if (docScrollPane == null) {
docScrollPane = new JScrollPane();
docScrollPane.setViewportView(getDocPane());
docScrollPane.setBorder(BorderFactory.createTitledBorder(null, "Documentation", TitledBorder.LEFT, TitledBorder.BOTTOM, new Font("Dialog", Font.BOLD, 12), new Color(51, 51, 51)));
docScrollPane.setBackground(Color.WHITE);
}
return docScrollPane;
}
private MetaNodeDocPane getDocPane(){
if (docPane == null) {
docPane = new MetaNodeDocPane(false, false);
}
return docPane;
}
private void updateDocument(DataNode node){
MetaNode meta = null;
DataNode parent;
if(node instanceof DataValue){
parent = node.getParent();
if(parent != null){
meta = parent.getMetadata();
}
} else {
meta = node.getMetadata();
}
this.getDocScrollPane().setBorder(BorderFactory.createTitledBorder(null,
"Documentation for '" + this.getXPath(node) + "'",
TitledBorder.LEFT, TitledBorder.BOTTOM,
new Font("Dialog", Font.BOLD, 12), new Color(51, 51, 51)));
this.getDocPane().setNode(meta);
}
private String getXPath(DataNode node){
String result;
DataNode curNode = node;
result = "";
while(curNode != null){
if(curNode instanceof DataElement){
result = "/" + ((MetaElement)curNode.getMetadata()).getName() + result;
} else if(curNode instanceof DataAttribute){
result = "[@" + ((MetaAttribute)curNode.getMetadata()).getName() + "]" + result;
}
curNode = curNode.getParent();
}
result = "/" + result;
return result;
}
}