001
014
015 package com.liferay.portal.tools.propertiesdoc;
016
017 import com.liferay.portal.freemarker.FreeMarkerUtil;
018 import com.liferay.portal.kernel.util.CharPool;
019 import com.liferay.portal.kernel.util.GetterUtil;
020 import com.liferay.portal.kernel.util.StringBundler;
021 import com.liferay.portal.kernel.util.StringPool;
022 import com.liferay.portal.kernel.util.StringUtil;
023 import com.liferay.portal.kernel.util.Validator;
024 import com.liferay.portal.tools.ArgumentsUtil;
025 import com.liferay.portal.util.FileImpl;
026
027 import java.io.File;
028 import java.io.FileWriter;
029 import java.io.IOException;
030 import java.io.Writer;
031
032 import java.util.ArrayList;
033 import java.util.HashMap;
034 import java.util.List;
035 import java.util.Map;
036
037
041 public class PropertiesDocBuilder {
042
043 public static void main(String[] args) throws Exception {
044 Map<String, String> arguments = ArgumentsUtil.parseArguments(args);
045
046 try {
047 new PropertiesDocBuilder(arguments);
048 }
049 catch (Exception e) {
050 ArgumentsUtil.processMainException(arguments, e);
051 }
052 }
053
054 public PropertiesDocBuilder(Map<String, String> arguments)
055 throws IOException {
056
057 String propertiesDestDirName = GetterUtil.getString(
058 arguments.get("properties.dest.dir"));
059 String propertiesFileName = GetterUtil.getString(
060 arguments.get("properties.file"));
061 String title = GetterUtil.getString(arguments.get("properties.title"));
062 boolean toc = GetterUtil.getBoolean(arguments.get("properties.toc"));
063
064 System.out.println("Converting " + propertiesFileName + " to HTML");
065
066 File propertiesFile = new File(propertiesFileName);
067
068 Map<String, Object> context = new HashMap<>();
069
070 context.put("pageTitle", title);
071
072 int pos = propertiesFileName.lastIndexOf(StringPool.SLASH);
073
074 if (pos != -1) {
075 propertiesFileName = propertiesFileName.substring(pos + 1);
076 }
077
078 context.put("propertiesFileName", propertiesFileName);
079
080 List<PropertiesSection> propertiesSections = getPropertiesSections(
081 propertiesFile);
082
083 if (propertiesSections == null) {
084 return;
085 }
086
087 context.put("sections", propertiesSections);
088
089 context.put("toc", toc);
090
091 try {
092 StringBundler sb = new StringBundler(4);
093
094 sb.append(propertiesDestDirName);
095 sb.append(StringPool.SLASH);
096 sb.append(propertiesFileName);
097 sb.append(".html");
098
099 String propertiesHTMLFileName = sb.toString();
100
101 File propertiesHTMLFile = new File(propertiesHTMLFileName);
102
103 System.out.println("Writing " + propertiesHTMLFile);
104
105 Writer writer = new FileWriter(propertiesHTMLFile);
106
107 try {
108 FreeMarkerUtil.process(
109 "com/liferay/portal/tools/propertiesdoc/dependencies/" +
110 "properties.ftl",
111 context, writer);
112 }
113 catch (Exception e) {
114 e.printStackTrace();
115 }
116
117 writer.flush();
118 }
119 catch (IOException ioe) {
120 ioe.printStackTrace();
121 }
122 }
123
124 protected void addPropertyComment(
125 List<PropertyComment> propertyComments, String comment) {
126
127 if (Validator.isNotNull(comment)) {
128 PropertyComment propertyComment = new PropertyComment(comment);
129
130 propertyComments.add(propertyComment);
131 }
132 }
133
134 protected List<String> extractComments(String[] lines) {
135 List<String> comments = new ArrayList<>();
136
137 StringBundler sb = new StringBundler();
138
139 for (String line : lines) {
140 String trimmedLine = line.trim();
141
142 if (trimmedLine.startsWith("## ")) {
143 trimmedLine = trimmedLine.substring(2);
144
145 sb.append(trimmedLine.trim());
146 }
147
148 if (trimmedLine.length() < 3) {
149 if (sb.index() == 0) {
150 continue;
151 }
152
153 comments.add(sb.toString());
154
155 sb = new StringBundler();
156 }
157 }
158
159 return comments;
160 }
161
162 protected String extractDefaultProperties(String[] lines) {
163 StringBundler sb = new StringBundler();
164
165 boolean previousLineIsDefaultProperty = false;
166
167 for (String line : lines) {
168 if (!previousLineIsDefaultProperty) {
169 if (!line.startsWith("#") && !line.startsWith(INDENT + "#")) {
170 previousLineIsDefaultProperty = true;
171
172 sb.append(line);
173 sb.append(StringPool.NEW_LINE);
174 }
175 }
176 else {
177 if (line.startsWith("#") || line.startsWith(INDENT + "#")) {
178 previousLineIsDefaultProperty = false;
179
180 continue;
181 }
182
183 sb.append(line);
184 sb.append(StringPool.NEW_LINE);
185 }
186 }
187
188 return sb.toString();
189 }
190
191 protected String extractExampleProperties(String[] lines) {
192 StringBundler sb = new StringBundler();
193
194 boolean previousLineIsExample = false;
195
196 for (String line : lines) {
197 String trimmedLine = line.trim();
198
199 if (!previousLineIsExample) {
200 if (line.startsWith(INDENT + "# ") || trimmedLine.equals("#")) {
201 continue;
202 }
203
204 if (line.startsWith(INDENT + "#")) {
205 previousLineIsExample = true;
206
207 String exampleProperty =
208 StringUtil.replaceFirst(line, "#", StringPool.BLANK) +
209 StringPool.NEW_LINE;
210
211 sb.append(exampleProperty);
212 }
213 }
214 else {
215 if (!trimmedLine.startsWith("#")) {
216 previousLineIsExample = false;
217
218 continue;
219 }
220
221 String exampleProperty =
222 line.replaceFirst("#", StringPool.BLANK) +
223 StringPool.NEW_LINE;
224
225 sb.append(exampleProperty);
226 }
227 }
228
229 return sb.toString();
230 }
231
232 protected List<PropertyComment> extractPropertyComments(String[] lines) {
233 List<PropertyComment> propertyComments = new ArrayList<>();
234
235 StringBundler sb = new StringBundler();
236
237 boolean previousLineIsPreformatted = false;
238
239 for (String line : lines) {
240 line = StringUtil.trimTrailing(line);
241
242 if (line.startsWith(DOUBLE_INDENT + "#")) {
243 break;
244 }
245
246 String trimmedLine = line.trim();
247
248 if (trimmedLine.startsWith("# " + INDENT)) {
249 if (previousLineIsPreformatted) {
250 sb.append(
251 StringUtil.replaceFirst(
252 trimmedLine, "#", StringPool.BLANK));
253 }
254 else {
255 addPropertyComment(propertyComments, sb.toString());
256
257 sb = new StringBundler();
258
259 sb.append(
260 StringUtil.replaceFirst(
261 trimmedLine, "#", StringPool.BLANK));
262 }
263
264 sb.append(StringPool.NEW_LINE);
265
266 previousLineIsPreformatted = true;
267 }
268 else if (trimmedLine.startsWith("# ")) {
269 if (previousLineIsPreformatted) {
270 addPropertyComment(propertyComments, sb.toString());
271
272 sb = new StringBundler();
273
274 trimmedLine = StringUtil.replaceFirst(
275 trimmedLine, "#", StringPool.BLANK);
276
277 sb.append(trimmedLine.trim());
278 }
279 else {
280 if (sb.length() > 0) {
281 sb.append(StringPool.SPACE);
282 }
283
284 line = StringUtil.replaceFirst(line, "#", StringPool.BLANK);
285
286 sb.append(line.trim());
287 }
288
289 sb.append(StringPool.NEW_LINE);
290
291 previousLineIsPreformatted = false;
292 }
293 else if (trimmedLine.startsWith("#") &&
294 (trimmedLine.length() < 2)) {
295
296 addPropertyComment(propertyComments, sb.toString());
297
298 sb = new StringBundler();
299 }
300 else {
301 addPropertyComment(propertyComments, sb.toString());
302
303 break;
304 }
305 }
306
307 return propertyComments;
308 }
309
310 protected String extractTitle(String[] lines) {
311 if ((lines == null) || (lines.length <= 1)) {
312 return null;
313 }
314
315 String title = lines[1];
316
317 title = StringUtil.replaceFirst(title, "##", StringPool.BLANK);
318
319 return title.trim();
320 }
321
322 protected int getLineCount(String sectionString) {
323 String[] lines = sectionString.split("\r\n|\r|\n");
324
325 return lines.length;
326 }
327
328 protected List<PropertiesSection> getPropertiesSections(File propertiesFile)
329 throws IOException {
330
331 String content = _fileUtil.read(propertiesFile);
332
333 String[] sections = content.split("\n\n");
334
335 List<PropertiesSection> propertiesSections = new ArrayList<>(
336 sections.length);
337
338 for (String section : sections) {
339 section = StringUtil.trimLeading(section, CharPool.SPACE);
340
341 PropertiesSection propertiesSection = new PropertiesSection(
342 section);
343
344 String[] lines = section.split(StringPool.NEW_LINE);
345
346 if (section.startsWith("##")) {
347 int lineCount = getLineCount(section);
348
349 if (lineCount == 3) {
350 propertiesSection.setTitle(extractTitle(lines));
351
352 propertiesSections.add(propertiesSection);
353 }
354 else if (lineCount > 3) {
355 propertiesSection.setComments(extractComments(lines));
356
357 propertiesSections.add(propertiesSection);
358 }
359 else {
360 StringBundler sb = new StringBundler(8);
361
362 sb.append("Properties section should consist of 3 ");
363 sb.append("or more lines:");
364 sb.append(StringPool.NEW_LINE);
365 sb.append("##");
366 sb.append(StringPool.NEW_LINE);
367 sb.append("## Comments");
368 sb.append(StringPool.NEW_LINE);
369 sb.append("##");
370
371 System.out.println(sb.toString());
372
373 return null;
374 }
375 }
376 else {
377 propertiesSection.setDefaultProperties(
378 extractDefaultProperties(lines));
379 propertiesSection.setExampleProperties(
380 extractExampleProperties(lines));
381 propertiesSection.setPropertyComments(
382 extractPropertyComments(lines));
383
384 propertiesSections.add(propertiesSection);
385 }
386 }
387
388 return propertiesSections;
389 }
390
391 protected static final String DOUBLE_INDENT =
392 PropertiesDocBuilder.INDENT + PropertiesDocBuilder.INDENT;
393
394 protected static final String INDENT = StringPool.FOUR_SPACES;
395
396 private static final FileImpl _fileUtil = FileImpl.getInstance();
397
398 }