LCOV - code coverage report
Current view: top level - httpd/template - SiteHeaderFooter.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 24 59 40.7 %
Date: 2022-11-19 15:00:39 Functions: 6 11 54.5 %

          Line data    Source code
       1             : // Copyright (C) 2013 The Android Open Source Project
       2             : //
       3             : // Licensed under the Apache License, Version 2.0 (the "License");
       4             : // you may not use this file except in compliance with the License.
       5             : // You may obtain a copy of the License at
       6             : //
       7             : // http://www.apache.org/licenses/LICENSE-2.0
       8             : //
       9             : // Unless required by applicable law or agreed to in writing, software
      10             : // distributed under the License is distributed on an "AS IS" BASIS,
      11             : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             : // See the License for the specific language governing permissions and
      13             : // limitations under the License.
      14             : 
      15             : package com.google.gerrit.httpd.template;
      16             : 
      17             : import static com.google.gerrit.common.FileUtil.lastModified;
      18             : 
      19             : import com.google.common.base.Strings;
      20             : import com.google.common.flogger.FluentLogger;
      21             : import com.google.gerrit.common.Nullable;
      22             : import com.google.gerrit.httpd.HtmlDomUtil;
      23             : import com.google.gerrit.server.config.GerritServerConfig;
      24             : import com.google.gerrit.server.config.SitePaths;
      25             : import com.google.inject.Inject;
      26             : import com.google.inject.Singleton;
      27             : import java.io.IOException;
      28             : import java.nio.file.Path;
      29             : import org.eclipse.jgit.lib.Config;
      30             : import org.w3c.dom.Document;
      31             : import org.w3c.dom.Element;
      32             : 
      33             : @Singleton
      34             : public class SiteHeaderFooter {
      35          99 :   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
      36             : 
      37             :   private final boolean refreshHeaderFooter;
      38             :   private final SitePaths sitePaths;
      39             :   private volatile Template template;
      40             : 
      41             :   @Inject
      42          99 :   SiteHeaderFooter(@GerritServerConfig Config cfg, SitePaths sitePaths) {
      43          99 :     this.refreshHeaderFooter = cfg.getBoolean("site", "refreshHeaderFooter", true);
      44          99 :     this.sitePaths = sitePaths;
      45             : 
      46             :     try {
      47          99 :       Template t = new Template(sitePaths);
      48          99 :       t.load();
      49          99 :       template = t;
      50           0 :     } catch (IOException e) {
      51           0 :       logger.atWarning().withCause(e).log("Cannot load site header or footer");
      52          99 :     }
      53          99 :   }
      54             : 
      55             :   public Document parse(Class<?> clazz, String name) throws IOException {
      56           0 :     Template t = template;
      57           0 :     if (refreshHeaderFooter && t.isStale()) {
      58           0 :       t = new Template(sitePaths);
      59             :       try {
      60           0 :         t.load();
      61           0 :         template = t;
      62           0 :       } catch (IOException e) {
      63           0 :         logger.atWarning().withCause(e).log("Cannot refresh site header or footer");
      64           0 :         t = template;
      65           0 :       }
      66             :     }
      67             : 
      68           0 :     Document doc = HtmlDomUtil.parseFile(clazz, name);
      69           0 :     injectCss(doc, "gerrit_sitecss", t.css);
      70           0 :     injectXml(doc, "gerrit_header", t.header);
      71           0 :     injectXml(doc, "gerrit_footer", t.footer);
      72           0 :     return doc;
      73             :   }
      74             : 
      75             :   private void injectCss(Document doc, String id, String content) {
      76           0 :     Element e = HtmlDomUtil.find(doc, id);
      77           0 :     if (e != null) {
      78           0 :       if (!Strings.isNullOrEmpty(content)) {
      79           0 :         while (e.getFirstChild() != null) {
      80           0 :           e.removeChild(e.getFirstChild());
      81             :         }
      82           0 :         e.removeAttribute("id");
      83           0 :         e.appendChild(doc.createCDATASection("\n" + content + "\n"));
      84             :       } else {
      85           0 :         e.getParentNode().removeChild(e);
      86             :       }
      87             :     }
      88           0 :   }
      89             : 
      90             :   private void injectXml(Document doc, String id, Element d) {
      91           0 :     Element e = HtmlDomUtil.find(doc, id);
      92           0 :     if (e != null) {
      93           0 :       if (d != null) {
      94           0 :         while (e.getFirstChild() != null) {
      95           0 :           e.removeChild(e.getFirstChild());
      96             :         }
      97           0 :         e.appendChild(doc.importNode(d, true));
      98             :       } else {
      99           0 :         e.getParentNode().removeChild(e);
     100             :       }
     101             :     }
     102           0 :   }
     103             : 
     104             :   private static class Template {
     105             :     private final FileInfo cssFile;
     106             :     private final FileInfo headerFile;
     107             :     private final FileInfo footerFile;
     108             : 
     109             :     String css;
     110             :     Element header;
     111             :     Element footer;
     112             : 
     113          99 :     Template(SitePaths site) {
     114          99 :       cssFile = new FileInfo(site.site_css);
     115          99 :       headerFile = new FileInfo(site.site_header);
     116          99 :       footerFile = new FileInfo(site.site_footer);
     117          99 :     }
     118             : 
     119             :     void load() throws IOException {
     120          99 :       css = HtmlDomUtil.readFile(cssFile.path.getParent(), cssFile.path.getFileName().toString());
     121          99 :       header = readXml(headerFile);
     122          99 :       footer = readXml(footerFile);
     123          99 :     }
     124             : 
     125             :     boolean isStale() {
     126           0 :       return cssFile.isStale() || headerFile.isStale() || footerFile.isStale();
     127             :     }
     128             : 
     129             :     @Nullable
     130             :     private static Element readXml(FileInfo src) throws IOException {
     131          99 :       Document d = HtmlDomUtil.parseFile(src.path);
     132          99 :       return d != null ? d.getDocumentElement() : null;
     133             :     }
     134             :   }
     135             : 
     136             :   private static class FileInfo {
     137             :     final Path path;
     138             :     final long time;
     139             : 
     140          99 :     FileInfo(Path p) {
     141          99 :       path = p;
     142          99 :       time = lastModified(p);
     143          99 :     }
     144             : 
     145             :     boolean isStale() {
     146           0 :       return time != lastModified(path);
     147             :     }
     148             :   }
     149             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750