Merge pull request #279 from martinbremmer/merge4
Merge master into security
This commit is contained in:
commit
5399e5103c
93 changed files with 7999 additions and 13305 deletions
34
.travis.yml
34
.travis.yml
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
16
README.md
16
README.md
|
@ -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
|
||||
|
||||
|
|
676
docs/makernc.pl
Normal file
676
docs/makernc.pl
Normal 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/"/"/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: "$defaultvalue".</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
1716
docs/manual/options.md
Normal file
File diff suppressed because it is too large
Load diff
1397
etc/cyclonedds.rnc
Normal file
1397
etc/cyclonedds.rnc
Normal file
File diff suppressed because it is too large
Load diff
1886
etc/cyclonedds.xsd
Normal file
1886
etc/cyclonedds.xsd
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 &
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
},
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -26,6 +26,7 @@ list(APPEND sources
|
|||
"string.c"
|
||||
"log.c"
|
||||
"random.c"
|
||||
"retcode.c"
|
||||
"strlcpy.c"
|
||||
"socket.c"
|
||||
"select.c")
|
||||
|
|
|
@ -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(©, &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(©, &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
59
src/ddsrt/tests/retcode.c
Normal 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);
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
|
@ -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
|
@ -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>
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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.";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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) {}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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) {}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue