releasing/cbrtools/perl/NotesCompiler.pm
changeset 602 3145852acc89
equal deleted inserted replaced
600:6d08f4a05d93 602:3145852acc89
       
     1 # Copyright (c) 2000-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 the License "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 # 
       
    15 #
       
    16 
       
    17 package NotesCompiler;
       
    18 
       
    19 use strict;
       
    20 use CGI qw(-no_debug :standard start_ul);
       
    21 use IniData;
       
    22 use RelData;
       
    23 use EnvDb;
       
    24 use MrpData;
       
    25 use IO::File;
       
    26 use File::Basename;
       
    27 
       
    28 
       
    29 #
       
    30 # Constants.
       
    31 #
       
    32 
       
    33 use constant NOTES_DIREXTENSION => '.RelNotes';
       
    34 
       
    35 #
       
    36 # Public.
       
    37 #
       
    38 
       
    39 sub New {
       
    40   my $pkg = shift;
       
    41   my $self = {};
       
    42   bless $self, $pkg;
       
    43   $self->{iniData} = shift;
       
    44   $self->{comp} = shift;
       
    45   $self->{ver} = shift;
       
    46   $self->{verbose} = shift;
       
    47   $self->{htmlMainFile} = shift;
       
    48   $self->{outputSTDOUTonly} = shift;
       
    49   $self->{htmlNotes} = shift; # flag to render old notes as html or plain text
       
    50   $self->{fh} = undef; # filehandle to write to
       
    51   $self->{envDb} = EnvDb->Open($self->{iniData}, $self->{verbose});
       
    52   # Not using 'use constant' because that requires Utils::PrependEpocRoot to be called at compile-time
       
    53   $self->{notes_store} = Utils::PrependEpocRoot('\\epoc32\\relinfo\\notes'); # constant
       
    54   return $self;
       
    55 }
       
    56 
       
    57 sub DoStandardNotes {
       
    58   my $self = shift;
       
    59   if( !defined ($self->{htmlMainFile} )) {
       
    60     my $filename = $self->{comp}.".".$self->{ver};
       
    61     if ($self->{htmlNotes}) {
       
    62       $filename.=".htmlnotes";
       
    63     } else {
       
    64       $filename.=".textnotes";
       
    65     }
       
    66     $self->{htmlName} = $self->{notes_store} . "\\$filename.html";
       
    67   }
       
    68   else {
       
    69     $self->{htmlName} = $self->{htmlMainFile};
       
    70   }
       
    71   
       
    72   if(!defined ($self->{outputSTDOUTonly})){
       
    73     $self->WriteUnlessAlreadyCompiled(\&PrepareStandardNotes, undef, 1); # sub, filename, cache
       
    74   }
       
    75   else{
       
    76     $self->WriteUnlessAlreadyCompiled(\&PrepareStandardNotes, undef, 0); # sub, filename, cache
       
    77   }
       
    78 }
       
    79 
       
    80 sub DoCompSummary {
       
    81   my $self = shift;
       
    82   if( !defined ($self->{htmlMainFile} )) {
       
    83     $self->{htmlName} = $self->{notes_store} . "\\$self->{comp}.summary.html";
       
    84   }
       
    85   else {
       
    86     $self->{htmlName} = $self->{htmlMainFile};
       
    87   }
       
    88   my $relDataObjects = RelData->OpenSet($self->{iniData}, $self->{comp}, $self->{verbose});
       
    89   @$relDataObjects = grep { $self->PassesFilter($_) } @$relDataObjects;
       
    90   foreach my $thisRelData (@$relDataObjects) {
       
    91     my $ver = $thisRelData->Version();
       
    92     my $htmlName;
       
    93     my $filename = $self->{comp}.".".$ver;
       
    94     if ($self->{htmlNotes}) {
       
    95       $filename.=".htmlnotes";
       
    96     } else {
       
    97       $filename.=".textnotes";
       
    98     }
       
    99     if( !defined ($self->{htmlMainFile}) ) {
       
   100       $htmlName = $self->{notes_store} . "\\$filename.html";
       
   101     }
       
   102     else {
       
   103       $htmlName = $self->{htmlMainFile} . NOTES_DIREXTENSION . "\\$filename.html";
       
   104     }
       
   105     $self->WriteUnlessAlreadyCompiled(\&PrepareStandardNotes, $htmlName, 1, $thisRelData); # sub, filename, cache, @args
       
   106   }
       
   107   $self->WriteUnlessAlreadyCompiled(\&PrepareSummary, undef, 0, $relDataObjects, 1); # sub, filename, cache, @args
       
   108   return $self;
       
   109 }
       
   110 
       
   111 sub DoEnvSummary {
       
   112   my $self = shift;
       
   113   if( !defined ($self->{htmlMainFile} )) {
       
   114     if ($self->{comp} and $self->{ver}) {
       
   115       $self->{htmlName} = $self->{notes_store} . "\\$self->{comp}.$self->{ver}.summary.html";
       
   116     }
       
   117     else {
       
   118       $self->{htmlName} = $self->{notes_store} . "\\current_env_summary.html";
       
   119     }
       
   120   }
       
   121   else {
       
   122     $self->{htmlName} = $self->{htmlMainFile};
       
   123   }
       
   124 
       
   125   my $versionInfo;
       
   126   if ($self->{comp} and $self->{ver}) {
       
   127     my $relData = RelData->Open($self->{iniData}, $self->{comp}, $self->{ver}, $self->{verbose});
       
   128     $versionInfo = $relData->Environment();
       
   129   }
       
   130   else {
       
   131     $versionInfo = $self->{envDb}->VersionInfo();
       
   132   }
       
   133 
       
   134   my @relData;
       
   135   foreach my $thisComp (sort keys %$versionInfo) {
       
   136     my $thisVer = $versionInfo->{$thisComp};
       
   137     (my $relData, my $preview) = $self->CreateRelData($thisComp, $thisVer);
       
   138     next unless $self->PassesFilter($relData);
       
   139     push (@relData, $relData);
       
   140     my $htmlName;
       
   141     my $filename = $thisComp.".".$thisVer;
       
   142     if ($self->{htmlNotes}) {
       
   143       $filename.=".htmlnotes";
       
   144     } else {
       
   145       $filename.=".textnotes";
       
   146     }
       
   147     if( !defined ($self->{htmlMainFile} )) {
       
   148       $htmlName = $self->{notes_store} . "\\$filename.html";
       
   149     }
       
   150     else {
       
   151       $htmlName = $self->{htmlMainFile} . NOTES_DIREXTENSION . "\\$filename.html";
       
   152     }
       
   153     $self->WriteUnlessAlreadyCompiled(\&PrepareStandardNotes, $htmlName, 1, $relData, $preview); # sub, filename, cache, @args
       
   154   }
       
   155   $self->WriteUnlessAlreadyCompiled(\&PrepareSummary, undef, 0, \@relData); # sub, filename, cache, @args
       
   156   return $self;
       
   157 }
       
   158 
       
   159 sub DoDiffEnvSummary {
       
   160   my $self = shift;
       
   161   my $comp2 = shift;
       
   162   my $ver2 = shift;
       
   163 
       
   164   require EnvDifferencer;
       
   165 
       
   166   my $comp1 = $self->{comp};
       
   167   my $ver1 = $self->{ver};
       
   168   $comp2 ||= $comp1;
       
   169   $ver2 ||=  $self->{envDb}->VersionInfo()->{$comp2};
       
   170   unless ($ver2) {
       
   171     die "Error: $comp2 not installed in current environment\n";
       
   172   }
       
   173   if( !defined ($self->{htmlMainFile} )) {
       
   174     my $filename = $comp1.".".$ver1.".".$comp2.".".$ver2."-full";
       
   175     if ($self->{htmlNotes}) {
       
   176       $filename.=".htmlnotes";
       
   177     } else {
       
   178       $filename.=".textnotes";
       
   179     }
       
   180     $self->{htmlName} = $self->{notes_store} . "\\$filename.html";
       
   181   }
       
   182   else {
       
   183     $self->{htmlName} = $self->{htmlMainFile};
       
   184   }
       
   185   if(!defined ($self->{outputSTDOUTonly})){
       
   186     $self->WriteUnlessAlreadyCompiled(\&PrepareDiffEnvReport, undef, 1, $comp2, $ver2); # sub, filename, cache, @args
       
   187   }
       
   188   else{
       
   189     $self->WriteUnlessAlreadyCompiled(\&PrepareDiffEnvReport, undef, 0, $comp2, $ver2); # sub, filename, cache, @args
       
   190   }
       
   191 }
       
   192 
       
   193 sub HtmlFileName {
       
   194   my $self = shift;
       
   195   return $self->{htmlName};
       
   196 }
       
   197 
       
   198 sub HtmlMainFile {
       
   199   my $self = shift;
       
   200   return $self->{htmlMainFile};
       
   201 }
       
   202 
       
   203 sub SetProjectFilter {
       
   204   my $self = shift;
       
   205   $self->{filter}->{project} = shift;
       
   206 }
       
   207 
       
   208 sub SetVersionNumberFilter {
       
   209   my $self = shift;
       
   210   $self->{filter}->{versionregex} = shift;
       
   211 }
       
   212 
       
   213 #
       
   214 # Private.
       
   215 #
       
   216 
       
   217 sub WriteUnlessAlreadyCompiled {
       
   218   my $self = shift;
       
   219   my $sub = shift;
       
   220   my $filename = shift || $self->{htmlName};
       
   221   my $cache = shift;
       
   222   my @args = @_;
       
   223 
       
   224   if ($cache) {
       
   225     return if $self->NotesFileAlreadyCompiled($filename, $self->{comp}, $self->{ver});
       
   226   }
       
   227 
       
   228   my $output = $sub->($self, @args);
       
   229  
       
   230   if (!defined ($self->{outputSTDOUTonly})) {
       
   231     my $fh = $self->OpenFileForWriting($filename);
       
   232     print "FILE LOCATION: $filename\n" if ($self->{verbose});
       
   233     print $fh $output;
       
   234     $fh = undef; # close file
       
   235   }
       
   236   else {
       
   237     print $output;
       
   238   }
       
   239 }
       
   240 
       
   241 sub OpenFileForWriting {
       
   242   my $self = shift;
       
   243   my $filename = shift;
       
   244   Utils::MakeDir(dirname($filename));
       
   245   return new IO::File($filename, "w") or die "Couldn't open file \"$filename\" for writing: $!";
       
   246 }
       
   247 
       
   248 sub PrepareDiffEnvReport {
       
   249   my $self = shift;
       
   250   my $endcomp = shift;
       
   251   my $endver = shift;
       
   252   my $startcomp = $self->{comp};
       
   253   my $startver = $self->{ver};
       
   254 
       
   255   $self->{envDb} = EnvDb->Open($self->{iniData}, $self->{verbose});
       
   256 
       
   257   my $envDifferencer = EnvDifferencer->New($self->{iniData}, $self->{verbose});
       
   258   $envDifferencer->SetStartCompVer($startcomp, $startver);
       
   259   $envDifferencer->SetEndCompVer($endcomp, $endver);
       
   260 
       
   261   my @contentsrows;
       
   262   my $bodies;
       
   263   
       
   264   my $changedcomps = $envDifferencer->ChangedComps();
       
   265   my $i=0;
       
   266   foreach my $comp (sort @$changedcomps) {
       
   267     $i++; # counter for debug output only
       
   268     my $endReldata = $envDifferencer->EndReldata($comp);
       
   269     my $intermediateReldatas = $envDifferencer->IntermediateReldatas($comp);
       
   270     
       
   271     my @allreldatas = (@$intermediateReldatas, $endReldata);
       
   272     @allreldatas = grep { $self->PassesFilter($_) } @allreldatas;
       
   273     print "Processing $comp ($i/".(scalar @$changedcomps)."): ".(scalar @allreldatas)." releases to process\n" if $self->{verbose};
       
   274     next unless @allreldatas;
       
   275 
       
   276     my @versions;
       
   277 
       
   278     $bodies .= hr . h2(a({name=>$comp},$comp));
       
   279 
       
   280     my $firstver;
       
   281     foreach my $reldata (sort { $b->ReleaseTime() <=> $a->ReleaseTime() } @allreldatas) {
       
   282       my $ver = $reldata->Version();
       
   283       my $link = "$comp$ver";
       
   284       if(defined $self->{htmlMainFile})
       
   285         {
       
   286         $link = $self->{htmlMainFile} . NOTES_DIREXTENSION . "/" . $link;
       
   287         }
       
   288       # First add an entry to our contents table
       
   289       push @versions, td(a{href=>"#$link"}, $ver);
       
   290 
       
   291       # Now prepare the body itself
       
   292       $bodies .= a({name=>$link}, h3($ver));
       
   293       $bodies .= ul($self->MainBody($reldata, 1)); # 1 = concise
       
   294     }
       
   295     push @contentsrows, Tr(th(a({href=>"#$comp"},$comp)), @versions);
       
   296   }
       
   297 
       
   298   my $output = "";
       
   299   $output .= h1("Differences between $startcomp $startver and $endcomp $endver");
       
   300   $output .= h1("Contents");
       
   301   $output .= p("Newer releases are on the left.");
       
   302   $output .= table({border=>1},@contentsrows);
       
   303 
       
   304   if(defined $bodies){
       
   305     $output .= $bodies;
       
   306   }
       
   307   
       
   308   return $output;
       
   309 }
       
   310 
       
   311 sub PrepareStandardNotes {
       
   312   my $self = shift;
       
   313   my $relData = shift;
       
   314   my $preview;
       
   315   my $comp;
       
   316   my $ver;
       
   317   if ($relData) {
       
   318     $comp = $relData->Component();
       
   319     $ver = $relData->Version();
       
   320   } else {
       
   321     $comp = $self->{comp};
       
   322     $ver = $self->{ver};
       
   323     ($relData, $preview) = $self->CreateRelData($comp, $ver);
       
   324   }
       
   325   my $output = "";
       
   326 
       
   327   if ($self->{verbose}) { print "Compiling release notes for $comp $ver...\n"; }
       
   328 
       
   329   if ($preview) {
       
   330     $output .= start_html({-title => "$comp $ver release notes PREVIEW"})
       
   331       .h1({-style=>'Color: red;'}, 'Release Notes Preview'). hr
       
   332       .h1("$comp")
       
   333       .hr;
       
   334   }
       
   335   else {
       
   336     $output .= start_html({-title => "$comp $ver release notes"})
       
   337       .h1("$comp")
       
   338       .hr;
       
   339   }
       
   340 
       
   341   $output .= $self->MainBody($relData);
       
   342   $output .= $self->EnvDetails($relData, $preview);
       
   343   $output .= $self->SrcFilterErrors($relData, $preview);
       
   344 
       
   345   $output .= end_html();
       
   346  
       
   347   return $output;
       
   348 }
       
   349 
       
   350 sub PrepareSummary {
       
   351   my $self = shift;
       
   352   my $relDataObjects = shift;
       
   353   my $compSummary = shift;
       
   354 
       
   355   my $output = "";
       
   356 
       
   357   if ($compSummary) {
       
   358     if ($self->{verbose}) { print "Writing component summary for $self->{comp}...\n"; }
       
   359     $output .= (start_html({-title => "Release note summary for component $self->{comp}"})
       
   360       .h1("Release note summary for component $self->{comp}")
       
   361       .hr);
       
   362   }
       
   363   else {
       
   364     if ($self->{comp} and $self->{ver}) {
       
   365       if ($self->{verbose}) { print "Writing environment summary for $self->{comp} $self->{ver}...\n"; }
       
   366       $output .= (start_html({-title => "Release note summary for environment $self->{comp} $self->{ver}"})
       
   367       .h1("Release note summary for environment $self->{comp} $self->{ver}")
       
   368       .hr);
       
   369     }
       
   370     else {
       
   371       if ($self->{verbose}) { print "Writing environment summary for current environment...\n"; }
       
   372       $output .= (start_html({-title => "Release note summary for the current environment"})
       
   373         .h1("Release note summary for the current environment")
       
   374         .hr);
       
   375     }
       
   376   }
       
   377 
       
   378   foreach my $thisRelData (@$relDataObjects) {
       
   379     my $thisVer = $thisRelData->Version();
       
   380     my $thisComp = $thisRelData->Component();
       
   381     my $thisIntVer = $thisRelData->InternalVersion();
       
   382 
       
   383     my $link;
       
   384     if ($compSummary) {
       
   385       my $filename = $self->{comp}.".".$thisVer;
       
   386       if ($self->{htmlNotes}) {
       
   387         $filename.=".htmlnotes";
       
   388       } else {
       
   389         $filename.=".textnotes";
       
   390       }
       
   391       $link = "$filename.html";
       
   392     }
       
   393     else {
       
   394       my $filename = $thisComp.".".$thisVer;
       
   395       if ($self->{htmlNotes}) {
       
   396         $filename.=".htmlnotes";
       
   397       } else {
       
   398         $filename.=".textnotes";
       
   399       }
       
   400       $link = "$filename.html";
       
   401     }
       
   402 
       
   403     if(defined $self->{htmlMainFile})
       
   404       {
       
   405       $link = $self->{htmlMainFile} . NOTES_DIREXTENSION . "/" . $link;
       
   406       }
       
   407 
       
   408     my $caption = $thisVer;
       
   409     if ($thisIntVer) {
       
   410       $caption .= " [$thisIntVer]";
       
   411     }
       
   412     unless ($compSummary) {
       
   413       $caption = "$thisComp $caption";
       
   414     }
       
   415     my $notesSrc = $thisRelData->NotesSource();
       
   416     $output .= a({ -href => $link }, $caption). ' - ';
       
   417     $output .= ("Made by $notesSrc->{releaser} on $notesSrc->{date}");
       
   418     $output .= (p(""));
       
   419   }
       
   420 
       
   421   $output .= (end_html());
       
   422   return $output;
       
   423 }
       
   424 
       
   425 sub CreateRelData {
       
   426   my $self = shift;
       
   427   my $comp = shift;
       
   428   my $ver = shift;
       
   429 
       
   430   my $installedVer = $self->{envDb}->Version($comp);
       
   431   my $preview = 0;
       
   432   my $relData;
       
   433   if (defined $installedVer) {
       
   434     if ($ver eq $installedVer) {
       
   435       if ($self->{envDb}->Status($comp) == EnvDb::STATUS_PENDING_RELEASE) {
       
   436         # This release has not yet been made, so preview the notes.
       
   437         $preview = 1;
       
   438         my $intVer = $self->{envDb}->InternalVersion($comp);
       
   439         unless (defined $intVer) {
       
   440           $intVer = ' ';
       
   441         }
       
   442         my $mrpData = MrpData->New($self->{envDb}->MrpName($comp),
       
   443           $ver, $intVer, $self->{iniData}, $self->{verbose});
       
   444           $relData = RelData->New($self->{iniData}, $mrpData,
       
   445           Utils::PrependSourceRoot($mrpData->NotesSource()), $self->{envDb}->VersionInfo(), 'viewnotes', $self->{verbose}, 1);
       
   446       }
       
   447     }
       
   448   }
       
   449   unless (defined $relData) {
       
   450     # This release has already been made, so we can read it's reldata.
       
   451     $relData = RelData->Open($self->{iniData}, $comp, $ver, $self->{verbose});
       
   452   }
       
   453 
       
   454   return ($relData, $preview);
       
   455 }
       
   456 
       
   457 sub MainBody {
       
   458   my $self = shift;
       
   459   my $relData = shift;
       
   460   my $concise = shift;
       
   461 
       
   462   my $output = "";
       
   463 
       
   464   if ($self->{verbose} > 1) {
       
   465     print "Compiling release notes main body for ".$relData->Component()." ".$relData->Version()."...\n";
       
   466   }
       
   467 
       
   468   my $notesSrc = $relData->NotesSource();
       
   469   
       
   470   my $release_version = $relData->MadeWithVersion();
       
   471 
       
   472   foreach my $key (keys %{$notesSrc}) {
       
   473     my $html_markers;
       
   474     my $note = $notesSrc->{$key};
       
   475     if (ref $note eq 'ARRAY') {
       
   476       $html_markers = $self->CheckHtmlMarkers(join("",@$note));
       
   477     } else {
       
   478       $html_markers = $self->CheckHtmlMarkers($note);
       
   479     }
       
   480     if (!$html_markers) {
       
   481       if (Utils::CompareVers($release_version, "2.83.1013") > 0) {
       
   482         # 'Recent' release: escape html chars
       
   483         $notesSrc->{$key} = $self->EscapeHtmlChars($note);
       
   484       } else {
       
   485         # Old release
       
   486         if (!($self->{htmlNotes})) {
       
   487           # User hasn't set html_notes: escape html chars
       
   488           $notesSrc->{$key} = $self->EscapeHtmlChars($note);
       
   489         }
       
   490       }
       
   491     }
       
   492   }
       
   493   
       
   494   unless ($concise) {
       
   495     my $comp = $relData->Component();
       
   496     my $ver = $relData->Version();
       
   497     my $intVer = $relData->InternalVersion();
       
   498     my $toolsver = $relData->MadeWith();
       
   499     my $sourcecode = $relData->SourceIncluded();
       
   500     my $mrpName = $relData->MrpName();
       
   501     my $project = $self->ComponentProject($comp, $ver);
       
   502     my $envUserName = $relData->EnvUserName() || "";
       
   503     my $firstCompatibleVersion = $relData->FirstCompatibleVersion() || "&lt;unknown&gt;";
       
   504     my $zipsize;
       
   505     eval {
       
   506       $zipsize = $self->{envDb}->GetReleaseSize($relData->Component(), $relData->Version());
       
   507     };
       
   508     $zipsize ||= "-"; # for example, if we're pending release...
       
   509 
       
   510     $output .= table({-border=>0}, Tr({-align =>'left'},
       
   511                [td([b('Version'), $ver]),
       
   512           td([b('Internal version'), ($intVer || "&lt;none&gt;")]),
       
   513           td([b('Made by'), $notesSrc->{releaser}]),
       
   514           td([b('Date'), $notesSrc->{date}]),
       
   515           td([b('Made with'), $toolsver]),
       
   516           td([b('Earliest compatible tools'), $firstCompatibleVersion]),
       
   517           td([b('Source included'), tt($sourcecode)]),
       
   518           td([b('Size of release zips'), tt($zipsize)]),
       
   519           td([b('Project storage archive'), $project]),
       
   520           td([b('MRP file used'), tt($mrpName)]),
       
   521           td([b('Environment username'), $envUserName])
       
   522                ]));
       
   523   }
       
   524 
       
   525   $output .= hr;
       
   526   $output .= h2("Release Summary");
       
   527   $output .= h3("Reason for release");
       
   528   foreach my $line (@{$notesSrc->{releaseReason}}) {
       
   529     $output .= tt($line). br;
       
   530   }
       
   531   $output .= h3("General release comments");
       
   532   foreach my $line (@{$notesSrc->{generalComments}}) {
       
   533       $output .= tt($line). br;
       
   534   }
       
   535   $output .= h3("Known omissions, deviations and discrepancies");
       
   536   foreach my $line (@{$notesSrc->{knownDeviations}}) {
       
   537       $output .= tt($line). br;
       
   538   }
       
   539   
       
   540   @{$notesSrc->{bugsFixed}} = map tt($_), @{$notesSrc->{bugsFixed}};
       
   541   @{$notesSrc->{bugsRemaining}} = map tt($_), @{$notesSrc->{bugsRemaining}}; 
       
   542   @{$notesSrc->{otherChanges}} = map tt($_), @{$notesSrc->{otherChanges}};
       
   543    
       
   544   $output .= hr;
       
   545   $output .= h2("Bugs fixed");
       
   546   $output .= ul(li($notesSrc->{bugsFixed}));
       
   547   $output .= hr;
       
   548   $output .= h2("Known bugs remaining");
       
   549   $output .= ul(li($notesSrc->{bugsRemaining}));
       
   550   $output .= hr;
       
   551   $output .= h2("Other changes");
       
   552   $output .= ul(li($notesSrc->{otherChanges}));
       
   553   $output .= hr;
       
   554 
       
   555   return $output;
       
   556 }
       
   557 
       
   558 sub EscapeHtmlChars {
       
   559   my $self = shift;
       
   560   my $note = shift;
       
   561   
       
   562   my $newnote;
       
   563   if (ref $note eq 'ARRAY') {
       
   564     $newnote = [];
       
   565     foreach my $line (@$note) {
       
   566       my $newline = $line;
       
   567       $newline =~ s/&/&amp;/g;
       
   568       $newline =~ s/</&lt;/g;
       
   569       $newline =~ s/>/&gt;/g;
       
   570       push @$newnote, $newline;
       
   571     }
       
   572   } else {
       
   573     $newnote = $note;
       
   574     $newnote =~ s/&/&amp;/g;
       
   575     $newnote =~ s/</&lt;/g;
       
   576     $newnote =~ s/>/&gt;/g;
       
   577   }
       
   578   return $newnote;
       
   579 }
       
   580 
       
   581 sub CheckHtmlMarkers {
       
   582   my $self = shift;
       
   583   my $note = shift;
       
   584   if ($note =~ /^\s*<\s*html\s*>.*<\s*[\/\\]\s*html\s*>\s*$/i) {
       
   585     # Note begins with <html> and ends with </html> or something along those lines
       
   586     return 1;
       
   587   } else {
       
   588     return 0;
       
   589   }
       
   590 }
       
   591 
       
   592 sub EnvDetails {
       
   593   my $self = shift;
       
   594   my $relData = shift;
       
   595   my $preview = shift;
       
   596 
       
   597   my $contents = "";
       
   598 
       
   599   if ($preview) {
       
   600     $contents .= h2("Release environment");
       
   601     $contents .= span({-style=>'Color: red;'}, '[not yet known]');
       
   602     $contents .= br();
       
   603   }
       
   604   else {
       
   605     my $env = $relData->Environment();
       
   606     if (defined $env) {
       
   607       $contents .= h2("Release environment");
       
   608       my $tableData;
       
   609       $contents .= p("Number of components: ".(scalar keys %$env));
       
   610       foreach my $comp (sort keys %{$env}) {
       
   611   push (@$tableData, td([b($comp), $env->{$comp}]));
       
   612       }
       
   613       $contents .= table({-border=>0}, Tr({-align =>'left'}, $tableData));
       
   614     }
       
   615   }
       
   616   return $contents;
       
   617 }
       
   618 
       
   619 sub SrcFilterErrors {
       
   620   my $self = shift;
       
   621   my $relData = shift;
       
   622   my $preview = shift;
       
   623   my $notesSrc = $relData->NotesSource();
       
   624 
       
   625   my $contents = "";
       
   626 
       
   627   if (defined $notesSrc->{srcFilterErrors} and scalar(@{$notesSrc->{srcFilterErrors}}) > 0) {
       
   628     $contents .= hr, h2("Source filter errors");
       
   629     foreach my $errorLine (@{$notesSrc->{srcFilterErrors}}) {
       
   630       $contents .= $errorLine, br();
       
   631     }
       
   632   }
       
   633   return $contents;
       
   634 }
       
   635 
       
   636 sub NotesFileAlreadyCompiled {
       
   637   my $self = shift;
       
   638   my $fileName = shift;
       
   639   my $comp = shift;
       
   640   my $ver = shift;
       
   641   my $alreadyCompiled = 0;
       
   642 
       
   643   if(!(defined $self->{htmlMainFile})) {
       
   644     if (-e $fileName && $comp && $ver) {
       
   645       my $reldata = $self->{iniData}->PathData->LocalArchivePathForExistingOrNewComponent($comp, $ver) . '\\reldata';
       
   646       if (-e $reldata and Utils::FileModifiedTime($reldata) < Utils::FileModifiedTime($fileName)) {
       
   647         $alreadyCompiled = 1;
       
   648       }
       
   649     }
       
   650   }
       
   651   return $alreadyCompiled;
       
   652 }
       
   653 
       
   654 sub PassesFilter {
       
   655   my $self = shift;
       
   656   my $rd = shift;
       
   657   my $comp = $rd->Component();
       
   658   my $ver = $rd->Version();
       
   659   if ($self->{filter}->{project}) {
       
   660     return 0 unless $self->ComponentProject($comp, $ver) eq $self->{filter}->{project};
       
   661   }
       
   662   if ($self->{filter}->{versionregex}) {
       
   663     my $re = $self->{filter}->{versionregex};
       
   664     return 0 unless $ver =~ m/$re/i;
       
   665   }
       
   666   return 1;
       
   667 }
       
   668 
       
   669 sub ComponentProject {
       
   670   my $self = shift;
       
   671   my $comp = shift;
       
   672   my $ver = shift;
       
   673 
       
   674   return $self->{iniData}->PathData->ComponentProject($comp, $ver);
       
   675 }
       
   676 
       
   677 1;
       
   678   
       
   679 __END__
       
   680 
       
   681 =head1 NAME
       
   682 
       
   683 NotesCompiler.pm - Compiles a set of release notes into HTML.
       
   684 
       
   685 =head1 INTERFACE
       
   686 
       
   687 =head2 New
       
   688 
       
   689 Expects to be passed an C<IniData> reference, a component name, a version, a verbosity level, an output HTML file name and an output STDOUT only flag. Creates a C<RelData> object for the component release and uses the information contained within it to compile the output HTML file.
       
   690 
       
   691 =head1 KNOWN BUGS
       
   692 
       
   693 None.
       
   694 
       
   695 =head1 COPYRIGHT
       
   696 
       
   697  Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
       
   698  All rights reserved.
       
   699  This component and the accompanying materials are made available
       
   700  under the terms of the License "Eclipse Public License v1.0"
       
   701  which accompanies this distribution, and is available
       
   702  at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
   703  
       
   704  Initial Contributors:
       
   705  Nokia Corporation - initial contribution.
       
   706  
       
   707  Contributors:
       
   708  
       
   709  Description:
       
   710  
       
   711 
       
   712 =cut