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