Home | History | Annotate | Download | only in doclava
      1 /*
      2  * Copyright (C) 2010 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  *
     16  */
     17 
     18 package com.google.doclava;
     19 
     20 import com.google.clearsilver.jsilver.data.Data;
     21 
     22 import java.io.*;
     23 import java.util.regex.Pattern;
     24 import java.util.regex.Matcher;
     25 
     26 
     27 public class DocFile {
     28   public static final Pattern LINE = Pattern.compile("(.*)[\r]?\n", Pattern.MULTILINE);
     29   public static final Pattern PROP = Pattern.compile("([^=]+)=(.*)");
     30 
     31   public static String readFile(String filename) {
     32     try {
     33       File f = new File(filename);
     34       int length = (int) f.length();
     35       FileInputStream is = new FileInputStream(f);
     36       InputStreamReader reader = new InputStreamReader(is, "UTF-8");
     37       char[] buf = new char[length];
     38       int index = 0;
     39       int amt;
     40       while (true) {
     41         amt = reader.read(buf, index, length - index);
     42 
     43         if (amt < 1) {
     44           break;
     45         }
     46 
     47         index += amt;
     48       }
     49       return new String(buf, 0, index);
     50     } catch (IOException e) {
     51       return null;
     52     }
     53   }
     54 
     55   public static String[] DEVSITE_VALID_LANGS = {"en", "es", "id", "in", "ja", "ko",
     56       "ru", "vi", "zh-cn", "zh-tw", "pt-br"};
     57 
     58   public static String getPathRoot(String filename) {
     59     //look for a valid lang string in the file path. If found,
     60     //snip the intl/lang from the path.
     61     for (String t : DEVSITE_VALID_LANGS) {
     62       int langStart = filename.indexOf("/" + t + "/");
     63       if (langStart > -1) {
     64         int langEnd = filename.indexOf("/", langStart + 1);
     65         filename = filename.substring(langEnd + 1);
     66         break;
     67       }
     68     }
     69     return filename;
     70   }
     71 
     72   public static Data getPageMetadata (String docfile, Data hdf) {
     73     //utility method for extracting metadata without generating file output.
     74     if (hdf == null) {
     75       hdf = Doclava.makeHDF();
     76     }
     77     String filedata = readFile(docfile);
     78 
     79     // The document is properties up until the line "@jd:body".
     80     // Any blank lines are ignored.
     81     int start = -1;
     82     int lineno = 1;
     83     Matcher lines = LINE.matcher(filedata);
     84     String line = null;
     85     while (lines.find()) {
     86       line = lines.group(1);
     87       if (line.length() > 0) {
     88         if (line.equals("@jd:body")) {
     89           start = lines.end();
     90           break;
     91         }
     92         Matcher prop = PROP.matcher(line);
     93         if (prop.matches()) {
     94           String key = prop.group(1);
     95           String value = prop.group(2);
     96           hdf.setValue(key, value);
     97         } else {
     98           break;
     99         }
    100       }
    101       lineno++;
    102     }
    103     if (start < 0) {
    104       System.err.println(docfile + ":" + lineno + ": error parsing docfile");
    105       if (line != null) {
    106         System.err.println(docfile + ":" + lineno + ":" + line);
    107       }
    108       System.exit(1);
    109     }
    110     return hdf;
    111   }
    112 
    113   public static void writePage(String docfile, String relative, String outfile, Data hdf) {
    114 
    115     /*
    116      * System.out.println("docfile='" + docfile + "' relative='" + relative + "'" + "' outfile='" +
    117      * outfile + "'");
    118      */
    119     if (hdf == null) {
    120       hdf = Doclava.makeHDF();
    121     }
    122     String filedata = readFile(docfile);
    123 
    124     // The document is properties up until the line "@jd:body".
    125     // Any blank lines are ignored.
    126     int start = -1;
    127     int lineno = 1;
    128     Matcher lines = LINE.matcher(filedata);
    129     String line = null;
    130     while (lines.find()) {
    131       line = lines.group(1);
    132       if (line.length() > 0) {
    133         if (line.equals("@jd:body")) {
    134           start = lines.end();
    135           break;
    136         }
    137         Matcher prop = PROP.matcher(line);
    138         if (prop.matches()) {
    139           String key = prop.group(1);
    140           String value = prop.group(2);
    141           hdf.setValue(key, value);
    142         } else {
    143           break;
    144         }
    145       }
    146       lineno++;
    147     }
    148     if (start < 0) {
    149       System.err.println(docfile + ":" + lineno + ": error parsing docfile");
    150       if (line != null) {
    151         System.err.println(docfile + ":" + lineno + ":" + line);
    152       }
    153       System.exit(1);
    154     }
    155 
    156     // if they asked to only be for a certain template, maybe skip it
    157     String fromTemplate = hdf.getValue("template.which", "");
    158     String fromPage = hdf.getValue("page.onlyfortemplate", "");
    159     if (!"".equals(fromPage) && !fromTemplate.equals(fromPage)) {
    160       return;
    161     }
    162 
    163     // and the actual text after that
    164     String commentText = filedata.substring(start);
    165 
    166     Comment comment = new Comment(commentText, null, new SourcePositionInfo(docfile, lineno, 1));
    167     TagInfo[] tags = comment.tags();
    168 
    169     TagInfo.makeHDF(hdf, "root.descr", tags);
    170 
    171     hdf.setValue("commentText", commentText);
    172 
    173     // write the page using the appropriate root template, based on the
    174     // whichdoc value supplied by build
    175     String fromWhichmodule = hdf.getValue("android.whichmodule", "");
    176     if (fromWhichmodule.equals("online-pdk")) {
    177       // leaving this in just for temporary compatibility with pdk doc
    178       hdf.setValue("online-pdk", "true");
    179       // add any conditional login for root template here (such as
    180       // for custom left nav based on tab etc.
    181       ClearPage.write(hdf, "docpage.cs", outfile);
    182     } else {
    183       String filename = outfile;
    184       // Special case handling of samples files for devsite
    185       // locale handling -- strip out the en/ root
    186       if (Doclava.USE_DEVSITE_LOCALE_OUTPUT_PATHS) {
    187         filename = filename.replaceFirst("^en/", "");
    188       }
    189       // Strip out the intl and lang id substr and get back just the
    190       // guide, design, distribute, etc.
    191       filename = getPathRoot(filename);
    192 
    193       // map types to design, dev, distribute etc.
    194       if (filename.indexOf("design") == 0) {
    195         hdf.setValue("design", "true");
    196         hdf.setValue("page.type", "design");
    197         hdf.setValue("page.category", "design");
    198       } else if (filename.indexOf("develop") == 0) {
    199         hdf.setValue("develop", "true");
    200         hdf.setValue("page.type", "develop");
    201         hdf.setValue("page.category", "develop");
    202       } else if (filename.indexOf("guide") == 0) {
    203         hdf.setValue("guide", "true");
    204         hdf.setValue("page.type", "develop");
    205         if (filename.indexOf("guide/topics/manif") == 0) {
    206           hdf.setValue("page.category", "app manifest");
    207         } else {
    208           hdf.setValue("page.category", "guide");
    209         }
    210       } else if (filename.indexOf("training") == 0) {
    211         hdf.setValue("training", "true");
    212         hdf.setValue("page.type", "develop");
    213         hdf.setValue("page.category", "training");
    214       } else if (filename.indexOf("more") == 0) {
    215         hdf.setValue("more", "true");
    216       } else if (filename.indexOf("google") == 0) {
    217         hdf.setValue("google", "true");
    218         hdf.setValue("page.type", "develop");
    219         hdf.setValue("page.category", "google");
    220       } else if (filename.indexOf("samples") == 0) {
    221         hdf.setValue("samples", "true");
    222         hdf.setValue("samplesDocPage", "true");
    223         hdf.setValue("page.type", "develop");
    224         hdf.setValue("page.category", "samples");
    225         if (Doclava.samplesNavTree != null) {
    226           hdf.setValue("samples_toc_tree", Doclava.samplesNavTree.getValue("samples_toc_tree", ""));
    227         }
    228       } else if (filename.indexOf("topic/") == 0) {
    229         hdf.setValue("topic", "true");
    230         hdf.setValue("page.type", "develop");
    231         if (filename.indexOf("topic/libraries") == 0) {
    232           hdf.setValue("page.category", "libraries");
    233           hdf.setValue("page.type", "develop");
    234           hdf.setValue("libraries", "true");
    235         } else if (filename.indexOf("topic/instant-apps") == 0) {
    236           hdf.setValue("instantapps", "true");
    237           hdf.setValue("page.type", "develop");
    238           hdf.setValue("page.category", "instant apps");
    239         } else if (filename.indexOf("topic/performance") == 0) {
    240           hdf.setValue("perf", "true");
    241           hdf.setValue("page.type", "develop");
    242           hdf.setValue("page.category", "performance");
    243         } else if (filename.indexOf("topic/arc") == 0) {
    244           hdf.setValue("arc", "true");
    245           hdf.setValue("page.type", "develop");
    246           hdf.setValue("page.category", "arc");
    247         }
    248       } else if (filename.indexOf("distribute") == 0) {
    249         hdf.setValue("distribute", "true");
    250         hdf.setValue("page.type", "distribute");
    251         hdf.setValue("page.category", "distribute");
    252         if (filename.indexOf("distribute/googleplay") == 0) {
    253           hdf.setValue("page.category", "googleplay");
    254           hdf.setValue("page.type", "distribute");
    255           hdf.setValue("googleplay", "true");
    256         } else if (filename.indexOf("distribute/essentials") == 0) {
    257           hdf.setValue("page.category", "essentials");
    258           hdf.setValue("essentials", "true");
    259         } else if (filename.indexOf("distribute/users") == 0) {
    260           hdf.setValue("page.category", "users");
    261           hdf.setValue("users", "true");
    262         } else if (filename.indexOf("distribute/engage") == 0) {
    263           hdf.setValue("page.category", "engage");
    264           hdf.setValue("engage", "true");
    265         } else if (filename.indexOf("distribute/monetize") == 0) {
    266           hdf.setValue("page.category", "monetize");
    267           hdf.setValue("monetize", "true");
    268         } else if (filename.indexOf("distribute/analyze") == 0) {
    269           hdf.setValue("page.category", "analyze");
    270           hdf.setValue("analyze", "true");
    271         } else if (filename.indexOf("distribute/tools") == 0) {
    272           hdf.setValue("page.category", "essentials");
    273           hdf.setValue("essentials", "true");
    274         } else if (filename.indexOf("distribute/stories") == 0) {
    275           hdf.setValue("page.category", "stories");
    276           hdf.setValue("stories", "true");
    277         }
    278       } else if (filename.indexOf("about") == 0) {
    279         hdf.setValue("about", "true");
    280         hdf.setValue("page.type", "about");
    281         hdf.setValue("page.category", "about");
    282         if ((filename.indexOf("about/versions") == 0)) {
    283           hdf.setValue("versions", "true");
    284           hdf.setValue("page.category", "versions");
    285         //todo remove this because there's no file at this location
    286         } else if ((filename.indexOf("wear") == 0)) {
    287           hdf.setValue("wear", "true");
    288           hdf.setValue("page.category", "wear");
    289         } else if ((filename.indexOf("tv") == 0)) {
    290           hdf.setValue("tv", "true");
    291           hdf.setValue("page.category", "tv");
    292         } else if ((filename.indexOf("auto") == 0)) {
    293           hdf.setValue("auto", "true");
    294           hdf.setValue("page.category", "auto");
    295         }
    296       } else if (filename.indexOf("wear/preview") == 0) {
    297         hdf.setValue("wearpreview", "true");
    298         hdf.setValue("page.type", "about");
    299         hdf.setValue("page.category", "wear preview");
    300       } else if (filename.indexOf("devices") == 0) {
    301         hdf.setValue("devices", "true");
    302         hdf.setValue("page.type", "devices");
    303       } else if (filename.indexOf("source") == 0) {
    304         hdf.setValue("source", "true");
    305       } else if (filename.indexOf("security") == 0) {
    306         hdf.setValue("security", "true");
    307       } else if (filename.indexOf("compatibility") == 0) {
    308         hdf.setValue("compatibility", "true");
    309       } else if (filename.indexOf("wear") == 0) {
    310         hdf.setValue("wear", "true");
    311         hdf.setValue("about", "true");
    312         hdf.setValue("page.type", "about");
    313         hdf.setValue("page.category", "wear");
    314       } else if (filename.indexOf("work") == 0) {
    315         hdf.setValue("work", "true");
    316         hdf.setValue("page.type", "about");
    317         hdf.setValue("page.category", "work");
    318       } else if (filename.indexOf("preview") == 0) {
    319         hdf.setValue("page.type", "develop");
    320         hdf.setValue("page.category", "preview");
    321         hdf.setValue("preview", "true");
    322       } else if (filename.indexOf("auto") == 0) {
    323         hdf.setValue("auto", "true");
    324         hdf.setValue("about", "true");
    325         hdf.setValue("page.type", "about");
    326         hdf.setValue("page.category", "auto");
    327       } else if (filename.indexOf("tv") == 0) {
    328         hdf.setValue("tv", "true");
    329         hdf.setValue("about", "true");
    330         hdf.setValue("page.type", "about");
    331         hdf.setValue("page.category", "tv");
    332       } else {
    333         hdf.setValue("about", "true");
    334         hdf.setValue("page.type", "about");
    335         hdf.setValue("page.category", "about");
    336       }
    337 
    338       //set metadata for this file in jd_lists_unified
    339       PageMetadata.setPageMetadata(docfile, relative, outfile, hdf, Doclava.sTaglist);
    340 
    341       //for devsite builds, remove 'intl/' from output paths for localized files
    342       if (Doclava.USE_DEVSITE_LOCALE_OUTPUT_PATHS) {
    343         outfile = outfile.replaceFirst("^intl/", "");
    344       }
    345 
    346       ClearPage.write(hdf, "docpage.cs", outfile);
    347     }
    348   } // writePage
    349 }
    350