• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
readFile(String filename)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 
getPathRoot(String filename)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 
getPageMetadata(String docfile, Data hdf)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 
writePage(String docfile, String relative, String outfile, Data hdf)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