| #******************************************************************************* |
| #* Copyright (c) 2011 Forschungszentrum Juelich GmbH. |
| #* All rights reserved. This program and the accompanying materials |
| #* are made available under the terms of the Eclipse Public License v1.0 |
| #* which accompanies this distribution, and is available at |
| #* http://www.eclipse.org/legal/epl-v10.html |
| #* |
| #* Contributors: |
| #* Wolfgang Frings (Forschungszentrum Juelich GmbH) |
| #*******************************************************************************/ |
| package LML_file_obj; |
| |
| my $VERSION='$Revision: 1.00 $'; |
| my($debug)=0; |
| |
| use strict; |
| use Data::Dumper; |
| use Time::Local; |
| use Time::HiRes qw ( time ); |
| |
| use LML_ndtree; |
| |
| sub new { |
| my $self = {}; |
| my $proto = shift; |
| my $class = ref($proto) || $proto; |
| my $verbose = shift; |
| my $timings = shift; |
| printf("\t LML_file_obj: new %s\n",ref($proto)) if($debug>=3); |
| $self->{DATA} = {}; |
| $self->{VERBOSE} = $verbose; |
| $self->{TIMINGS} = $timings; |
| $self->{LASTINFOID} = undef; |
| bless $self, $class; |
| return $self; |
| } |
| |
| # internal data structures: |
| # $self->{DATA}-> # structure corresponds to LML scheme |
| # {OBJECT}->{$id}->{id} |
| # ->{name} |
| # ->{type} |
| # {INFO} ->{$oid}->{oid} |
| # ->{type} |
| # {INFODATA}->{$oid}->{$key} |
| # |
| # {TABLELAYOUT}->{$id}->{id} |
| # ->{gid} |
| # ->{column}->{$cid}->{cid} |
| # ->{key} |
| # ->{pos} |
| # ->{width} |
| # ->{active} |
| # {TABLE}->{$id}->{id} |
| # ->{title} |
| # ->{column}->{$cid}->{id} |
| # ->{name} |
| # ->{sort} |
| # ->{row}->{$id}->{cell}->[value,value,...] |
| # |
| # {NODEDISPLAYLAYOUT}->{$id}->{id} |
| # ->{gid} |
| # ->{elements}->[elref, elref, ...] |
| # ... elref->{elname} |
| # ->{key} |
| # ->{elements}->[elref, elref, ...] |
| # |
| # |
| # derived: |
| # {INFOATTR}->{obj_type}->{$key} # of occurrences |
| # |
| sub get_data_ref { |
| my($self) = shift; |
| return($self->{DATA}); |
| } |
| |
| |
| sub init_file_obj { |
| my($self) = shift; |
| $self->{DATA}->{LMLLGUI}={ |
| 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', |
| 'xmlns:lml' => 'http://www.llview.de', |
| 'version' => '1.0', |
| 'xsi:schemaLocation' => 'http://www.llview.de lgui.xsd ' |
| }; |
| return(1); |
| } |
| |
| sub get_stat { |
| my($self) = shift; |
| my($log,$type,%types,$id); |
| $log=""; |
| |
| { |
| my($type,%types,$id); |
| $log.=sprintf("objects: total #%d\n",scalar keys(%{$self->{DATA}->{OBJECT}})); |
| foreach $id (keys %{$self->{DATA}->{OBJECT}}) { |
| $type=$self->{DATA}->{OBJECT}->{$id}->{type}; |
| $types{$type}++; |
| } |
| foreach $type (sort keys %types) { |
| $log.=sprintf(" |-- %10d (%s)\n",$types{$type},$type); |
| } |
| } |
| |
| { |
| my($type,%types,$id); |
| if($self->{DATA}->{TABLELAYOUT}) { |
| $log.=sprintf("tablelayout: total #%d\n",scalar keys(%{$self->{DATA}->{TABLELAYOUT}})); |
| foreach $id (keys %{$self->{DATA}->{TABLELAYOUT}}) { |
| $log.=sprintf(" |-- 1x%d (%s)\n", |
| scalar keys(%{$self->{DATA}->{TABLELAYOUT}->{$id}->{column}}), |
| $id); |
| } |
| } |
| } |
| |
| { |
| my($type,%types,$id); |
| if($self->{DATA}->{TABLE}) { |
| $log.=sprintf("table: total #%d\n",scalar keys(%{$self->{DATA}->{TABLE}})); |
| foreach $id (keys %{$self->{DATA}->{TABLE}}) { |
| $log.=sprintf(" |-- %4dx%d (%s)\n", |
| scalar keys(%{$self->{DATA}->{TABLE}->{$id}->{row}}), |
| scalar keys(%{$self->{DATA}->{TABLE}->{$id}->{column}}), |
| $id); |
| } |
| } |
| } |
| return($log); |
| } |
| |
| sub read_lml_fast { |
| my($self) = shift; |
| my $infile = shift; |
| my $type = shift; |
| my($xmlin); |
| my $rc=0; |
| |
| my $tstart=time; |
| if(!open(IN,$infile)) { |
| print "could not open $infile, leaving ...\n";return(0); |
| } |
| while(<IN>) { |
| $xmlin.=$_; |
| } |
| close(IN); |
| my $tdiff=time-$tstart; |
| printf("LML_file_obj: read XML in %6.4f sec\n",$tdiff) if($self->{VERBOSE}); |
| |
| $self->{DATA}->{SEARCHTYPE}=$type; |
| $tstart=time; |
| |
| # light-weight self written xml parser, only working for simple XML files |
| $xmlin=~s/\n/ /gs; |
| $xmlin=~s/\s\s+/ /gs; |
| my ($tag,$tagname,$rest,$ctag,$nrc); |
| foreach $tag (split(/\>\s*/,$xmlin)) { |
| $ctag.=$tag; |
| $nrc=($ctag=~ tr/\"/\"/); |
| if($nrc%2==0) { |
| $tag=$ctag; |
| $ctag=""; |
| } else { |
| next; |
| } |
| |
| # print "TAG: '$tag'\n"; |
| if($tag=~/^<[\/\?](.*)[^\s\>]/) { |
| $tagname=$1; |
| $self->lml_end($self->{DATA},$tagname,()); |
| } elsif($tag=~/<([^\s]+)\s*$/) { |
| $tagname=$1; |
| # print "TAG0: '$tagname'\n"; |
| $self->lml_start($self->{DATA},$tagname,()); |
| } elsif($tag=~/<([^\s]+)(\s(.*)[^\/])$/) { |
| $tagname=$1; |
| $rest=$2;$rest=~s/^\s*//gs;$rest=~s/\s*$//gs; |
| # print "TAG1: '$tagname' rest='$rest'\n"; |
| $self->lml_start($self->{DATA},$tagname,split(/=?\"\s*/,$rest)); |
| } elsif($tag=~/<([^\s]+)(\s(.*)\s?)\/$/) { |
| $tagname=$1; |
| $rest=$2;$rest=~s/^\s*//gs;$rest=~s/\s*$//gs; |
| # print "TAG2: '$tagname' rest='$rest' closed\n"; |
| $self->lml_start($self->{DATA},$tagname,split(/=?\"\s*/,$rest)); |
| $self->lml_end($self->{DATA},$tagname,()); |
| } |
| } |
| |
| $tdiff=time-$tstart; |
| printf("LML_file_obj: parse XML in %6.4f sec\n",$tdiff) if($self->{VERBOSE}); |
| |
| # print Dumper($self->{DATA}); |
| return($rc); |
| |
| } |
| |
| |
| # from lib/LLview_parse_xml.pm |
| sub lml_start { |
| my $self=shift; # object reference |
| my $o =shift; |
| my $name=shift; |
| # print "WF: >",ref($o),"< >$name<\n"; |
| my($k,$v,$actnodename,$id,$cid,$oid); |
| |
| if($name eq "!--") { |
| # a comment |
| return(1); |
| } |
| my %attr=(@_); |
| |
| if($name eq "lml:lgui") { |
| foreach $k (sort keys %attr) { |
| # print "$k: $attr{$k}\n"; |
| $o->{LMLLGUI}->{$k}=$attr{$k}; |
| } |
| return(1); |
| } |
| # Objects |
| if($name eq "objects") { |
| return(1); |
| } |
| if($name eq "object") { |
| $id=$attr{id}; |
| if(exists($o->{OBJECT}->{$id})) { |
| print "LML_file_obj: WARNING objects with id >$id< exists, skipping\n"; |
| return(0); |
| } |
| foreach $k (sort keys %attr) { |
| # print "$k: $attr{$k}\n"; |
| $o->{OBJECT}->{$id}->{$k}=$attr{$k}; |
| } |
| return(1); |
| } |
| # Information |
| if($name eq "information") { |
| return(1); |
| } |
| if($name eq "info") { |
| $oid=$attr{oid}; |
| $o->{LASTINFOID}=$oid; |
| $o->{LASTINFOTYPE}=$o->{OBJECT}->{$oid}->{type}; |
| if(exists($o->{INFO}->{$oid})) { |
| print "LML_file_obj: WARNING info with id >$id< exists, skipping\n"; |
| return(0); |
| } |
| foreach $k (sort keys %attr) { |
| # print "$k: $attr{$k}\n"; |
| $o->{INFO}->{$oid}->{$k}=$attr{$k}; |
| } |
| return(1); |
| } |
| if($name eq "data") { |
| $id=$o->{LASTINFOID}; |
| $k=$attr{key}; |
| $v=$attr{value}; |
| # $o->{INFOATTR}->{$o->{LASTINFOTYPE}}->{$k}++; |
| if(exists($o->{INFODATA}->{$id}->{$k})) { |
| print "LML_file_obj: WARNING infodata with id >$id< and key >$k< exists, skipping\n"; |
| return(0); |
| } |
| $o->{INFODATA}->{$id}->{$k}=$v; |
| return(1); |
| } |
| # Tablelayout |
| if($name eq "tablelayout") { |
| $id=$attr{id}; |
| $o->{LASTTABLELAYOUTID}=$id; |
| if(exists($o->{TABLELAYOUT}->{$id})) { |
| print "LML_file_obj: WARNING Tablelayout with id >$id< exists, skipping\n"; |
| return(0); |
| } |
| foreach $k (sort keys %attr) { |
| # print "$k: $attr{$k}\n"; |
| $o->{TABLELAYOUT}->{$id}->{$k}=$attr{$k}; |
| } |
| return(1); |
| } |
| |
| if($name eq "column") { |
| $id=$o->{LASTTABLELAYOUTID}; |
| $cid=$attr{cid}; |
| $v=$attr{value}; |
| |
| if(exists($o->{TABLELAYOUT}->{$id}->{column}->{$cid})) { |
| print "LML_file_obj: WARNING column in tablelayout with id >$cid< exists, skipping\n"; |
| return(0); |
| } |
| foreach $k (sort keys %attr) { |
| # print "$k: $attr{$k}\n"; |
| $o->{TABLELAYOUT}->{$id}->{column}->{$cid}->{$k}=$attr{$k}; |
| } |
| return(1); |
| } |
| |
| # nodedisplaylayout |
| if($name eq "nodedisplaylayout") { |
| $id=$attr{id}; |
| if(exists($o->{NODEDISPLAYLAYOUT}->{$id})) { |
| print "LML_file_obj: WARNING Nodedisplaylayout with id >$id< exists, skipping\n"; |
| return(0); |
| } |
| foreach $k (sort keys %attr) { |
| $o->{NODEDISPLAYLAYOUT}->{$id}->{$k}=$attr{$k}; |
| } |
| $o->{NODEDISPLAYLAYOUT}->{$id}->{tree}=LML_ndtree->new("ndlytree"); |
| $o->{NODEDISPLAYLAYOUT}->{$id}->{tree}->{_level}=-1; |
| push(@{$o->{NODEDISPLAYLAYOUTSTACK}},$o->{NODEDISPLAYLAYOUT}->{$id}->{tree}); |
| return(1); |
| } |
| if(($name=~/el\d/) || ($name eq 'img')) { |
| my $lastelem=$o->{NODEDISPLAYLAYOUTSTACK}->[-1]; |
| my $treenode=$lastelem->new_child(\%attr,$name); |
| push(@{$o->{NODEDISPLAYLAYOUTSTACK}},$treenode); |
| return(1); |
| } |
| |
| print "LML_file_obj: WARNING unknown tag >$name< \n"; |
| |
| } |
| |
| sub lml_end { |
| my $self=shift; # object reference |
| my $o =shift; |
| my $name=shift; |
| if(($name=~/el\d/) || ($name eq 'img')) { |
| pop(@{$o->{NODEDISPLAYLAYOUTSTACK}}); |
| } |
| } |
| |
| |
| sub write_lml { |
| my($self) = shift; |
| my $outfile = shift; |
| my($k,$rc,$id,$c,$key); |
| my $tstart=time; |
| $rc=1; |
| |
| open(OUT,"> $outfile") || die "cannot open file $outfile"; |
| printf(OUT "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); |
| |
| printf(OUT "<lml:lgui "); |
| foreach $k (sort keys %{$self->{DATA}->{LMLLGUI}}) { |
| printf(OUT "%s=\"%s\"\n ",$k,$self->{DATA}->{LMLLGUI}->{$k}); |
| } |
| printf(OUT " \>\n"); |
| |
| |
| printf(OUT "<objects>\n"); |
| foreach $id (sort keys %{$self->{DATA}->{OBJECT}}) { |
| printf(OUT "<object"); |
| foreach $k (sort keys %{$self->{DATA}->{OBJECT}->{$id}}) { |
| printf(OUT " %s=\"%s\"",$k,$self->{DATA}->{OBJECT}->{$id}->{$k}); |
| } |
| printf(OUT "/>\n"); |
| } |
| printf(OUT "</objects>\n"); |
| |
| printf(OUT "<information>\n"); |
| foreach $id (sort keys %{$self->{DATA}->{INFO}}) { |
| printf(OUT "<info"); |
| foreach $k (sort keys %{$self->{DATA}->{INFO}->{$id}}) { |
| printf(OUT " %s=\"%s\"",$k,$self->{DATA}->{INFO}->{$id}->{$k}); |
| } |
| printf(OUT ">\n"); |
| foreach $k (sort keys %{$self->{DATA}->{INFODATA}->{$id}}) { |
| printf(OUT "<data key=\"%s\" value=\"%s\"/>\n",$k,$self->{DATA}->{INFODATA}->{$id}->{$k}); |
| } |
| printf(OUT "</info>\n"); |
| } |
| printf(OUT "</information>\n"); |
| |
| if(exists($self->{DATA}->{TABLE})) { |
| |
| foreach $id (sort keys %{$self->{DATA}->{TABLE}}) { |
| my $table=$self->{DATA}->{TABLE}->{$id}; |
| printf(OUT "<table title=\"%s\" id=\"%s\">\n", $table->{title}, $table->{id}); |
| foreach $k (sort keys %{$table->{column}}) { |
| printf(OUT "<column"); |
| for $key ("id","name","sort") { |
| printf(OUT " %s=\"%s\"",$key, $table->{column}->{$k}->{$key}); |
| } |
| printf(OUT "/>\n"); |
| } |
| foreach $k (sort keys %{$table->{row}}) { |
| printf(OUT "<row %s=\"%s\">\n","oid",$k); |
| foreach $c (@{$table->{row}->{$k}->{cell}}) { |
| printf(OUT "<cell %s=\"%s\"/>\n","value",$c); |
| } |
| printf(OUT "</row>\n"); |
| } |
| printf(OUT "</table>\n"); |
| } |
| } |
| |
| if(exists($self->{DATA}->{TABLELAYOUT})) { |
| |
| foreach $id (sort keys %{$self->{DATA}->{TABLELAYOUT}}) { |
| my $tablelayout=$self->{DATA}->{TABLELAYOUT}->{$id}; |
| printf(OUT "<tablelayout id=\"%s\" gid=\"%s\">\n", $tablelayout->{id}, $tablelayout->{gid}); |
| foreach $k (sort {$a <=> $b} keys %{$tablelayout->{column}}) { |
| printf(OUT "<column"); |
| for $key ("cid","pos","width","active","key") { |
| printf(OUT " %s=\"%s\"",$key, $tablelayout->{column}->{$k}->{$key}); |
| } |
| printf(OUT "/>\n"); |
| } |
| printf(OUT "</tablelayout>\n"); |
| } |
| } |
| |
| |
| if(exists($self->{DATA}->{NODEDISPLAYLAYOUT})) { |
| |
| foreach $id (sort keys %{$self->{DATA}->{NODEDISPLAYLAYOUT}}) { |
| my $ndlayout=$self->{DATA}->{NODEDISPLAYLAYOUT}->{$id}; |
| printf(OUT "<nodedisplaylayout id=\"%s\" gid=\"%s\">\n", $ndlayout->{id}, $ndlayout->{gid}); |
| print OUT $ndlayout->{tree}->get_xml_tree(0); |
| printf(OUT "</nodedisplaylayout>\n"); |
| } |
| } |
| |
| if(exists($self->{DATA}->{NODEDISPLAY})) { |
| |
| foreach $id (sort keys %{$self->{DATA}->{NODEDISPLAY}}) { |
| my $nd=$self->{DATA}->{NODEDISPLAY}->{$id}; |
| printf(OUT "<nodedisplay id=\"%s\" title=\"%s\">\n", $nd->{id}, $nd->{title}); |
| print OUT "<scheme>\n"; |
| print OUT $nd->{schemeroot}->get_xml_tree(1); |
| print OUT "</scheme>\n"; |
| print OUT "<data>\n"; |
| print OUT $nd->{dataroot}->get_xml_tree(1); |
| print OUT "</data>\n"; |
| printf(OUT "</nodedisplay>\n"); |
| } |
| } |
| |
| printf(OUT "</lml:lgui>\n"); |
| |
| close(OUT); |
| |
| my $tdiff=time-$tstart; |
| printf("LML_file_obj: wrote XML in %6.4f sec to %s\n",$tdiff,$outfile) if($self->{TIMINGS}); |
| |
| return($rc); |
| |
| } |
| |
| 1; |