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.input;
17
18import java.io.File;
19import java.io.IOException;
20import java.util.HashMap;
21import java.util.Map;
22import java.util.Properties;
23
24import org.tp23.antinstaller.InstallerContext;
25
26
27
28/**
29 * <p>Data Holder for results of the data collection and convenience methods for
30 * obtaining default values containing ${prop.name}/blah syntax </p>
31 * @todo   Ensure in the validator (and Docs) that developers only add ${refs} for properties set on earlier pages
32 * @author Paul Hinds
33 * @version $Id: ResultContainer.java,v 1.6 2007/01/28 10:25:48 teknopaul Exp $
34 */
35public class ResultContainer {
36
37    private HashMap properties = new HashMap();
38    private Properties environment = InstallerContext.getEnvironment();
39    private File installRoot;
40
41    public ResultContainer() {
42    }
43
44    /**
45     * fetch a string for File and Directory inputs that expands ${refs} and
46     * also creates absolute paths from relative paths in the default value
47     * @param defaultString String
48     * @return String
49     */
50    public String getDefaultFileRef(String defaultString){
51        if(defaultString == null) {
52            return null;
53        }
54        
55        String expandedRefs = getDefaultValue(defaultString);
56        File ref = new File(expandedRefs);
57        if(!ref.isAbsolute()){
58            String path = null;
59            try {
60                path = new File(installRoot, expandedRefs).getCanonicalPath();
61            }
62            catch (IOException ex) {
63                // this is a bugger, but it should not happen it implies . or ..
64                // can not be resolved, all we can do is return the . or .. and hope
65                // it works later
66                 path = new File(installRoot, expandedRefs).getAbsolutePath();
67            }
68            return path;
69        } else {
70            String path = ref.getAbsolutePath();
71            return path;
72        }
73    }
74
75    /**
76     *
77     * Handles dereferenceing ${propName} syntax in default value fields
78     * @param defaultString String a plain String or a String with ${ref} references
79     * @return String
80     */
81    public String getDefaultValue(String defaultString) {
82        if(defaultString == null) {
83            return null;
84        }
85
86        char[] characters = defaultString.toCharArray();
87        char c;
88        StringBuffer result = new StringBuffer();
89
90        StringBuffer propertyNameBuffer = new StringBuffer();
91        boolean inProp = false; // state flag indicating parsing a propertyName
92        for (int i = 0; i < characters.length;) {
93            c = characters[i];
94            if ( c == '$' && ( characters.length > i + 1 && characters[i + 1] == '{' ) ){
95                if(inProp){
96                    //Nested property
97                    int endIndex = defaultString.indexOf( '}', i + 1 );
98                    if( endIndex != -1 ) {
99                        ++endIndex;
00                        propertyNameBuffer.append( getDefaultValue( defaultString.substring( i, endIndex ) ) );
01                        i = endIndex;
02                        continue;
03                    }
04                    else {
05                        result.append(propertyNameBuffer.toString());
06                        propertyNameBuffer = new StringBuffer();
07                    }
08                }
09                else{
10                    inProp = true;
11                    propertyNameBuffer.append(c);
12                    ++i;
13                    continue;
14                }
15            }
16            else if (c == '{') {
17                if (inProp) {
18                    propertyNameBuffer.append(c);
19                    if(characters[i - 1] != '$') {
20                        inProp=false;
21                        result.append(propertyNameBuffer.toString());
22                        propertyNameBuffer = new StringBuffer();
23                    }
24                    ++i;
25                    continue;
26                }
27            }
28            else if (c == '}') {
29                if (inProp) {
30                    appendProperty(propertyNameBuffer, result);
31                    propertyNameBuffer = new StringBuffer();
32                    inProp = false;
33                    ++i;
34                    continue;
35                }
36            }
37            if (!inProp) result.append(c);
38            else propertyNameBuffer.append(c);
39            ++i;
40        }
41        if(propertyNameBuffer.length() != 0) {
42            result.append(propertyNameBuffer.toString());
43        }
44        return result.toString();
45    }
46
47
48
49    public HashMap getResults() {
50        return properties;
51    }
52    public void setProperty(String key, String value){
53        properties.put(key, value);
54    }
55    public String getProperty(String key){
56        return (String)properties.get(key);
57    }
58
59    public void setInstallRoot(File installRoot) {
60        this.installRoot = installRoot;
61    }
62    /**
63     * @since 0.7.1 to support installs from readonly media
64     * @return Map
65     */
66    public Map getAllProperties(){
67        return properties;
68    }
69
70    /**
71     * Appends the property if found or inserts an empty string.
72     * This method now supports loading environment variables.
73     * @param propertyNameBuffer StringBuffer
74     * @param result StringBuffer
75     */
76    private void appendProperty(StringBuffer propertyNameBuffer, StringBuffer result) {
77        String propertyName = propertyNameBuffer.toString();
78        String key = propertyName.substring(2);
79        String value = (String)properties.get(key);
80        if(value == null && key.startsWith(InstallerContext.ENV_PREFIX)) {
81            value = environment.getProperty(key);
82        }
83        if(value == null && key.startsWith(InstallerContext.JAVA_PREFIX)) {
84            value = environment.getProperty(key);
85        }
86        if (value != null) {
87            result.append(value);
88        }
89    }
90}
91