1 /* 
2  * Copyright 2005 Paul Hinds
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 */
16package org.tp23.antinstaller;
17
18import java.io.BufferedWriter;
19import java.io.File;
20import java.io.FileWriter;
21import java.util.Date;
22import java.util.Iterator;
23import java.util.List;
24
25import org.tp23.antinstaller.input.ConditionalField;
26import org.tp23.antinstaller.input.InputField;
27import org.tp23.antinstaller.input.OutputField;
28import org.tp23.antinstaller.input.SecretPropertyField;
29import org.tp23.antinstaller.page.Page;
30
31/**
32 * <p>Outputs the completed Pages as a Java Properties file. The file produced is compatible
33 * with java.util.Properties. </p>
34 * <p>Output is commented as it is printed to aid debugging</p>
35 * @see http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#100850
36 * @author Paul Hinds
37 * @version $Id: ExplicitPropertiesFileRenderer.java,v 1.9 2007/01/09 22:41:41 teknopaul Exp $
38 */
39public class ExplicitPropertiesFileRenderer
40    implements PropertiesFileRenderer {
41
42    private static String newLine = System.getProperty("line.separator");
43    private static final char[] hexidecimals = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
44
45    public ExplicitPropertiesFileRenderer() {
46    }
47
48    public void renderProperties(InstallerContext ctx, File baseDir){
49        Installer installer = ctx.getInstaller();
50        Page[] completedPages = installer.getPages();
51
52        StringBuffer propertiesData = new StringBuffer();
53        propertiesData.append("### Ant Installer - properties auto generated on ");
54        propertiesData.append( convert(new Date().toString(), true) );
55        propertiesData.append(newLine);
56        propertiesData.append(newLine);
57
58        propertiesData.append(FILE_ROOT_PROPERTY);
59        propertiesData.append(" = ");
60        propertiesData.append( convert(baseDir.getAbsolutePath(), true) );
61        propertiesData.append(newLine);
62
63        propertiesData.append(INSTALLER_VERSION_PROPERTY);
64        propertiesData.append(" = ");
65        propertiesData.append( convert(ctx.getInstaller().getVersion(), true) );
66        propertiesData.append(newLine);
67
68        propertiesData.append(newLine);
69        String property = null;
70        String value = null;
71
72
73        for (int i = 0; i < completedPages.length; i++) {
74            OutputField[] fields = completedPages[i].getOutputField();
75
76            propertiesData.append(newLine);
77            propertiesData.append("## Properties from Page:" + completedPages[i].getName());
78            propertiesData.append(newLine);
79
80            retrievePropertiesData( fields, propertiesData );
81
82            // print targets selected
83            List targets = completedPages[i].getTargets(ctx);
84            if(targets.size() > 0){
85                Iterator iterator = targets.iterator();
86                StringBuffer targetProperty = new StringBuffer();
87                while (iterator.hasNext()) {
88                    String target = (String) iterator.next();
89                    targetProperty.append(target).append(",");
90                }
91                propertiesData.append("# Targets selected for page");
92                propertiesData.append(newLine);
93                property = convert(completedPages[i].getName() + TARGETS_SUFFIX, true);
94                value = convert(targetProperty.toString(), true);
95                propertiesData.append(property + " = " + value);
96                propertiesData.append(newLine);
97                
98            }
99        }
00        try {
01            File antInstallProperties = new File(baseDir.getAbsolutePath(), PROPERTIES_FILE_NAME);
02            FileWriter fos = new FileWriter(antInstallProperties);
03            BufferedWriter writer = new BufferedWriter(fos);
04            writer.write(propertiesData.toString());
05            writer.flush();
06            fos.close();
07        }
08        catch (Throwable ex) {
09            if(ctx.getInstaller().isVerbose()) {
10                ctx.log(ex);
11            }
12            //swallow Exceptions as in the contract for this method
13        }
14    }
15    private void retrievePropertiesData( OutputField[] fields, StringBuffer propertiesData ) {
16        String property = null;
17        String value = null;
18
19        for (int f = 0; f < fields.length; f++) {
20            if (fields[f] instanceof SecretPropertyField) {
21                InputField field = (InputField) fields[f];
22                //String result = field.getInputResult();
23                propertiesData.append("# Property hidden " + printClass(fields[f].getClass()));
24                propertiesData.append(newLine);
25                property = convert(field.getProperty(), true);
26                propertiesData.append("#" + property + "=XXXXXXXX");
27                propertiesData.append(newLine);
28            }
29            else if (fields[f] instanceof ConditionalField ) {
30                ConditionalField confField = (ConditionalField) fields[f];
31                retrievePropertiesData( confField.getFields(), propertiesData );
32            }
33            else if (fields[f] instanceof InputField) {
34                InputField field = (InputField) fields[f];
35                String result = field.getInputResult();
36                propertiesData.append("# " + printClass(fields[f].getClass()));
37                propertiesData.append(newLine);
38
39                property = convert(field.getProperty(), true);
40                value = convert(result, false);
41                propertiesData.append(property + " = " + value);
42                propertiesData.append(newLine);
43            }
44        }
45    }
46
47    private String printClass(Class clazz) {
48        String name = clazz.getName();
49        int lastDot = name.lastIndexOf('.');
50        return name.substring(lastDot, name.length());
51    }
52
53    private String convert(String input, boolean doSpaces) {
54        if (input == null) {
55            // this happens when a page is skipped in text mode
56            return "";
57        }
58        int num = input.length();
59        StringBuffer sb = new StringBuffer(num);
60
61        for (int i = 0; i < num; i++) {
62            char c = input.charAt(i);
63            switch (c) {
64                case ' ':
65                    if (i == 0 || doSpaces) {
66                        sb.append('\\');
67                    }
68                    sb.append(' ');
69                    break;
70                case '\n':
71                    sb.append("\\n");
72                    break;
73                case '\r':
74                    sb.append("\\r");
75                    break;
76                case '\\':
77                    sb.append("\\\\");
78                    break;
79                case '\t':
80                    sb.append("\\t");
81                    break;
82                case '\f':
83                    sb.append("\\f");
84                    break;
85                case '=':
86                    sb.append("\\=");
87                    break;
88                case ':':
89                    sb.append("\\:");
90                    break;
91                case '#':
92                    sb.append("\\#");
93                    break;
94                case '!':
95                    sb.append("\\!");
96                    break;
97
98                default:
99                    if ( (c < 0x0020) || (c > 0x007e) ) {
00                        sb.append("\\u")
01                            .append(hex( (c >> 12) & 0xF))
02                            .append(hex( (c >> 8) & 0xF))
03                            .append(hex( (c >> 4) & 0xF))
04                            .append(hex(c & 0xF));
05                    }
06                    else {
07                        sb.append(c);
08                    }
09            }
10        }
11        return sb.toString();
12    }
13
14    private char hex(int val) {
15        return hexidecimals[ (val & 0xF)];
16    }
17
18}
19