• 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 package com.google.clearsilver.jsilver.precompiler;
18 
19 import com.google.clearsilver.jsilver.autoescape.EscapeMode;
20 import com.google.clearsilver.jsilver.exceptions.JSilverAutoEscapingException;
21 import com.google.common.annotations.VisibleForTesting;
22 import com.google.common.collect.ImmutableMap;
23 
24 import java.io.FileNotFoundException;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.InputStreamReader;
28 import java.io.LineNumberReader;
29 import java.io.Reader;
30 import java.util.HashMap;
31 import java.util.Map;
32 import java.util.StringTokenizer;
33 
34 /**
35  * Utility class that reads in the file output by BatchCompiler that is a list of template names and
36  * corresponding class names and returns a Map of template filenames to class names which can be fed
37  * to {@see com.google.clearsilver.jsilver.JSilverOptions#setPrecompiledTemplateMap}
38  */
39 public class PrecompiledTemplateMapFileReader {
40 
41   private final String mapFileName;
42   private final String dirPattern;
43   private final String rootDir;
44 
45   private Map<Object, String> templateMap = null;
46 
47   /**
48    * Helper object that reads in the specified resource file and generates a mapping of template
49    * filenames to corresponding BaseCompiledTemplate class names.
50    *
51    * @param filename name of the resource file to read the map from.
52    * @param dirPattern prefix to remove from read in template names. Used in conjunction with
53    *        rootDir to update template file paths.
54    * @param rootDir optional string to prepend to all non-absolute template filenames. Should be set
55    *        to the location of the templates in production via a flag.
56    */
PrecompiledTemplateMapFileReader(String filename, String dirPattern, String rootDir)57   public PrecompiledTemplateMapFileReader(String filename, String dirPattern, String rootDir) {
58     this.mapFileName = filename;
59     this.dirPattern = dirPattern;
60     this.rootDir = rootDir;
61   }
62 
getTemplateMap()63   public Map<Object, String> getTemplateMap() throws IOException {
64     if (templateMap == null) {
65       templateMap = makeTemplateMap(mapFileName, rootDir);
66     }
67     return templateMap;
68   }
69 
makeTemplateMap(String templateMapFile, String rootDir)70   private Map<Object, String> makeTemplateMap(String templateMapFile, String rootDir)
71       throws IOException {
72     Map<Object, String> templateMap = new HashMap<Object, String>();
73     LineNumberReader reader = null;
74     try {
75       reader = new LineNumberReader(getMapFileReader(templateMapFile));
76       for (String line = reader.readLine(); line != null; line = reader.readLine()) {
77         // Process single line from the templateMapFile
78         // and put found templates into templateMap.
79         processTemplateMapFileLine(line, reader.getLineNumber(), templateMap, templateMapFile,
80             rootDir);
81       }
82     } finally {
83       if (reader != null) {
84         reader.close();
85       }
86     }
87     return ImmutableMap.copyOf(templateMap);
88   }
89 
processTemplateMapFileLine(String line, int lineNumber, Map<Object, String> templateMap, String templateMapFile, String rootDir)90   private void processTemplateMapFileLine(String line, int lineNumber,
91       Map<Object, String> templateMap, String templateMapFile, String rootDir) {
92 
93     line = line.trim();
94     if (line.isEmpty() || line.startsWith("#")) {
95       // Ignore blank lines and comment lines.
96       return;
97     }
98     StringTokenizer st = new StringTokenizer(line);
99     if (!st.hasMoreTokens()) {
100       throw new IllegalArgumentException("No template file name found in " + templateMapFile
101           + " on line " + lineNumber + ": " + line);
102     }
103     String templateName = st.nextToken();
104     if (dirPattern != null && templateName.startsWith(dirPattern)) {
105       templateName = templateName.substring(dirPattern.length());
106     }
107     if (rootDir != null) {
108       // If it is not an absolute path and we were given a root directory,
109       // prepend it.
110       templateName = rootDir + templateName;
111     }
112     if (!st.hasMoreTokens()) {
113       throw new IllegalArgumentException("No class name found in " + templateMapFile + " on line "
114           + lineNumber + ": " + line);
115     }
116     String className = st.nextToken();
117     EscapeMode escapeMode;
118     if (!st.hasMoreTokens()) {
119       escapeMode = EscapeMode.ESCAPE_NONE;
120     } else {
121       String escapeCmd = st.nextToken();
122       try {
123         escapeMode = EscapeMode.computeEscapeMode(escapeCmd);
124       } catch (JSilverAutoEscapingException e) {
125         throw new IllegalArgumentException("Invalid escape mode found in " + templateMapFile
126             + " on line " + lineNumber + ": " + escapeCmd);
127       }
128     }
129     PrecompiledTemplateMapKey key = new PrecompiledTemplateMapKey(templateName, escapeMode);
130     templateMap.put(key, className);
131   }
132 
133   @VisibleForTesting
getMapFileReader(String templateMapFile)134   protected Reader getMapFileReader(String templateMapFile) throws IOException {
135     ClassLoader classLoader = getClass().getClassLoader();
136     InputStream in = classLoader.getResourceAsStream(templateMapFile);
137     if (in == null) {
138       throw new FileNotFoundException("Unable to locate resource: " + templateMapFile);
139     }
140     return new InputStreamReader(in, "UTF-8");
141   }
142 
143 }
144