• 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", "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       if (Doclava.USE_UPDATED_TEMPLATES) {
194         //remap types to design, dev, distribute etc.
195         if (filename.indexOf("design") == 0) {
196           hdf.setValue("design", "true");
197           hdf.setValue("page.type", "design");
198           hdf.setValue("page.category", "design");
199         } else if (filename.indexOf("develop") == 0) {
200           hdf.setValue("develop", "true");
201           hdf.setValue("page.type", "develop");
202           hdf.setValue("page.category", "develop");
203         } else if (filename.indexOf("guide") == 0) {
204           hdf.setValue("guide", "true");
205           hdf.setValue("page.type", "develop");
206           if (filename.indexOf("guide/topics/manif") == 0) {
207             hdf.setValue("page.category", "app manifest");
208           } else {
209             hdf.setValue("page.category", "guide");
210           }
211         } else if (filename.indexOf("training") == 0) {
212           hdf.setValue("training", "true");
213           hdf.setValue("page.type", "develop");
214           hdf.setValue("page.category", "training");
215         } else if (filename.indexOf("more") == 0) {
216           hdf.setValue("more", "true");
217         } else if (filename.indexOf("google") == 0) {
218           hdf.setValue("google", "true");
219           hdf.setValue("page.type", "develop");
220           hdf.setValue("page.category", "google");
221         } else if (filename.indexOf("samples") == 0) {
222           hdf.setValue("samples", "true");
223           hdf.setValue("samplesDocPage", "true");
224           hdf.setValue("page.type", "develop");
225           hdf.setValue("page.category", "samples");
226           if (Doclava.samplesNavTree != null) {
227             hdf.setValue("samples_toc_tree", Doclava.samplesNavTree.getValue("samples_toc_tree", ""));
228           }
229         } else if (filename.indexOf("topic/") == 0) {
230           hdf.setValue("topic", "true");
231           hdf.setValue("page.type", "develop");
232           if (filename.indexOf("topic/libraries") == 0) {
233             hdf.setValue("page.category", "libraries");
234             hdf.setValue("page.type", "develop");
235             hdf.setValue("libraries", "true");
236           } else if (filename.indexOf("topic/instant-apps") == 0) {
237             hdf.setValue("instantapps", "true");
238             hdf.setValue("page.type", "develop");
239             hdf.setValue("page.category", "instant apps");
240           } else if (filename.indexOf("topic/performance") == 0) {
241             hdf.setValue("perf", "true");
242             hdf.setValue("page.type", "develop");
243             hdf.setValue("page.category", "performance");
244           } else if (filename.indexOf("topic/arc") == 0) {
245             hdf.setValue("arc", "true");
246             hdf.setValue("page.type", "develop");
247             hdf.setValue("page.category", "arc");
248           }
249         } else if (filename.indexOf("distribute") == 0) {
250           hdf.setValue("distribute", "true");
251           hdf.setValue("page.type", "distribute");
252           hdf.setValue("page.category", "distribute");
253           if (filename.indexOf("distribute/googleplay") == 0) {
254             hdf.setValue("page.category", "googleplay");
255             hdf.setValue("page.type", "distribute");
256             hdf.setValue("googleplay", "true");
257           } else if (filename.indexOf("distribute/essentials") == 0) {
258             hdf.setValue("page.category", "essentials");
259             hdf.setValue("essentials", "true");
260           } else if (filename.indexOf("distribute/users") == 0) {
261             hdf.setValue("page.category", "users");
262             hdf.setValue("users", "true");
263           } else if (filename.indexOf("distribute/engage") == 0) {
264             hdf.setValue("page.category", "engage");
265             hdf.setValue("engage", "true");
266           } else if (filename.indexOf("distribute/monetize") == 0) {
267             hdf.setValue("page.category", "monetize");
268             hdf.setValue("monetize", "true");
269           } else if (filename.indexOf("distribute/analyze") == 0) {
270             hdf.setValue("page.category", "analyze");
271             hdf.setValue("analyze", "true");
272           } else if (filename.indexOf("distribute/tools") == 0) {
273             hdf.setValue("page.category", "essentials");
274             hdf.setValue("essentials", "true");
275           } else if (filename.indexOf("distribute/stories") == 0) {
276             hdf.setValue("page.category", "stories");
277             hdf.setValue("stories", "true");
278           }
279         } else if (filename.indexOf("about") == 0) {
280           hdf.setValue("about", "true");
281           hdf.setValue("page.type", "about");
282           hdf.setValue("page.category", "about");
283           if ((filename.indexOf("about/versions") == 0)) {
284             hdf.setValue("versions", "true");
285             hdf.setValue("page.category", "versions");
286           //todo remove this because there's no file at this location
287           } else if ((filename.indexOf("wear") == 0)) {
288             hdf.setValue("wear", "true");
289             hdf.setValue("page.category", "wear");
290           } else if ((filename.indexOf("tv") == 0)) {
291             hdf.setValue("tv", "true");
292             hdf.setValue("page.category", "tv");
293           } else if ((filename.indexOf("auto") == 0)) {
294             hdf.setValue("auto", "true");
295             hdf.setValue("page.category", "auto");
296           }
297         } else if (filename.indexOf("wear/preview") == 0) {
298           hdf.setValue("wearpreview", "true");
299           hdf.setValue("page.type", "about");
300           hdf.setValue("page.category", "wear preview");
301         } else if (filename.indexOf("devices") == 0) {
302           hdf.setValue("devices", "true");
303           hdf.setValue("page.type", "devices");
304         } else if (filename.indexOf("source") == 0) {
305           hdf.setValue("source", "true");
306         } else if (filename.indexOf("security") == 0) {
307           hdf.setValue("security", "true");
308         } else if (filename.indexOf("compatibility") == 0) {
309           hdf.setValue("compatibility", "true");
310         } else if (filename.indexOf("wear") == 0) {
311           hdf.setValue("wear", "true");
312           hdf.setValue("about", "true");
313           hdf.setValue("page.type", "about");
314           hdf.setValue("page.category", "wear");
315         } else if (filename.indexOf("work") == 0) {
316           hdf.setValue("work", "true");
317           hdf.setValue("page.type", "about");
318           hdf.setValue("page.category", "work");
319         } else if (filename.indexOf("preview") == 0) {
320           hdf.setValue("page.type", "develop");
321           hdf.setValue("page.category", "preview");
322           hdf.setValue("preview", "true");
323         } else if (filename.indexOf("auto") == 0) {
324           hdf.setValue("auto", "true");
325           hdf.setValue("about", "true");
326           hdf.setValue("page.type", "about");
327           hdf.setValue("page.category", "auto");
328         } else if (filename.indexOf("tv") == 0) {
329           hdf.setValue("tv", "true");
330           hdf.setValue("about", "true");
331           hdf.setValue("page.type", "about");
332           hdf.setValue("page.category", "tv");
333         }
334       } else {
335         //support the old mappings
336         if (filename.indexOf("design") == 0) {
337           hdf.setValue("design", "true");
338           hdf.setValue("page.type", "design");
339         } else if (filename.indexOf("develop") == 0) {
340           hdf.setValue("develop", "true");
341           hdf.setValue("page.type", "develop");
342         } else if (filename.indexOf("guide") == 0) {
343           hdf.setValue("guide", "true");
344           hdf.setValue("page.type", "guide");
345         } else if (filename.indexOf("training") == 0) {
346           hdf.setValue("training", "true");
347           hdf.setValue("page.type", "training");
348         } else if (filename.indexOf("more") == 0) {
349           hdf.setValue("more", "true");
350         } else if (filename.indexOf("google") == 0) {
351           hdf.setValue("google", "true");
352           hdf.setValue("page.type", "google");
353         } else if (filename.indexOf("samples") == 0) {
354           hdf.setValue("samples", "true");
355           hdf.setValue("samplesDocPage", "true");
356           hdf.setValue("page.type", "samples");
357           if (Doclava.samplesNavTree != null) {
358             hdf.setValue("samples_toc_tree", Doclava.samplesNavTree.getValue("samples_toc_tree", ""));
359           }
360         } else if (filename.indexOf("distribute") == 0) {
361           hdf.setValue("distribute", "true");
362           hdf.setValue("page.type", "distribute");
363           if (filename.indexOf("distribute/googleplay") == 0) {
364             hdf.setValue("googleplay", "true");
365           } else if (filename.indexOf("distribute/essentials") == 0) {
366             hdf.setValue("essentials", "true");
367           } else if (filename.indexOf("distribute/users") == 0) {
368             hdf.setValue("users", "true");
369           } else if (filename.indexOf("distribute/engage") == 0) {
370             hdf.setValue("engage", "true");
371           } else if (filename.indexOf("distribute/monetize") == 0) {
372             hdf.setValue("monetize", "true");
373           } else if (filename.indexOf("distribute/analyze") == 0) {
374             hdf.setValue("analyze", "true");
375           } else if (filename.indexOf("distribute/tools") == 0) {
376             hdf.setValue("essentials", "true");
377           } else if (filename.indexOf("distribute/stories") == 0) {
378             hdf.setValue("stories", "true");
379           }
380         } else if (filename.indexOf("about") == 0) {
381           hdf.setValue("about", "true");
382           hdf.setValue("page.type", "about");
383         } else if (filename.indexOf("devices") == 0) {
384           hdf.setValue("devices", "true");
385           hdf.setValue("page.type", "devices");
386         } else if (filename.indexOf("source") == 0) {
387           hdf.setValue("source", "true");
388         } else if (filename.indexOf("security") == 0) {
389           hdf.setValue("security", "true");
390         } else if (filename.indexOf("compatibility") == 0) {
391           hdf.setValue("compatibility", "true");
392         } else if (filename.indexOf("topic/") == 0) {
393           hdf.setValue("topic", "true");
394           hdf.setValue("page.type", "develop");
395           if (filename.indexOf("topic/libraries") == 0) {
396             hdf.setValue("page.category", "libraries");
397             hdf.setValue("page.type", "develop");
398             hdf.setValue("libraries", "true");
399           } else if (filename.indexOf("topic/instant-apps") == 0) {
400             hdf.setValue("instantapps", "true");
401             hdf.setValue("page.type", "develop");
402             hdf.setValue("page.category", "instant apps");
403           } else if (filename.indexOf("topic/performance") == 0) {
404             hdf.setValue("perf", "true");
405             hdf.setValue("page.type", "develop");
406             hdf.setValue("page.category", "performance");
407           } else if (filename.indexOf("topic/arc") == 0) {
408             hdf.setValue("arc", "true");
409             hdf.setValue("page.type", "develop");
410             hdf.setValue("page.category", "arc");
411           }
412         } else if (filename.indexOf("wear/preview") == 0) {
413           hdf.setValue("wearpreview", "true");
414           hdf.setValue("page.type", "about");
415           hdf.setValue("page.category", "wear preview");
416         } else if (filename.indexOf("wear") == 0) {
417           hdf.setValue("wear", "true");
418         } else if (filename.indexOf("work") == 0) {
419           hdf.setValue("work", "true");
420           hdf.setValue("page.type", "about");
421           hdf.setValue("page.category", "work");
422         } else if (filename.indexOf("preview") == 0) {
423           hdf.setValue("page.type", "preview");
424           hdf.setValue("page.category", "preview");
425           hdf.setValue("preview", "true");
426         } else if (filename.indexOf("auto") == 0) {
427           hdf.setValue("auto", "true");
428         } else if (filename.indexOf("tv") == 0) {
429           hdf.setValue("tv", "true");
430         }
431       }
432       //set metadata for this file in jd_lists_unified
433       PageMetadata.setPageMetadata(docfile, relative, outfile, hdf, Doclava.sTaglist);
434 
435       //for devsite builds, remove 'intl/' from output paths for localized files
436       if (Doclava.USE_DEVSITE_LOCALE_OUTPUT_PATHS) {
437         outfile = outfile.replaceFirst("^intl/", "");
438       }
439 
440       ClearPage.write(hdf, "docpage.cs", outfile);
441     }
442   } // writePage
443 }
444