1/* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2 *
3 * This program and the accompanying materials are made available under
4 * the terms of the Common Public License v1.0 which accompanies this distribution,
5 * and is available at http://www.eclipse.org/legal/cpl-v10.html
6 *
7 * $Id: GenericCfg.java,v 1.1.1.1.2.1 2004/07/08 10:52:10 vlad_r Exp $
8 */
9package com.vladium.emma.ant;
10
11import java.io.File;
12import java.io.IOException;
13import java.util.ArrayList;
14import java.util.Iterator;
15import java.util.List;
16import java.util.Properties;
17
18import org.apache.tools.ant.BuildException;
19import org.apache.tools.ant.Task;
20
21import com.vladium.emma.EMMAProperties;
22import com.vladium.util.IProperties;
23import com.vladium.util.Property;
24
25// ----------------------------------------------------------------------------
26/**
27 * GenericCfg is a simple container for 'generic' properties, i.e., properties
28 * that are set via generic 'properties=<file>' attribute and <property>
29 * nested elements. This class makes no decision about relative priorities for
30 * propertie set in an external file or via nested elements, leaving this up
31 * to the parent.
32 *
33 * @author Vlad Roubtsov, (C) 2003
34 */
35public
36class GenericCfg
37{
38    // public: ................................................................
39
40
41    public GenericCfg (final Task task)
42    {
43        if (task == null) throw new IllegalArgumentException ("null input: task");
44
45        m_task = task;
46        m_genericPropertyElements = new ArrayList ();
47    }
48
49
50    // .properties file attribute [actual file I/O done lazily by getFileSettings()]:
51
52    public void setProperties (final File file)
53    {
54        m_settingsFile = file; // actual file I/O is done in getFileSettings()
55    }
56
57    // generic property element:
58
59    public PropertyElement createProperty ()
60    {
61        m_genericSettings = null;
62
63        final PropertyElement property = new PropertyElement ();
64        m_genericPropertyElements.add (property);
65
66        return property;
67    }
68
69    // ACCESSORS:
70
71    public IProperties getFileSettings ()
72    {
73        IProperties fileSettings = m_fileSettings;
74        if ((fileSettings == null) && (m_settingsFile != null))
75        {
76            try
77            {
78                fileSettings = EMMAProperties.wrap (Property.getPropertiesFromFile (m_settingsFile));
79            }
80            catch (IOException ioe)
81            {
82                throw (BuildException) SuppressableTask.newBuildException (m_task.getTaskName ()
83                    + ": property file [" + m_settingsFile.getAbsolutePath () + "] could not be read" , ioe, m_task.getLocation ()).fillInStackTrace ();
84            }
85
86            m_fileSettings = fileSettings;
87
88            return fileSettings;
89        }
90
91        return fileSettings;
92    }
93
94    public IProperties getGenericSettings ()
95    {
96        IProperties genericSettings = m_genericSettings;
97        if (genericSettings == null)
98        {
99            genericSettings = EMMAProperties.wrap (new Properties ());
100
101            for (Iterator i = m_genericPropertyElements.iterator (); i.hasNext (); )
102            {
103                final PropertyElement property = (PropertyElement) i.next ();
104
105                final String name = property.getName ();
106                String value = property.getValue ();
107                if (value == null) value = "";
108
109                if (name != null)
110                {
111                    // [assertion: name != null, value != null]
112
113                    final String currentValue = genericSettings.getProperty (name);
114                    if ((currentValue != null) && ! value.equals (currentValue))
115                    {
116                        throw (BuildException) SuppressableTask.newBuildException (m_task.getTaskName ()
117                            + ": conflicting settings for property [" + name + "]: [" + value + "]" , m_task.getLocation ()).fillInStackTrace ();
118                    }
119                    else
120                    {
121                        genericSettings.setProperty (name, value);
122                    }
123                }
124            }
125
126            m_genericSettings = genericSettings;
127
128            return genericSettings;
129        }
130
131        return genericSettings;
132    }
133
134    // protected: .............................................................
135
136    // package: ...............................................................
137
138    // private: ...............................................................
139
140
141    private final Task m_task;
142
143    private final List /* PropertyElement */ m_genericPropertyElements; // never null
144    private File m_settingsFile; // can be null
145
146    private transient IProperties m_fileSettings; // can be null
147    private transient IProperties m_genericSettings; // can be null
148
149} // end of class
150// ----------------------------------------------------------------------------