|
1 # Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 # All rights reserved. |
|
3 # This component and the accompanying materials are made available |
|
4 # under the terms of "Eclipse Public License v1.0" |
|
5 # which accompanies this distribution, and is available |
|
6 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 # |
|
8 # Initial Contributors: |
|
9 # Nokia Corporation - initial contribution. |
|
10 # |
|
11 # Contributors: |
|
12 # |
|
13 # Description: |
|
14 # Package: DrawSvg |
|
15 # Build the SVG diagram |
|
16 # |
|
17 # |
|
18 |
|
19 package DrawSvg; |
|
20 |
|
21 use Cwd; |
|
22 use Cwd 'abs_path'; |
|
23 use File::Copy; |
|
24 use File::Path; |
|
25 use FindBin; |
|
26 use lib $FindBin::Bin."/../common"; |
|
27 use Getopt::Long qw(:config no_ignore_case); |
|
28 use File::Basename; |
|
29 use File::Spec; |
|
30 |
|
31 |
|
32 use constant KNoCoreOs => 0; |
|
33 use constant KCoreOsWithHal => 1; |
|
34 use constant KCoreOsWithHardware => 2; |
|
35 use constant KOldSystemModelGenerator => 202; |
|
36 |
|
37 my @Filters; |
|
38 |
|
39 #------------------------------------------------------------------------------------------------- |
|
40 # Subroutine: new |
|
41 # Purpose: |
|
42 # Input: None (extracted from command line args) |
|
43 # Output: A reference to itself |
|
44 #------------------------------------------------------------------------------------------------- |
|
45 sub new |
|
46 { |
|
47 my $package = shift; |
|
48 my $self = {}; # Create reference to object |
|
49 bless $self, $package; # Associate a reference with class name |
|
50 |
|
51 $self->{iScriptCode} = 999; |
|
52 |
|
53 # basic test of command line: |
|
54 if (scalar(@ARGV) == 0) |
|
55 { |
|
56 $self->Help(); |
|
57 exit Logger::KErrorNone; # nothing to do. Leave |
|
58 } |
|
59 |
|
60 # process the input: |
|
61 $self->ParseCommandLineOptions(); |
|
62 |
|
63 $self->{iReturnCode} = Logger::KErrorNone; |
|
64 return $self; |
|
65 } |
|
66 |
|
67 |
|
68 # gets the schema versions without comsuming any of the command line arguments |
|
69 sub SchemaVersionsFromArgs |
|
70 { |
|
71 my @sysdefs; |
|
72 my @ini; |
|
73 my $model; |
|
74 for(my $i=0;$i<=$#_;$i++) |
|
75 { |
|
76 if($_[$i] eq '-model') |
|
77 { |
|
78 $model=$_[++$i]; |
|
79 } |
|
80 if($_[$i] eq '-sysdef') |
|
81 { |
|
82 $i++; |
|
83 push(@sysdefs,split(/,/,$_[$i])); |
|
84 } |
|
85 elsif($_[$i] eq '-i') |
|
86 { |
|
87 push(@ini,$_[++$i]); |
|
88 } |
|
89 } |
|
90 if(!scalar(@sysdefs) ) |
|
91 { |
|
92 foreach my $in (@ini) |
|
93 { |
|
94 open(INI,$in); |
|
95 my $iniDir = $in; |
|
96 $iniDir =~ s,[^\\//]+$,,; |
|
97 while(my $line = <INI>) |
|
98 { |
|
99 $line =~ s/^\s*//; # remove spaces |
|
100 $line =~ s/\s*$//; # a/a |
|
101 $line =~ s/\n$//; # remove new line |
|
102 if($line =~/"/) { |
|
103 $line =~ s/^(([^"#]*"[^"]*")+)#.*$/$1/; # remove comments indicated by # (to the end of the line) |
|
104 } else { |
|
105 $line =~ s/#.*$//; # remove comments indicated by # (to the end of the line) |
|
106 } |
|
107 next if $line eq ""; # ignore blank lines |
|
108 if ($line =~ m/sysdef\s*=\s*(.*)/i) |
|
109 { |
|
110 foreach my $file (split(/,/,$1)) |
|
111 { |
|
112 push(@sysdefs,&FullPath($iniDir,$file)); |
|
113 } |
|
114 } |
|
115 } |
|
116 close INI; |
|
117 } |
|
118 } |
|
119 my $dir = $model; |
|
120 $dir=~s,[^/\\]+$,,; |
|
121 open M,$model; |
|
122 $/=">"; |
|
123 while(my $line=<M>) |
|
124 { |
|
125 if($line=~s/<sysdef.*href=("[^"]+"|'[^']+')//) |
|
126 { |
|
127 my $f=$1; |
|
128 $f=~s/^.(.*).$/$1/; |
|
129 if(! ($f=~/^(\/|[a-z]+:)/)) {$f="$dir$f"} |
|
130 push(@sysdefs,$f); |
|
131 } |
|
132 } |
|
133 close M; |
|
134 my %res; |
|
135 foreach my $file (@sysdefs) |
|
136 { |
|
137 open S,$file; |
|
138 while(my $line = <S>) |
|
139 { |
|
140 if($line =~ /<SystemDefinition.*\sschema="(.*?)"/s) |
|
141 { |
|
142 push(@{$res{$1}},$file); |
|
143 last; |
|
144 } |
|
145 } |
|
146 close S; |
|
147 } |
|
148 $/="\n"; |
|
149 return %res; |
|
150 } |
|
151 |
|
152 sub GuessReleaseNumber() |
|
153 { |
|
154 my $self = shift; |
|
155 # always use release value if defined |
|
156 $self->{iRelease} && return $self->{iRelease} ; |
|
157 # if not there, it's in the s12, |
|
158 my $ver; |
|
159 my $t = $/; |
|
160 foreach my $s12 (@{$self->{'iS12'}}) # use version from first s12 file listed |
|
161 { |
|
162 if(-d $s12) {next} |
|
163 open(FILE,$s12) || return; |
|
164 $/='>'; |
|
165 while(<FILE>) |
|
166 { |
|
167 if(/<Schedule12\s.*\bOS_version=('(.*?)'|"(.*?)")/s) |
|
168 { |
|
169 $ver = $2 || $3; |
|
170 last; |
|
171 } |
|
172 } |
|
173 close FILE; |
|
174 $/=$t; |
|
175 return $ver; |
|
176 } |
|
177 # not there either, |
|
178 if($self->{'iDepsFile'}) |
|
179 { |
|
180 open(FILE,$self->{'iDepsFile'}) || return; |
|
181 $/='>'; |
|
182 while(<FILE>) |
|
183 { |
|
184 if(/<SystemModelDeps\s.*\bversion=('(.*?)'|"(.*?)")/s) |
|
185 { |
|
186 $ver = $2 || $3; |
|
187 last; |
|
188 } |
|
189 } |
|
190 close FILE; |
|
191 $/=$t; |
|
192 return $ver; |
|
193 } |
|
194 return ""; |
|
195 } |
|
196 |
|
197 |
|
198 # an empty value indicates its a single file. Any other value means it's a list separated by that value as a regexp |
|
199 %KFileParams = |
|
200 ( |
|
201 'iSysDefFile' => ',', |
|
202 'iS12' => ',', |
|
203 'iExtra' => ',', |
|
204 'iDepsFile' => '', |
|
205 'iLocalize' => ',', |
|
206 'iLevels' => ',', |
|
207 'iStyle' => ',', |
|
208 'iOverlay' => ',', |
|
209 'iBorder' => ',', |
|
210 'iColor' => ',', |
|
211 'iShapes' => '', |
|
212 'iLogoSrc' => '', |
|
213 'iModel' => '', |
|
214 'iLogFile' => '', |
|
215 ); |
|
216 |
|
217 sub ParseCommandLineOptions() |
|
218 { |
|
219 my $self = shift; |
|
220 |
|
221 # Possible arguments (with default values where possible): |
|
222 my $help; |
|
223 $self->{iSysDefFile}; |
|
224 $self->{iDepsFile}; |
|
225 $self->{iOutputCsv}; |
|
226 $self->{iCsvColumns}; |
|
227 $self->{iCsvLabels}; |
|
228 $self->{iTemporaryDirectory}; |
|
229 $self->{iLogFile}; |
|
230 $self->{iWarningLevel}; |
|
231 $self->{iClean}; # if specified, it will delete the temp directory. |
|
232 |
|
233 # custom properties: |
|
234 $self->{iDiagram}; # the output svg |
|
235 $self->{iCopyright}; |
|
236 $self->{iRelease}; |
|
237 $self->{iName}; |
|
238 $self->{iLabel}; |
|
239 $self->{iModel}; |
|
240 $self->{iCoreOs}; |
|
241 $self->{iLevels}; |
|
242 $self->{iExtra}; |
|
243 $self->{iIniFile}; |
|
244 $self->{iS12}; |
|
245 $self->{iLink}; |
|
246 # Read in the user arguments: |
|
247 GetOptions( "h" => \$help, |
|
248 "i=s" => \$self->{iIniFile}, |
|
249 "output=s" => \$self->{iDiagram} , |
|
250 "csv_output=s" => \$self->{iOutputCsv} , |
|
251 "csv_columns=s" => \$self->{iCsvColumns} , |
|
252 "csv_labels=s" => \$self->{iCsvLabels} , |
|
253 'xml_output=s' => \$self->{iOutputXml} , |
|
254 "model=s" => \$self->{iModel} , |
|
255 "sysdef=s" => \@{$self->{iSysDefFile}} , |
|
256 "srcvar=s" => \@{$self->{iSourceRoot}} , |
|
257 "shapes=s" => \$self->{iShapes}, |
|
258 "link=s" => \$self->{iLink}, |
|
259 "system_name=s" => \$self->{iName} , |
|
260 "system_version=s" => \$self->{iRelease} , |
|
261 "model_name=s" => \$self->{iLabel} , |
|
262 "model_version=s" => \$self->{iRevision}, |
|
263 "model_version_type=s" => \$self->{iRevisionType}, |
|
264 "copyright=s" => \$self->{iCopyright}, |
|
265 "distribution=s" => \$self->{iDistribution}, |
|
266 "legend_title=s" => \$self->{iLgdTitle}, |
|
267 "coreos=s" => \$self->{iCoreOs}, |
|
268 |
|
269 "sysinfo=s" => \@{$self->{iExtra}}, |
|
270 "localize=s" => \@{$self->{iLocalize}}, |
|
271 "levels=s" => \@{$self->{iLevels}}, |
|
272 |
|
273 "color=s" => \@{$self->{iColor}}, |
|
274 "border-shape=s" => \@{$self->{iBorder}}, |
|
275 "pattern=s" => \@{$self->{iOverlay}}, |
|
276 "border-style=s" => \@{$self->{iStyle}}, |
|
277 |
|
278 "filter=s" => \@{$self->{iFilter}}, |
|
279 "filter-has=s" => \&OrderedOption, |
|
280 "show-attr=s" => \&OrderedOption, |
|
281 "hide-attr=s" => \&OrderedOption, |
|
282 "ignore=s" => \@{$self->{iIgnore}}, |
|
283 |
|
284 "s12=s" => \@{$self->{iS12}}, |
|
285 |
|
286 "detail=s" => \$self->{iDetail}, |
|
287 "detail-type=s" => \$self->{iDetailType}, |
|
288 "page-width=s" => \$self->{iPageWidth}, |
|
289 "static" => \$self->{iStatic}, |
|
290 "deps=s" => \$self->{iDepsFile}, |
|
291 "w=s" => \$self->{iWarningLevel}, |
|
292 "clean" => \$self->{iClean}, |
|
293 "compress" => \$self->{iCompress}, |
|
294 "tempdir=s" => \$self->{iTemporaryDirectory}, |
|
295 "dpi=s" => \$self->{iPrintResolution}, |
|
296 "model_font=s" => \$self->{iModelFont}, |
|
297 "version-list=s" => \$self->{iVersions}, |
|
298 "log=s" => \$self->{iLogFile}, |
|
299 "logo=s" => \$self->{iLogoSrc}, |
|
300 "logo-height=s" => \$self->{iLogoHeight}, |
|
301 "logo-width=s" => \$self->{iLogoWidth}, |
|
302 "legend-width=s" => \$self->{iLegendWidth}, |
|
303 "legend-max-scale=s" => \$self->{iLegendMaxScale}, |
|
304 "title-scale=s" => \$self->{iTitleScale}, |
|
305 "xslt-param=s" => \%{$self->{iXsltParam}}, |
|
306 "note=s" => \@{$self->{iLegendNote}} |
|
307 ); |
|
308 |
|
309 if ($help) |
|
310 { |
|
311 warn $self->Help(); |
|
312 exit Logger::KErrorNone; |
|
313 } |
|
314 |
|
315 @{$self->{'iFiltering'}} = @Filters; |
|
316 @Filters=(); |
|
317 my $i=0; |
|
318 for($i=0;$i<=$#ARGV;$i++) |
|
319 { # check remaining args to ensure they are valid |
|
320 if($ARGV[$i]=~/^(http|file):\/\//) { # assume URLs are correct |
|
321 next; |
|
322 } |
|
323 if($ARGV[$i] eq "-" || $ARGV[$i] eq "") |
|
324 { #special values to use nothing or use the tmp file, but only valid for odd numbered args |
|
325 if($i%2==1) {next} |
|
326 $self->Help(); |
|
327 &Logger::LogFatal("Invalid syntax", KOldSystemModelGenerator, 0,Logger::KIncorrectSyntax); |
|
328 } |
|
329 if(!(-e $ARGV[$i])) { |
|
330 warn "file $ARGV[$i] does not exist"; |
|
331 exit Logger::KFileDoesNotExist; |
|
332 } |
|
333 } |
|
334 |
|
335 # Now read the ini file and override command line if necessary: |
|
336 my @yr = gmtime(); |
|
337 my $dataroot =&SystemModelXmlDataDir(); |
|
338 my %defaults = ( |
|
339 'iCopyright' => (1900+$yr[5])." Nokia Corporation", |
|
340 'iDiagram' => "sysmodel.svg", |
|
341 'iTemporaryDirectory' => "drawsvg_temp", |
|
342 'iName' => "Symbian OS" , |
|
343 'iLabel' => "System Model", |
|
344 'iLgdTitle' => "Key", |
|
345 'iShapes' => "$dataroot/Shapes.xml" , |
|
346 'iLogFile' => "" # do not set this to any default: stdout is used if log file isn't set |
|
347 ); |
|
348 my %defaultsForMulti = ( |
|
349 'iLocalize' => "$dataroot/display-names.xml" , |
|
350 'iExtra' => "$dataroot/SystemInfo.xml" |
|
351 ); |
|
352 |
|
353 $self->ReadIniFile(); |
|
354 |
|
355 foreach my $type ('iSysDefFile', 'iFilter','iSourceRoot') |
|
356 { |
|
357 if(scalar(@{$self->{$type}})==1 && $self->{$type}->[0]=~/,/) |
|
358 { # treat as comma-separated for backwards compatibility (leave alone if no commas) |
|
359 @{$self->{$type}} = split(/,/,$self->{$type}->[0]); |
|
360 } |
|
361 } |
|
362 if (scalar(@{$self->{iIgnore}})) |
|
363 { |
|
364 foreach my $type ('iIgnore') |
|
365 { |
|
366 if(scalar(@{$self->{$type}})==1) |
|
367 { # treat as semicolon-separated for backwards compatibility |
|
368 @{$self->{$type}} = split(/;/,$self->{$type}->[0]); |
|
369 } |
|
370 } |
|
371 } |
|
372 else |
|
373 { |
|
374 push(@{$self->{iIgnore}}, "layer:Tools and Utils and SDKENG","layer:MISC","block:Techview") |
|
375 } |
|
376 |
|
377 |
|
378 my $ver = $self->GuessReleaseNumber(); # determine release from attached files. |
|
379 |
|
380 # Use a special levels.xml file for 9.1 (unless it's specified by the user): |
|
381 push(@{$self->{iLevels}}, "$dataroot/Levels91.xml") if !scalar(@{$self->{iLevels}}) and $ver eq "9.1"; |
|
382 push(@{$self->{iLevels}}, "$dataroot/Levels.xml") if !scalar(@{$self->{iLevels}}) and ($ver eq "9.2" or $ver eq "9.2" ); |
|
383 |
|
384 if(!scalar(@{$self->{'iFiltering'}}) && !scalar(@{$self->{'iFilter'}})) |
|
385 { # filter only has a default if fitler-has is not set |
|
386 @{$self->{'iFilter'}}= ("java","gt"); |
|
387 } |
|
388 while (($key, $value) = each %defaults) { |
|
389 $self->{$key} = $value if ! defined $self->{$key}; |
|
390 } |
|
391 |
|
392 while (($key, $value) = each %defaultsForMulti) { |
|
393 push(@{$self->{$key}}, $value) if ! scalar(@{$self->{$key}}); |
|
394 } |
|
395 |
|
396 |
|
397 |
|
398 # if saving to .svgz, try to compress |
|
399 $self->{iCompress} = $self->{iCompress} || ( $self->{iDiagram} =~ /\.svgz$/i ); |
|
400 |
|
401 # if there's a deps file XSLT will get revision number and type from that. |
|
402 # if there is no deps file and neither revision nor revision type are specified, default to "DRAFT 1" |
|
403 if(!$self->{'iDepsFile'} && !$self->{'iRevision'} && !$self->{'iRevisionType'}) |
|
404 { |
|
405 $self->{'iRevisionType'} = "draft"; |
|
406 $self->{'iRevision'} = "1"; |
|
407 } |
|
408 |
|
409 if ($self->{iShapes} eq "$dataroot/Shapes.xml" && !scalar(@{$self->{'iColor'}})) |
|
410 { # if it's got the default shapes use default colours |
|
411 @{$self->{iColor}} = (&SystemModelColorsXmlFile()); |
|
412 } |
|
413 |
|
414 if(defined $self->{iCoreOs}) |
|
415 { |
|
416 if($self->{iCoreOs}=~/(on|yes|true)$/i ) |
|
417 { |
|
418 $self->{iCoreOs} = KCoreOsWithHal; |
|
419 } |
|
420 elsif($self->{iCoreOs}=~/(off|no|false)$/i ) |
|
421 { |
|
422 $self->{iCoreOs} = KNoCoreOs; |
|
423 } |
|
424 elsif(! ($self->{iCoreOs}=~/^[0-9]+$/ )) # any other non-number |
|
425 { |
|
426 $self->{iCoreOs} = KCoreOsWithHardware; |
|
427 } |
|
428 } |
|
429 else # use version numebr to decide |
|
430 { |
|
431 $self->{iCoreOs} = ($self->{iRelease} eq 'Future' || $ver > 9.4) ? KCoreOsWithHardware : |
|
432 (($ver=~/^9\.4/) ? KCoreOsWithHal : KNoCoreOs); |
|
433 } |
|
434 |
|
435 $self->{'iGuessVer'} = $ver; |
|
436 |
|
437 mkpath $self->{iTemporaryDirectory} if ! -d $self->{iTemporaryDirectory}; |
|
438 |
|
439 # set the log file if needed: |
|
440 $Logger::LOGFILE = $self->{iLogFile} if $self->{iLogFile}; |
|
441 |
|
442 # set the correct warning level: |
|
443 # -w=1: errors only (default) |
|
444 # -w=2: warnings as well as errors |
|
445 # -w=3: info messages, warnings and errors. |
|
446 if (defined $self->{iWarningLevel} and $self->{iWarningLevel} > 1) |
|
447 { |
|
448 if ($self->{iWarningLevel} == 2) |
|
449 { |
|
450 $self->{iWarningLevel} = LogItem::WARNING; |
|
451 } |
|
452 elsif ($self->{iWarningLevel} == 3) |
|
453 { |
|
454 $self->{iWarningLevel} = LogItem::INFO; |
|
455 } |
|
456 else # for anything higher than set it to LogItem::VERBOSE |
|
457 { |
|
458 $self->{iWarningLevel} = LogItem::VERBOSE; |
|
459 } |
|
460 } |
|
461 else |
|
462 { |
|
463 $self->{iWarningLevel} = LogItem::ERROR; |
|
464 } |
|
465 # set the logger up: |
|
466 $Logger::SEVERITY = $self->{iWarningLevel}; |
|
467 |
|
468 # set all URIs |
|
469 |
|
470 (my $dir = cwd ) =~ s#\/#\\#g; |
|
471 |
|
472 |
|
473 foreach ( keys(%KFileParams)) { |
|
474 if($self->{$_} eq '') {next} # no value, so do nothing |
|
475 if($KFileParams{$_} eq '') { |
|
476 $self->{$_} = &FullPath("$dir\\", $self->{$_} ); |
|
477 } elsif($KFileParams{$_} eq ',') { |
|
478 foreach my $item (@{$self->{$_}}) { |
|
479 if ($item eq '') {next} # skip if explicitly set to empty |
|
480 $item = &FileAsUrl(&FullPath("$dir\\",$item)); |
|
481 } |
|
482 next; |
|
483 } |
|
484 $self->{$_} = &FileAsUrl($self->{$_}); |
|
485 } |
|
486 |
|
487 } |
|
488 |
|
489 |
|
490 sub OrderedOption() { |
|
491 my $var = shift; |
|
492 my $val = shift; |
|
493 if($var=~/^(show|hide)-attr$/) { |
|
494 my $f = "<filter display='$1' "; |
|
495 if($val=~s/^([^=]+)=//) {$f.="select='$1' value='$val'/>"} |
|
496 else {$f.="select='$val'/>"} |
|
497 push(@Filters,$f); |
|
498 } elsif($var eq 'filter-has' && $val eq '*') { |
|
499 push(@Filters,"<filter display='show' select='*'/>"); |
|
500 }elsif($var eq 'filter-has') { |
|
501 if(!scalar(@Filters)) { # if the 1st is showing a filter than that implies everythig without a filter is turned off |
|
502 push(@Filters,'<filter select="*" display="hide"/>'); |
|
503 } |
|
504 foreach my $v (split(/,/,$val)) { |
|
505 push(@Filters,"<filter display='show' select='filter' value='$v'/>"); |
|
506 } |
|
507 } |
|
508 } |
|
509 |
|
510 |
|
511 |
|
512 sub FullPath { |
|
513 my $root = shift; |
|
514 my $file = shift; |
|
515 |
|
516 # If the file is not specified then return null |
|
517 if (!$file) { |
|
518 return; |
|
519 } |
|
520 |
|
521 |
|
522 # If the file is a URL or Windows path then return it as is |
|
523 if ($file =~ /:/) { |
|
524 return $file; |
|
525 } |
|
526 |
|
527 if ($root && !-e $root) { |
|
528 &Logger::LogFatal("root $root does not exist"); |
|
529 } |
|
530 |
|
531 if (-f $root) { |
|
532 $root = File::Basename::dirname($root) |
|
533 } |
|
534 |
|
535 # if root is empty or the same dir, then file is relative |
|
536 if($root eq '' or $root eq '.') { |
|
537 return $file; |
|
538 } |
|
539 |
|
540 # If the file is relative from the root then we want to add the drive letter to the file (if one exists) |
|
541 if ($file =~ s/^[\\\/]// ) { |
|
542 if ($root =~ /^([a-z]:)/i) { |
|
543 return File::Spec->catdir($1, $file); |
|
544 } |
|
545 } |
|
546 |
|
547 # Return the concatenated root and filename |
|
548 return File::Spec->catdir($root, $file); |
|
549 } |
|
550 |
|
551 |
|
552 sub ReadIniFile() |
|
553 { |
|
554 my $self = shift; |
|
555 |
|
556 return if ! defined $self->{iIniFile}; |
|
557 |
|
558 # Log a fatal error if the ini file is defined but doesn't exist: |
|
559 &Logger::LogFatal("ini file does not exist\"$self->{iIniFile}\": $!", KOldSystemModelGenerator) if ! -e $self->{iIniFile}; |
|
560 |
|
561 open(INI, $self->{iIniFile}) or |
|
562 &Logger::LogFatal("Could not open the ini file \"$self->{iIniFile}\": $!", KOldSystemModelGenerator); |
|
563 |
|
564 &Logger::LogInfo("Reading ini file \"$self->{iIniFile}...", KOldSystemModelGenerator); |
|
565 |
|
566 %AllowMulitples = ( |
|
567 "iLocalize" => 1, |
|
568 "iExtra" => 1, |
|
569 'iLevels' => 1, |
|
570 'iSysDefFile' => 1, |
|
571 'iSourceRoot' => 1, |
|
572 'iS12' => 1, |
|
573 "iIgnore" => 1, |
|
574 "iFilter" => 1, |
|
575 "iStyle" => 1, |
|
576 "iOverlay" => 1, |
|
577 "iBorder" => 1, |
|
578 "iColor" => 1, |
|
579 "iLegendNote" => 1, |
|
580 "iXsltParam" => 2 |
|
581 ); # value of 2 means it's a hash, value of 1 is an array |
|
582 |
|
583 foreach my $m (keys %AllowMulitples) { |
|
584 # if it's already set, note that we're to ignore anything in the ini file |
|
585 if($AllowMulitples{$m}==2 ? (scalar(%{$self->{$m}})>0) : (scalar(@{$self->{$m}})>0)) {$AllowMulitples{$m}=0} |
|
586 } |
|
587 |
|
588 %Ordered = ( |
|
589 "filter-has" => 1, |
|
590 "show-attr" => 1, |
|
591 "hide-attr" => 1 |
|
592 ); |
|
593 |
|
594 %IniMap = ( |
|
595 "model" => 'iModel' , |
|
596 "sysdef" => 'iSysDefFile' , |
|
597 'srcvar' => 'iSourceRoot', |
|
598 "shapes" => 'iShapes', |
|
599 "system_name" => 'iName' , |
|
600 "model_name" => 'iLabel' , |
|
601 "system_version" => 'iRelease' , |
|
602 "copyright" => 'iCopyright', |
|
603 "model_version" => 'iRevision', |
|
604 "model_version_type" => 'iRevisionType', |
|
605 "distribution" => 'iDistribution', |
|
606 "legend_title" => 'iLgdTitle', |
|
607 "coreos" => 'iCoreOs', |
|
608 "sysinfo" => 'iExtra', |
|
609 "localize" => 'iLocalize', |
|
610 "levels" => 'iLevels', |
|
611 "filter" => 'iFilter', |
|
612 "ignore" => 'iIgnore', |
|
613 "output" => 'iDiagram', |
|
614 "csv_output" => 'iOutputCsv', |
|
615 "csv_columns" => 'iCsvColumns' , |
|
616 "csv_labels" => 'iCsvLabels' , |
|
617 'xml_output' => 'iOutputXml' , |
|
618 "detail" => 'iDetail', |
|
619 "detail-type" => 'iDetailType', |
|
620 "page-width" => 'iPageWidth', |
|
621 "static" => 'iStatic', |
|
622 "color" => 'iColor', |
|
623 "border-shape" => 'iBorder', |
|
624 "pattern" => 'iOverlay', |
|
625 "deps" => 'iDepsFile', |
|
626 "border-style" => 'iStyle', |
|
627 "w" => 'iWarningLevel', |
|
628 "tempdir" => 'iTemporaryDirectory', |
|
629 'dpi' =>'iPrintResolution', |
|
630 'model_font' =>'iModelFont', |
|
631 "s12" => 'iS12', |
|
632 "log" => 'iLogFile', |
|
633 "logo" => 'iLogoSrc', |
|
634 "logo-height" => 'iLogoHeight', |
|
635 "logo-width" => 'iLogoWidth', |
|
636 'version-list' => 'iVersions', |
|
637 "link" => 'iLink', |
|
638 "clean" => 'iClean', |
|
639 "compress" => 'iCompress', |
|
640 "legend-width" =>'iLegendWidth', |
|
641 "legend-max-scale" => 'iLegendMaxScale', |
|
642 "title-scale" => 'iTitleScale', |
|
643 "xslt-param" => 'iXsltParam', |
|
644 "note" => 'iLegendNote' |
|
645 ); |
|
646 |
|
647 foreach my $line (<INI>) |
|
648 { |
|
649 $line =~ s/^\s*//; # remove spaces |
|
650 $line =~ s/\s*$//; # a/a |
|
651 $line =~ s/\n$//; # remove new line |
|
652 if($line =~/"/) { |
|
653 $line =~ s/^(([^"#]*"[^"]*")+)#.*$/$1/; # remove comments indicated by # (to the end of the line) |
|
654 } else { |
|
655 $line =~ s/#.*$//; # remove comments indicated by # (to the end of the line) |
|
656 } |
|
657 next if $line eq ""; # ignore blank lines |
|
658 if ($line =~ m/([^=]+)\s*=\s*(.*)/) |
|
659 { |
|
660 my $argType = lc $1; # case-insensitive |
|
661 my $argValue = $2; # case-sensitive as it can have strings intended for html output |
|
662 |
|
663 $argType =~ s/^\s*//; # remove spaces on either end (Cannot use s/\s+// as this will not be suitable for html text) |
|
664 $argType =~ s/\s*$//; |
|
665 $argValue =~ s/^\s*//; |
|
666 $argValue =~ s/\s*$//; |
|
667 |
|
668 $argValue =~ s/^'//; # no need for quotes around the values |
|
669 $argValue =~ s/'$//; |
|
670 $argValue =~ s/^"//; |
|
671 $argValue =~ s/"$//; |
|
672 |
|
673 my $iniDir = $self->{iIniFile}; |
|
674 $iniDir =~ s,[^\\//]+$,,; |
|
675 #$iniDir .= '\\'; |
|
676 |
|
677 if(defined $Ordered{$argType}) { |
|
678 &OrderedOption($argType, $argValue); |
|
679 } elsif(defined $IniMap{$argType}) { |
|
680 my $param = $IniMap{$argType}; |
|
681 # make sure all files mentioned are taken relative to the ini file |
|
682 if($KFileParams{$param} ne '' ) |
|
683 {# comma-separated filenames |
|
684 my @list; |
|
685 foreach my $item (split(/,/,$argValue)) |
|
686 { |
|
687 push(@list,&FullPath($iniDir,$item)); |
|
688 } |
|
689 $argValue = join(',',@list); |
|
690 } |
|
691 elsif(defined $KFileParams{$param} && $argValue ne '') |
|
692 {# single file names |
|
693 $argValue = &FullPath($iniDir,$argValue); |
|
694 } |
|
695 # do not override! Only set values that have not been set on command line already |
|
696 if ($AllowMulitples{$param}==1) # check so we don't add if it's set by the cmd line |
|
697 { |
|
698 push(@{$self->{$param}}, $argValue); |
|
699 } |
|
700 elsif ($AllowMulitples{$param}==2) # check so we don't add if it's set by the cmd line |
|
701 { |
|
702 $argValue=~s/^([^=]+)=//; |
|
703 $self->{$param}->{$1}=$argValue; |
|
704 } |
|
705 elsif (! defined $AllowMulitples{$param}) |
|
706 { |
|
707 $self->{$param} = $argValue if ! $self->{$param}; |
|
708 } |
|
709 } |
|
710 } |
|
711 } |
|
712 ; |
|
713 @{$self->{'iFiltering'}} = @Filters if ! @{$self->{'iFiltering'}}; |
|
714 @Filters=(); |
|
715 } |
|
716 |
|
717 sub MakeInfo() { |
|
718 my $self = shift; |
|
719 my %files = @_; |
|
720 my $res=""; |
|
721 while (my ($key,$value) = each %files) { |
|
722 if ($self->{$key} ne '') { |
|
723 $res .= "\t\t<info href='".$self->{$key}."' type='$value'/>\n" |
|
724 } |
|
725 } |
|
726 return $res; |
|
727 } |
|
728 |
|
729 sub MakeMultiInfo() { |
|
730 my $self = shift; |
|
731 my %files = @_; |
|
732 my $res=""; |
|
733 while (my ($key,$value) = each %files) { |
|
734 foreach my $m (@{$self->{$key}}) { |
|
735 if($m ne '') { # skip if empty |
|
736 $res .= "\t\t<info href='$m' type='$value'/>\n" |
|
737 } |
|
738 } |
|
739 } |
|
740 return $res; |
|
741 } |
|
742 |
|
743 sub MakeAttirbutes() { |
|
744 my $self = shift; |
|
745 my %atts = @_; |
|
746 my $res=""; |
|
747 while (my ($key,$value) = each %atts) { |
|
748 if (defined $self->{$key}) { |
|
749 my $cur = $self->{$key}; |
|
750 if($key=~/File$/) {$cur=&FileAsUrl($cur)} # anything that ends in File is treated as a URL |
|
751 $res .= " $value=\"$cur\""; |
|
752 } |
|
753 } |
|
754 return $res; |
|
755 } |
|
756 |
|
757 sub getSchedule12Xml () |
|
758 { |
|
759 my $self = shift; |
|
760 my $ver = shift; |
|
761 my @files = @{$self->{'iS12'}}; |
|
762 my @ret; |
|
763 foreach my $s12 (@files) |
|
764 { |
|
765 if($s12 eq '') {next} |
|
766 if($s12=~/^file:\/\/\/(.*)$/) |
|
767 { |
|
768 if(-d $1) |
|
769 { |
|
770 # it's a directory, so append Symbian_OS_v[version]_Schedule12.xml |
|
771 $s12=~s,[\\/]*$,/Symbian_OS_v${ver}_Schedule12.xml,; |
|
772 } |
|
773 } |
|
774 push(@ret,$s12); |
|
775 } |
|
776 return @ret |
|
777 } |
|
778 |
|
779 sub getModel() |
|
780 { |
|
781 my $self = shift; |
|
782 if($self->{iModel}) {return $self->{iModel}} |
|
783 |
|
784 my $xsltDir = $self->GetXsltDir(); |
|
785 |
|
786 my $tempDirectoryPathname = abs_path($self->{iTemporaryDirectory}); |
|
787 |
|
788 (my $modelXml = "$tempDirectoryPathname/Model.xml") =~ s#\/#\\#g; |
|
789 (my $modelTemplateXml = $xsltDir."/") =~ s#\/#\\#g; |
|
790 |
|
791 if($self->{iCoreOs} == KCoreOsWithHardware) { # show 9.5+ CoreOS |
|
792 $modelTemplateXml .= "ModelTemplate.xml"; |
|
793 } elsif($self->{iCoreOs} == KCoreOsWithHal ) { # show 9.4 CoreOS |
|
794 $modelTemplateXml .= "ModelTemplate.mid.xml"; |
|
795 } else { |
|
796 $modelTemplateXml .= "ModelTemplate.older.xml"; |
|
797 } |
|
798 |
|
799 |
|
800 # the follownig params cannot be emtpy, delete if they are |
|
801 foreach my $item ('iCopyright' , 'iDistribution' ,'iDepsFile', 'iLink', 'iDetailType', 'iDetail', 'iVersions') |
|
802 { |
|
803 if($self->{$item} eq '') {delete $self->{$item}} |
|
804 } |
|
805 |
|
806 |
|
807 # Step 1: |
|
808 # Create a Model.xml based on the ModelTemplate.xml |
|
809 open (INPUT, $modelTemplateXml) or &Logger::LogError("Xalan error ($?) occured in Step 1 of SVG building (<$modelTemplateXml)...", KOldSystemModelGenerator, 1); |
|
810 open (OUTPUT, ">$modelXml") or &Logger::LogError("Xalan error ($?) occured in Step 1 of SVG building (>$modelXml)...", KOldSystemModelGenerator, 1); |
|
811 my $release = $self->{iRelease}; |
|
812 |
|
813 |
|
814 # Since $self->{iSysDefFile} may be a comma-separated list of sysdefs, create a <sysdef> tag for each one of the files: |
|
815 my $sysdefTagsForModelTemplate = ""; |
|
816 |
|
817 @{$self->{'iS12'}} = $self->getSchedule12Xml($self->{'iGuessVer'}); |
|
818 |
|
819 if(scalar(@{$self->{iSourceRoot}}) == 1) |
|
820 { |
|
821 @{$self->{iSourceRoot}} = ($self->{iSourceRoot}->[0]) x scalar($self->{iSourceRoot}->[0]); |
|
822 } |
|
823 |
|
824 for (my $index = 0; $index < scalar(@{$self->{iSysDefFile}}); ++$index) |
|
825 { |
|
826 $sysdefTagsForModelTemplate .= $self->CreateSysDefTagsForModelXML($self->{iSysDefFile}->[$index], $self->{iSourceRoot}->[$index]); |
|
827 } |
|
828 |
|
829 my $display; |
|
830 |
|
831 if($self->{iLink}=~/\\/) # it's a windows dir, change to file URI |
|
832 { |
|
833 $self->{iLink} = &FileAsUrl($self->{iLink}); |
|
834 } |
|
835 |
|
836 $display .= $self->MakeMultiInfo ('iLocalize' => 'abbrev'); |
|
837 |
|
838 my %infoMap = ( |
|
839 'iStyle' => 'style', |
|
840 'iOverlay' => 'overlay', |
|
841 'iBorder' => 'border', |
|
842 'iColor' => 'color' |
|
843 ); |
|
844 |
|
845 $display .=$self->MakeMultiInfo( %infoMap); |
|
846 if($self->{'iLogoSrc'}) |
|
847 { |
|
848 $display.="\n<logo". $self->MakeAttirbutes( |
|
849 'iLogoSrc' => 'src', |
|
850 'iLogoWidth' => 'width', |
|
851 'iLogoHeight' => 'height' |
|
852 ) ; |
|
853 if($self->{'iLogoSrc'} =~ /\.svg$/i) |
|
854 { |
|
855 $display.= " embed=\"yes\""; |
|
856 } |
|
857 $display.= "/>"; |
|
858 } |
|
859 |
|
860 my $filters=''; |
|
861 if(scalar @{$self->{'iFiltering'}}) # complex filtering |
|
862 { |
|
863 $filters = join("\n\t",@{$self->{'iFiltering'}}); |
|
864 } |
|
865 elsif (@{$self->{iFilter}}) { # can't have both -filter and complex filtering |
|
866 foreach ( @{$self->{iFilter}}) { |
|
867 if($_ ne '') {$filters.="<filter accept='$_'/>\n\t";} |
|
868 } |
|
869 } |
|
870 |
|
871 my $ignore=''; |
|
872 |
|
873 foreach ( @{$self->{iIgnore}}){ |
|
874 if(/^(.*):(.*)$/) {$ignore.="<ignore type='$1' name='$2'/>\n\t"} |
|
875 } |
|
876 |
|
877 |
|
878 my $optional = $self->MakeAttirbutes( |
|
879 'iCopyright' => 'copyright', |
|
880 'iDistribution' => 'distribution', |
|
881 'iRevision' => 'revision', |
|
882 'iDepsFile' => 'deps', |
|
883 'iLink' => 'link', |
|
884 'iRevisionType' => 'revision-type', |
|
885 'iVersions' => 'version-list' |
|
886 ); |
|
887 |
|
888 if($self->{iRelease} ne '') {$optional .= " ver='$self->{iRelease}'"} |
|
889 elsif($self->{iGuessVer} eq 'Future' ) {$optional .= " ver='$self->{iGuessVer}'"} |
|
890 |
|
891 |
|
892 my $layout = $self->MakeAttirbutes( |
|
893 'iDetail' => 'detail', |
|
894 'iDetailType' => 'detail-type', |
|
895 'iPageWidth' => 'page-width', |
|
896 'iPrintResolution' => 'resolution', |
|
897 'iModelFont' => 'font' |
|
898 ); |
|
899 if($self->{iStatic}) {$layout .= " static='true'"} |
|
900 my $legend = ''; |
|
901 my @legendmap = ( |
|
902 'iColor', 'colors', |
|
903 'iStyle', 'styles', |
|
904 'iOverlay', 'patterns', |
|
905 'iBorder', 'borders' |
|
906 ); # order is important |
|
907 for(my $i=0; $i<$#legendmap;$i+=2){ |
|
908 my $cur='#'.$infoMap{$legendmap[$i]}; |
|
909 my $count = scalar(@{$self->{$legendmap[$i]}}); |
|
910 if ($count==0 || ($count==1 && $self->{$legendmap[$i]}->[0] eq '' )) {$cur='@shapes'."#$legendmap[$i+1]"} |
|
911 $legend .= "\t\t\t<legend use=\"$cur\"/>\n"; |
|
912 } |
|
913 foreach my $note (@{$self->{iLegendNote}}) |
|
914 { |
|
915 if(!($note=~/&#?[0-9a-z]+;/i)) |
|
916 { # if not entity-encoded, entity encode the stuff |
|
917 $note=~ s/([&<>\x7f-\xff])/"&#".ord($1).";"/eg; |
|
918 } |
|
919 $legend .= "\t\t\t<note width='auto'>$note</note>"; |
|
920 } |
|
921 |
|
922 my $legendOptions; |
|
923 if($self->{iLegendWidth}) {$legendOptions .= ' width="' .$self->{iLegendWidth} .'"'} |
|
924 if($self->{iLegendMaxScale}) {$legendOptions .= ' maxscale="' .$self->{iLegendMaxScale} .'"'} |
|
925 if($self->{iTitleScale}) {$legendOptions .= ' title-scale="' .$self->{iTitleScale} .'"'} |
|
926 foreach my $line (<INPUT>) |
|
927 { |
|
928 my $cur=''; |
|
929 $line =~ s/___SYMBIAN_OS_RELEASE___/$self->{iRelease}/g; # not used |
|
930 $line =~ s/___NAME___/$self->{iName}/g; |
|
931 $line =~ s/___LABEL___/$self->{iLabel}/g; |
|
932 $line =~ s/___REVISION_TYPE___/$self->{iRevisionType}/g; # not used |
|
933 $line =~ s/___LINK___/$self->{iLink}/g; # not used |
|
934 $line =~ s/___OPTIONAL___/$optional/g; |
|
935 $line =~ s/___LAYOUT_OPTIONS___/$layout/g; |
|
936 $line =~ s/___FILTERS___/$filters/g; |
|
937 $line =~ s/___IGNORE___/$ignore/g; |
|
938 $line =~ s/___LEGEND___/$legend/g; |
|
939 $line =~ s/___LEGEND_TITLE___/$self->{iLgdTitle}/g; |
|
940 $line =~ s/___LEGEND_OPTIONS___/$legendOptions/g; |
|
941 $line =~ s/___SHAPES_XML___/$self->{iShapes}/g; |
|
942 $line =~ s/___SYSTEM_DEFINITIONS___/$sysdefTagsForModelTemplate/; # should be only one incident of it |
|
943 $line =~ s/___DISPLAY___/$display/g; |
|
944 $line =~ s/\sshapes=""//g; # remove empty attribute |
|
945 print OUTPUT $line; |
|
946 } |
|
947 close INPUT; |
|
948 close OUPUT; |
|
949 |
|
950 # Open and close the file so that it can flush itself: |
|
951 open (OUTPUT, "$modelXml") or &Logger::LogError("Xalan error ($error) occured in Step 1 of SVG building...", KOldSystemModelGenerator, 1); |
|
952 close OUTPUT; |
|
953 return $modelXml; |
|
954 } |
|
955 |
|
956 sub GetXsltDir() |
|
957 { |
|
958 my $self = shift; |
|
959 my $xsltDir = $FindBin::Bin."/svg"; # calcluated w.r.t old directory |
|
960 $xsltDir = $FindBin::Bin."/src/old/svg" if ! -d $xsltDir; # calculated w.r.t the root directory |
|
961 $xsltDir = $FindBin::Bin if ! -d $xsltDir; # calculated w.r.t the /svg directory |
|
962 return $xsltDir; |
|
963 } |
|
964 |
|
965 |
|
966 sub FileAsUrl() |
|
967 { |
|
968 my $file = $_[0]; |
|
969 if($file=~/^..+:/){ return $file} # already a URL |
|
970 if(-f $file) |
|
971 { # abs_path only works on dirs, so strip off file name and put it back when done |
|
972 if(! ($file=~/^[a-z]:[\\\/][^\\\/]+$/i)) |
|
973 { # if it's in the root dir, do nothing |
|
974 my $tail = "/$file"; |
|
975 # if it's just a file name, need to find cwd; |
|
976 if($file =~ s,([\\/][^\\/]+)$,,) |
|
977 { |
|
978 $tail = $1; |
|
979 } |
|
980 else {$file = "."} |
|
981 $file = abs_path($file)."$tail"; |
|
982 } |
|
983 } |
|
984 elsif (-d $file) |
|
985 { |
|
986 $file = abs_path($file); |
|
987 } # else does not exist, so just convert to unix-style path |
|
988 $file=~tr/\\/\//; |
|
989 return "file:///$file"; |
|
990 } |
|
991 |
|
992 |
|
993 sub RunCmd() { |
|
994 my $command = shift; |
|
995 open(EXE,"$command 2>&1|"); |
|
996 while(<EXE>){ |
|
997 chomp; |
|
998 s/^XSLT Message: //; |
|
999 s/\.Source tree node:.*$//; |
|
1000 if($_ ne '') { |
|
1001 if(s/^note: //i) { |
|
1002 &Logger::LogInfo($_, KOldSystemModelGenerator,2, 100); |
|
1003 } elsif(s/^Warning: //) { |
|
1004 &Logger::LogWarning($_, KOldSystemModelGenerator,2, 600); |
|
1005 } elsif(s/^Error: //i) { |
|
1006 &Logger::LogError($_, KOldSystemModelGenerator,2, 400); |
|
1007 } else { |
|
1008 print STDERR "$_\n"; |
|
1009 } |
|
1010 } |
|
1011 } |
|
1012 close(EXE); |
|
1013 return $?; |
|
1014 } |
|
1015 |
|
1016 sub ShouldCreateDepmodel() |
|
1017 { |
|
1018 my $self = shift; |
|
1019 if ($self->{iDepsFile}) |
|
1020 { |
|
1021 return 1; |
|
1022 } |
|
1023 my $model = $self->getModel(); |
|
1024 my $t = $/; |
|
1025 $/='>'; |
|
1026 open(M,$model); |
|
1027 while(<M>) |
|
1028 { |
|
1029 if(/<model\s/){last} |
|
1030 } |
|
1031 close M; |
|
1032 $/ = $t; |
|
1033 return /\sdeps=/; |
|
1034 } |
|
1035 |
|
1036 sub XsltTransform() |
|
1037 { |
|
1038 my $xslt = shift; |
|
1039 my $from = shift; |
|
1040 my $to = shift; |
|
1041 my $indent = shift; |
|
1042 my %params = %{$_[0]}; |
|
1043 my $xsltParams; |
|
1044 |
|
1045 # windows-specific stuff follows |
|
1046 |
|
1047 if(! ($xslt=~/^..+:/)) {$xslt =~ s#\/#\\#g} #it's not a URL |
|
1048 if(! ($from=~/^..+:/)) {$from =~ s#\/#\\#g} #it's not a URL |
|
1049 if(! ($to=~/^..+:/)) {$to =~ s#\/#\\#g} #it's not a URL |
|
1050 |
|
1051 while (my($p,$v) = each(%{$_[0]})) |
|
1052 { |
|
1053 $v =~ s/"/"/g; #" |
|
1054 $xsltParams.= " -p $p \"$v\""; |
|
1055 } |
|
1056 |
|
1057 my $command = &SysModelGen::Xalan(); |
|
1058 $command =~ s#\/#\\#g; |
|
1059 $command .= $xsltParams; |
|
1060 if($indent >=0) { |
|
1061 $command .= " -i $indent"; |
|
1062 } |
|
1063 if($to ne '') { |
|
1064 $command .= " -o \"$to\""; |
|
1065 } |
|
1066 $command.=" \"$from\" \"$xslt\""; |
|
1067 &Logger::LogInfo("System Call: $command", 800); |
|
1068 if($to eq '') {return `$command`} |
|
1069 return &RunCmd($command); |
|
1070 } |
|
1071 |
|
1072 sub Draw() |
|
1073 { |
|
1074 my $self = shift; |
|
1075 my $genSvg = $self->{'iDiagram'} ne ''; |
|
1076 my $genCsv = $self->{'iOutputCsv'} ne ''; |
|
1077 my $genXml = $self->{'iOutputXml'} ne ''; |
|
1078 |
|
1079 if(!$genSvg && !$genCsv && !$genXml) |
|
1080 { |
|
1081 &Logger::LogFatal("Must specify at least one type of output file. Cannot continue...", KOldSystemModelGenerator, 0,Logger::KNothingToDo); |
|
1082 } |
|
1083 |
|
1084 &Logger::LogInfo("Creating sysmodel.svg...", KOldSystemModelGenerator,0); |
|
1085 |
|
1086 # Step 0: |
|
1087 # Prepare some file names and create output directory: |
|
1088 |
|
1089 # construct full path name: |
|
1090 ($self->{iRootDirectory} = cwd ) =~ s#\/#\\#g; |
|
1091 chdir($self->{iTemporaryDirectory}); |
|
1092 my $tempDirectoryPathname = cwd; # now gives the full path name $self->{iTemporaryDirectory} |
|
1093 chdir($self->{iRootDirectory}); # change back! |
|
1094 |
|
1095 my $xsltDir = $self->GetXsltDir(); |
|
1096 |
|
1097 my $tempStuctureFile = "$tempDirectoryPathname/system_model_svg_tmp.xml"; |
|
1098 my $tempXslFile = "$tempDirectoryPathname/system_model_svg_tmp.xsl"; |
|
1099 my $tempModelFile = "$tempDirectoryPathname/model_tmp.svg"; |
|
1100 my $tempModelFile2 = "$tempDirectoryPathname/model_tmp2.svg"; |
|
1101 my $modelXsl = $xsltDir."/Model.xsl"; |
|
1102 |
|
1103 my $modelXml = $self->getModel(); |
|
1104 |
|
1105 # Step 2 |
|
1106 # xalan -i 2 model.xml model.xsl > tmp.xml |
|
1107 $error = &XsltTransform($modelXsl,$modelXml,$tempStuctureFile,1, $self->{'iXsltParam'}); |
|
1108 |
|
1109 &Logger::LogError("Xalan error ($error) occured in combining sysdefs", KOldSystemModelGenerator, 1) if $error; |
|
1110 |
|
1111 # Step 3 - validation |
|
1112 # xalan tmp.xml validate.xsl |
|
1113 if($self->{iWarningLevel} == LogItem::VERBOSE ) |
|
1114 { |
|
1115 my $errors = &XsltTransform($xsltDir."/validate.xsl",$tempStuctureFile,'',-1); |
|
1116 &Logger::LogList(split(/\n/,$errors)); |
|
1117 } |
|
1118 if($genSvg) |
|
1119 { # only needed for model building |
|
1120 |
|
1121 # Step 4 |
|
1122 &Logger::LogInfo("Creating styling XSLT...", KOldSystemModelGenerator, 1); |
|
1123 $error = &XsltTransform("$xsltDir/Shapes.xsl",$modelXml,$tempXslFile,1, |
|
1124 {%{$self->{'iXsltParam'}},'Model-Transform' => "'".&FileAsUrl($modelXsl)."'" }); |
|
1125 &Logger::LogError("Xalan error ($error) occured generating Styling transform", KOldSystemModelGenerator, 2) if $error; |
|
1126 |
|
1127 # Step 5 |
|
1128 &Logger::LogInfo("Generating SVG model...", KOldSystemModelGenerator, 1); |
|
1129 $error = &XsltTransform($tempXslFile,$tempStuctureFile,$tempModelFile,1,$self->{'iXsltParam'}); |
|
1130 &Logger::LogError("Xalan error ($error) occured in building SVG", KOldSystemModelGenerator, 2) if $error; |
|
1131 |
|
1132 if ($self->ShouldCreateDepmodel()) { # insert as 1st transform |
|
1133 @ARGV=( $xsltDir."/Postprocess.xsl",'-',@ARGV) |
|
1134 } |
|
1135 my $tmpsvg = $tempModelFile; |
|
1136 while(scalar(@ARGV)) { |
|
1137 my $transform = shift(@ARGV); |
|
1138 my $datafile = shift(@ARGV); |
|
1139 if($datafile eq '""' || $datafile eq "''") {$datafile=''} # not sure if this will work, but it should fix cygwin troubles |
|
1140 if($datafile eq '-') {$datafile = &FileAsUrl($tempStuctureFile)} |
|
1141 elsif($datafile ne '') {$datafile = &FileAsUrl($datafile)} |
|
1142 # save to the output if this is the last transform |
|
1143 # otherwise save to tempModelFile2 if reading from tempModelFile, and vis versa |
|
1144 my $saveto = $self->{'iDiagram'}; |
|
1145 if(scalar(ARGV)) { |
|
1146 $saveto = ($tmpsvg eq $tempModelFile) ? $tempModelFile2 : $tempModelFile; |
|
1147 } |
|
1148 # Step 6 |
|
1149 # xalan -i 2 -p Data tmp.xml 'tmp.svg' postprocess.xsl> final.svg |
|
1150 my %p; |
|
1151 if($datafile ne '') { |
|
1152 $p{'Data'}="'$datafile'"; # optional -- only if needed for transform |
|
1153 } |
|
1154 $error = &XsltTransform($transform,$tmpsvg,$saveto,1,\%p); |
|
1155 &Logger::LogError("Xalan error ($error) occured in post-processing SVG file", KOldSystemModelGenerator, 2) if $error; |
|
1156 |
|
1157 $tmpsvg = $saveto; # read from this next time. |
|
1158 } |
|
1159 if ($tmpsvg ne $self->{'iDiagram'}) { |
|
1160 open(OUT,">".$self->{iDiagram}); |
|
1161 open(IN,$tmpsvg); |
|
1162 print OUT <IN>; |
|
1163 close OUT; |
|
1164 close IN; |
|
1165 } |
|
1166 |
|
1167 my $zipname = $self->{iDiagram}; |
|
1168 my $unzipname = $zipname; |
|
1169 $zipname =~ s/\.svg$/.svgz/i; |
|
1170 $unzipname =~ s/\.svgz$/.svg/i; |
|
1171 my $compressed = 0; |
|
1172 if($self->{iCompress}) |
|
1173 { |
|
1174 my $gzip = &SysModelGen::GzipCommand(); |
|
1175 if($gzip) |
|
1176 { |
|
1177 my $command = "$gzip ".$self->{iDiagram}; |
|
1178 &Logger::LogInfo("System Call: $command", KOldSystemModelGenerator); |
|
1179 $error = &RunCmd($command);# this should generate the sysmodel.svg in the output directory |
|
1180 &Logger::LogError("Gzip error ($error) occured when comrpessing SVG", KOldSystemModelGenerator, 1) if $error; |
|
1181 &Logger::LogInfo("Renaming output to : $zipname", KOldSystemModelGenerator); |
|
1182 rename $self->{iDiagram}.".gz", $zipname; |
|
1183 $compressed = 1; |
|
1184 } |
|
1185 } |
|
1186 if(!$compressed && $unzipname ne $self->{iDiagram}) |
|
1187 { |
|
1188 &Logger::LogInfo("Renaming output to : $unzipname", KOldSystemModelGenerator); |
|
1189 rename $self->{iDiagram}, $unzipname; |
|
1190 } |
|
1191 } |
|
1192 # create CSV if desired |
|
1193 if($genCsv) |
|
1194 { |
|
1195 &Logger::LogInfo("Generating CSV output", KOldSystemModelGenerator, 0); |
|
1196 my %p; |
|
1197 if($self->{iCsvColumns}) |
|
1198 { |
|
1199 $p{'atts'}="'".$self->{iCsvColumns}."'"; |
|
1200 } |
|
1201 if($self->{iCsvLabels}) |
|
1202 { |
|
1203 $p{'labels'}="'".$self->{iCsvLabels}."'"; |
|
1204 } |
|
1205 $error = &XsltTransform($xsltDir."/output-csv.xsl",$tempStuctureFile,$self->{iOutputCsv},-1,\%p); |
|
1206 &Logger::LogError("Xalan error ($error) occured in CSV output...", KOldSystemModelGenerator, 1) if $error; |
|
1207 |
|
1208 } |
|
1209 |
|
1210 # create sysdef XML if desired |
|
1211 |
|
1212 if($genXml) |
|
1213 { |
|
1214 &Logger::LogInfo("Generating XML output", KOldSystemModelGenerator, 0); |
|
1215 $error = &XsltTransform($xsltDir."/output-sysdef.xsl",$tempStuctureFile,$self->{iOutputXml},1); |
|
1216 &Logger::LogError("Xalan error ($error) occured in Sysdef output...", KOldSystemModelGenerator, 1) if $error; |
|
1217 } |
|
1218 |
|
1219 # delete the contents of the temp directory if -clean is specified by the user: |
|
1220 if ($self->{iClean}) |
|
1221 { |
|
1222 &Logger::LogInfo("Deleting contents of the temp directory $self->{iTemporaryDirectory}...", 100); |
|
1223 $self->DeleteTempDirectory(); |
|
1224 } |
|
1225 } |
|
1226 |
|
1227 sub Downgrade() |
|
1228 { |
|
1229 my $self = shift; |
|
1230 my $sysdef = shift; |
|
1231 my $saveto = $self->{iTemporaryDirectory}."/".shift; |
|
1232 my $sysdefurl=&FileAsUrl($sysdef); |
|
1233 my $xsltDir = $self->GetXsltDir(); |
|
1234 foreach(@{$self->{iSysDefFile}}) |
|
1235 { |
|
1236 if($_ eq $sysdefurl) |
|
1237 { |
|
1238 $error = &XsltTransform("$xsltDir/sysdefdowngrade.xsl",$sysdef,$saveto,1); |
|
1239 &Logger::LogError("Xalan error ($error) occured in downgrading $sysdef...", KOldSystemModelGenerator, 1) if $error; |
|
1240 $_=&FileAsUrl($saveto); |
|
1241 } |
|
1242 } |
|
1243 } |
|
1244 |
|
1245 |
|
1246 sub SystemModelXmlDataDir() |
|
1247 { |
|
1248 my $file = $FindBin::Bin."/src/old/resources/auxiliary"; |
|
1249 $file = $FindBin::Bin."/../resources/auxiliary" if ! -d $file; # calculated w.r.t the /svg directory |
|
1250 return $file; |
|
1251 } |
|
1252 |
|
1253 sub SystemModelColorsXmlFile() |
|
1254 { |
|
1255 my $colorsFile = &SystemModelXmlDataDir()."/system_model_colors.xml"; |
|
1256 return $colorsFile; |
|
1257 } |
|
1258 |
|
1259 |
|
1260 |
|
1261 sub CreateSysDefTagsForModelXML() |
|
1262 { |
|
1263 my $self = shift; |
|
1264 my $sysdefXml = shift; |
|
1265 my $srcvar = shift; |
|
1266 |
|
1267 if($sysdefXml eq '') |
|
1268 { |
|
1269 &Logger::LogInfo("Cannot find System Definition file", 100); |
|
1270 return; |
|
1271 } |
|
1272 |
|
1273 my $ret = "<sysdef href=\"".&FileAsUrl($sysdefXml)."\""; |
|
1274 if($srcvar ne '') {$ret.=" root=\"$srcvar\""} |
|
1275 $ret .=">\n" . |
|
1276 $self->MakeMultiInfo('iExtra' => 'extra', 'iLevels' => 'levels' , 'iS12' => 's12'); |
|
1277 return "$ret\t</sysdef>\n"; |
|
1278 } |
|
1279 |
|
1280 sub DeleteTempDirectory() |
|
1281 { |
|
1282 my $self = shift; |
|
1283 # This will delete all files in the $self->{iTemporaryDirectory} |
|
1284 rmtree $self->{iTemporaryDirectory}; |
|
1285 } |
|
1286 |
|
1287 sub Help() |
|
1288 { |
|
1289 my $self = shift; |
|
1290 format OK = |
|
1291 @<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< |
|
1292 $param, $text, |
|
1293 ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~ |
|
1294 $text |
|
1295 . |
|
1296 my @list =( |
|
1297 'Switch', 'Explanation', |
|
1298 '------', '-----------', |
|
1299 '-h' , 'Help on usage', |
|
1300 '-i' , 'An INI file listing one argument per line, with the syntax: <argument> = <value>', |
|
1301 '==== Build Control ====', |
|
1302 '-w' , 'Warning level. 1: errors only (default), 2: warnings as well as errors, 3: info messages, warnings and errors, 4: all plus deep syntax validation and reporting -- note that this can take a long time to compute so do not use this warning level by default', |
|
1303 '-tempdir', 'Temporary directory for build files. Defaults to drawsvg_temp', |
|
1304 '-output', 'The name of the file to save the built System Model SVG. If in the format filename.svgz, it will attempt to compress the file. If compression is not supported, it will rename the output to filename.svg. Defaults to sysmodel.svg or sysmodel.svgz if -compress is set.', |
|
1305 '-csv_output', 'The name of the file to save a CSV description of the built System Model. Only items shown on the system model will be included.', |
|
1306 '-csv_columns', 'Comma-separated list of columns to include in the output CSV. This does nothing if -csv_output is not present. By default (if -csv_columns is not present), the columns will be a sorted list of all attributes on all items. ', |
|
1307 '-csv_labels', 'Comma-separated list of columns labels include in the output CSV. Do not use quotes or commas in label names. This does nothing if -csv_output is not present. If this list is shorter than -csv_columns, the remaining columns will use the attribute name as the label. ', |
|
1308 '-xml_output', 'The name of the file to save a combined system definition XML. Only items shown in the built system model will be included.', |
|
1309 '-log' , 'File in which to store output. Defaults to stdout', |
|
1310 '-compress', 'If set, it will attempt to compress the output as an SVGZ file. In order to success gzip must be installed and in the PATH. This will also rename the output file from filename.svg to filename.svgz.', |
|
1311 '-clean' , 'Caution: if set, it will delete the contents of the temporary directory.', |
|
1312 "==== Files or URIs ====\nAll of these take a file name (relative or absolute path) or URI of a data source", |
|
1313 '-model', 'The location of the Model XML file to use to build the file. If this is provided all other non-build control command line and ini options are ignored.', |
|
1314 '-shapes', 'The location of the Shapes XML file used to provide rules to control the display of the components on the model. If not present, default behaviour (in Shapes.xml) is used. This and the default bahaviours are overrriden by using the -color, -border, -pattern, and -style options. ', |
|
1315 '-localize', 'The location of the Localization file used to provide displayable names for the model entities. By default, the provided "display-names.xml" is used.', |
|
1316 '-s12', 'The location of the Schedule 12 XML file used to provide the border shapres of the components. If this a directory, the S12 XML file is found by appending "Symbian_OS_v[system_version]_Schedule12.xml" to the directory.', |
|
1317 '-levels', 'The location of the Levels XML file used to override the stacking of collections. ', |
|
1318 '-sysinfo', 'The location of extra component information used to provided additional properies for components. By default, the provided "SystemInfo.xml" is used.', |
|
1319 '-deps', 'The location of the Dependencies XML file used to draw the depmodel. If not present, dependencies will not be drawn', |
|
1320 '-color', 'The location of a Values XML file used to specify per-component colours. If not present, the default colours are used.', |
|
1321 '-border-shape', 'The location of a Values XML file used to specify the shape (border) of each component. If not present, the default borders are used.', |
|
1322 '-pattern', 'The location of a Values XML file used to specify per-component overlay patterns. If not present, the default patterns (for new and reference components) are used.', |
|
1323 '-border-style', 'The location of a Values XML file used to specify per-component border styles. If not present, the default border styles are used. ', |
|
1324 '-link','The base URL to use for all hyperlinks in the model. A base URL will be appended by the type and name (e.g. Blocks/Comms%20Services.html) of the items to create the full URL of the linked file. Window directories will be converted into file URIs.', |
|
1325 "==== Labels ====\nAll of these take a plain text value which is displayed on the model", |
|
1326 '-system_name', 'The name of the product described in the model. It appears at the bottom right. Defaults to "Symbian OS"', |
|
1327 '-system_version', 'The version of the product described in the model. It appears at the bottom right after the name.', |
|
1328 '-model_name', 'The label for the model. It appears at the bottom right, under the name. Defaults to "System Model".', |
|
1329 '-model_version', 'A number which appears before th model-revision-type. If specified this overrides the build number used by depmodel. If not building depmodel, this defaults to "1"', |
|
1330 '-model_version_type', 'One of "draft", "issued", "build" or free-text value. Appears below the model label. If specified this overrides the build number used by DepToolkit.If not building depmodel, this defaults to "draft"', |
|
1331 '-copyright', 'The copyright to appear in the lower left. Set to empty string to leave out. Defaults to "[this year] Nokia Corporation"', |
|
1332 '-distribution', 'Text to appear on the bottom centre to indicate to whom the model can be show. Informational only. Suggested values are "internal", "secret" or "unrestrictred". Not shown if not set.', |
|
1333 '-legend_title', 'The title to appear in the leftmost part of the legend. Defautls to "Key"', |
|
1334 '-note', 'Free text to appear inside the legend box, on the rightmost side. If multiple ones are provided, they will appear as separate boxes from left to right. Newlines and other special characters can be entity-encoded (e.g. 
)', |
|
1335 "==== Model Control ====", |
|
1336 '-sysdef [uri-list]', 'Comma-separated list of locations for the System Definition XML file(s) used to build the model. Layers in the files will be stacked on top of each other in order, from bottom to top.', |
|
1337 '-coreos [on/off/new]', 'Turn on or off Core OS colouring, or use the new colouring for 9.5 and later models. Defaults to "off" for model versions before 9.4 or those with no specified version, "on" for 9.4 and "new" for 9.5 and later', |
|
1338 '-filter [filter-name]', 'The name of a filter to turn on when building the model. All filters on an item must be present in this list in order for that item to appear. Can have any number of these Defaults to "java" and "gt"', |
|
1339 '-filter-has [filter-name]', 'Like -filter, except any filter on an item must be present in this list in order for that item to appear. Include "*" in the list in order to show items with no filters. Equivalent to "-show-attr filter xxx"', |
|
1340 '-ignore [item]', 'A model entity to not draw, in the form "[item-type]:[item-name]". Any number of these can be used. Defaults to "layer:Tools and Utils and SDKENG" ,"layer:MISC", "block:Techview"', |
|
1341 '-show-attr [attr[=val]]', 'A mechanism of filtering which allows filtering based on component attribute values. If a value is set for that attribute, the component will be shown. Use in conjunction with -hide-attr for fine contol of what is shown. "class" and "filter" attribtues are handled specially -- see the documentation for details', |
|
1342 '-hide-attr [attr[=val]]', 'A mechanism of filtering which allows filtering based on component attribute values. If a value is set for that attribute, the component will not be shown on the model. Use in conjunction with -show-attr for fine contol of what is shown. "class" and "filter" attribtues are handled specially -- see the documentation for details', |
|
1343 '-detail [item-type]' , 'The type of the smallest System Model entity to draw. One of "layer", "block", "subblock", "collection" or "component". Defaults to "component"', |
|
1344 '-detail-type [type]' , 'If set to "fixed", the smallest System Model entity drawn will have a fixed width (rather then sized by their invisible components). This can be used to reduce the size and complexity of the overall model.', |
|
1345 '-page-width [length]', 'The width of the drawn image (with units). If not specified it will fit the viewer window. Valid units: "in", "mm", "cm", "px", "pt"', |
|
1346 '-static', 'If present, the model will not have any mouseover effects (this is overriden by builing the depmodel).', |
|
1347 '-logo [file]', 'If present, the logo will be drawn in the lower-left corner of the model. If the logo is an SVG file, -logo-width and -logo-height are optional, otherwise the must both be specified', |
|
1348 '-logo-height [length]', 'Specifies the height of the logo (if any) in mm. Width is scaled along with height unless otherwise specified. Both width and height MUST be specified if a bitmap image is used', |
|
1349 '-logo-width [length]', 'Specifies the width of the logo (if any) in mm. Height is scaled along with width unless otherwise specified. Both width and height MUST be specified if a bitmap image is used', |
|
1350 '-legend-width [%]', 'The percent width of the model the legend takes up. This will scale the size of the legend and model title, but not the logo, to fill the specified space. If a logo is included, but no width specified, the legend cannot be scaled since it will not be able to determine the available space. Note that that -max-legend-scale will further limit the potential width.', |
|
1351 '-legend-max-scale [scale]', 'Specifies the maximum scale factor for resizing the legend. If this is present and -legend-width is not, the legend and title will scale to 100% of the available width. If both are present the scale factor will take precedent. If neither is present, the legend will not resize. Note that when this is used, the legend can shrink if it would normally be wider than the model.', |
|
1352 '-title-scale [scale]', 'Specifies the scale factor for the size of the title font (the text in the lower right). Use this instead of CSS to control the size, since the model generator needs to explicitly know how much space to allocate for the title.', |
|
1353 '-model_font [font]', 'The name of the base font to use to draw the model. This will be overriden by any custom CSS in the Shapes XML', |
|
1354 '-dpi [number]', 'The DPI to use when printing from the Adobe SVG Viewer. If not present, it will print well at A4 size. A value of 300 will look good on A3 size paper' |
|
1355 ); |
|
1356 print STDERR "Usage: DrawSvg.pl [Arguments] [Transform Data-file] ...\n\nArguments:\n"; |
|
1357 my $head=2; |
|
1358 while(@list) { |
|
1359 $param = shift(@list); |
|
1360 if($head<=0 and !($param=~/^-/)){print "\n$param\n";next;} |
|
1361 $text = shift(@list); |
|
1362 write OK ; |
|
1363 $head--; |
|
1364 } |
|
1365 return; |
|
1366 } |
|
1367 |
|
1368 1; |