KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jgap > data > config > MetaConfig


1 /*
2  * This file is part of JGAP.
3  *
4  * JGAP offers a dual license model containing the LGPL as well as the MPL.
5  *
6  * For licencing information please see the file license.txt included with JGAP
7  * or have a look at the top of class org.jgap.Chromosome which representatively
8  * includes the JGAP license policy applicable for any file delivered with JGAP.
9  */

10 package org.jgap.data.config;
11
12 import java.util.*;
13 import java.io.*;
14
15 /**
16  * This class provides an interface to the configuration information to create
17  * a JGAP Configuration GUI.
18  * @author Siddhartha Azad
19  * @since 2.4
20  *
21  */

22 public class MetaConfig {
23   // file to read the GUI Configuration information from
24
private static final String JavaDoc METACON_FILENAME = "jgap-meta.con";
25
26   private static final String JavaDoc CN = "MetaConfig";
27
28   // singleton instance
29
private static MetaConfig instance;
30
31   // ClassName-ConfigProperty mapping
32
private Hashtable m_metaMap = new Hashtable();
33
34   // state for the parser
35
private int m_state;
36
37   private static final int INIT = 0;
38
39   private static final int CLASS = 1;
40
41   private static final int PROPERTY = 2;
42
43   private static final int VALUES = 3;
44
45   // class name currently being handled
46
private String JavaDoc m_currName;
47
48   private ConfigProperty m_currProperty;
49
50   public static MetaConfig getInstance()
51       throws MetaConfigException, IOException {
52     if (null == instance) {
53       instance = new MetaConfig();
54     }
55     return instance;
56   }
57
58   private MetaConfig()
59       throws MetaConfigException, IOException {
60     m_state = MetaConfig.INIT;
61     init();
62   }
63
64   // public interface
65

66   /**
67    * Read the meta-config file and load it in memory.
68    * @param className the name of the class of which the properties are
69    * required
70    * @return the list of properties for this class, if class is registered,
71    * otherwise null
72    *
73    * @author Siddhartha Azad
74    * @since 2.4
75    * */

76   public List getConfigProperty(String JavaDoc className) {
77     return (List)m_metaMap.get(className);
78   }
79
80   /**
81    * Read the meta-config file and load it in memory.
82    * Having to read my own property file without using the Java Property
83    * class since I need to preserve the order of these properties, plus
84    * I have duplicate labels.
85    * @throws MetaConfigException
86    * @throws IOException
87    *
88    * @author Siddhartha Azad
89    * @since 2.4
90    */

91   protected void init()
92       throws MetaConfigException, IOException {
93     Reader fr = getReader(METACON_FILENAME);
94     LineNumberReader lr = new LineNumberReader(fr);
95     String JavaDoc line = lr.readLine();
96     while (line != null) {
97       if (!this.isComment(line)) {
98         parseLine(line);
99       }
100       line = lr.readLine();
101     }
102     endState();
103     lr.close();
104   }
105
106   /**
107    * Returns a reader to a file
108    * @param a_filename the file to retrieve a reader for
109    * @throws IOException
110    * @return the Reader
111    *
112    * @author Klaus Meffert
113    * @since 3.0
114    */

115   public Reader getReader(String JavaDoc a_filename) throws IOException {
116     File metaFile = new File(a_filename);
117     FileReader fr = new FileReader(metaFile);
118     return fr;
119   }
120
121   /**
122    * Check whether a line is a comment. Any line starting with a '#' is a
123    * comment.
124    * @return true if a line is a comment, false if it is not
125    *
126    * @author Siddhartha Azad
127    * @since 2.4
128    * */

129   private boolean isComment(String JavaDoc line) {
130     String JavaDoc tmpLine = line.trim();
131     StringBuffer JavaDoc sb = new StringBuffer JavaDoc(tmpLine);
132     if (sb.charAt(0) == '#') {
133       return true;
134     }
135     return false;
136   }
137
138   /**
139    * Parse a line. This method is dispatches lines to other methods, hence
140    * acting like a state machine.
141    * @throws MetaConfigException
142    *
143    * @author Siddhartha Azad
144    * @since 2.4
145    * */

146   private void parseLine(String JavaDoc a_line)
147       throws MetaConfigException {
148     String JavaDoc[] tokens = a_line.split("=");
149     if (tokens == null || tokens.length != 2)
150       throw new MetaConfigException(CN + ".parseLine():Exception while " +
151                                     "parsing " + METACON_FILENAME + " line " +
152                                     a_line + " is invalid");
153     if (m_state == MetaConfig.INIT && tokens[0].equals("class")) {
154       handleClass(tokens[1]);
155     }
156     else if (m_state == MetaConfig.CLASS && tokens[0].equals("property")) {
157       handleProperty(tokens[1]);
158     }
159     else if (m_state == MetaConfig.PROPERTY && tokens[0].equals("values")) {
160       handleValues(tokens[1]);
161     }
162     else if (m_state == MetaConfig.PROPERTY && tokens[0].equals("class")) {
163       handleClass(tokens[1]);
164     }
165     else if (m_state == MetaConfig.VALUES && tokens[0].equals("class")) {
166       handleClass(tokens[1]);
167     }
168     else if (m_state == MetaConfig.VALUES && tokens[0].equals("property")) {
169       handleProperty(tokens[1]);
170     }
171     else {
172       throw new MetaConfigException(CN + ".parseLine():Exception while "
173                                     + "parsing " + METACON_FILENAME + " state "
174                                     + m_state
175                                     + " incompatible with line " + a_line);
176     }
177   }
178
179   /**
180    * Handle the state when a 'class' tag is found.
181    * @author Siddhartha Azad
182    * @since 2.4
183    * */

184   private void handleClass(final String JavaDoc a_token) {
185     m_state = MetaConfig.CLASS;
186     if (m_currProperty != null) {
187       add(m_currName, m_currProperty);
188     }
189     m_currProperty = new ConfigProperty();
190     m_currName = a_token;
191   }
192
193   /**
194    * Handle the state when a 'property' tag is found.
195    * @throws MetaConfigException
196    *
197    * @author Siddhartha Azad
198    * @since 2.4
199    * */

200   private void handleProperty(final String JavaDoc a_token)
201       throws MetaConfigException {
202     int prevState = m_state;
203     if (prevState == MetaConfig.VALUES) {
204       if (m_currProperty != null) {
205         add(m_currName, m_currProperty);
206       }
207     }
208     m_currProperty = new ConfigProperty();
209     m_state = MetaConfig.PROPERTY;
210     String JavaDoc[] tokens = a_token.split(",");
211     if (tokens.length < 2 || tokens.length > 3) {
212       throw new MetaConfigException("Invalid format of property line: " +
213                                     a_token);
214     }
215     m_currProperty.setName(tokens[0].trim());
216     m_currProperty.setWidget(tokens[1].trim());
217     if (tokens.length == 3) {
218       m_currProperty.setLabel(tokens[2]);
219     }
220   }
221
222   /**
223    * Handle the state when a 'values' tag is found.
224    * @param a_token the rhs of the values property
225    * @throws MetaConfigException
226    *
227    * @author Siddhartha Azad
228    * @since 2.4
229    *
230    * */

231   private void handleValues(final String JavaDoc a_token)
232       throws MetaConfigException {
233     m_state = MetaConfig.VALUES;
234     String JavaDoc[] tokens = a_token.split(",");
235     if (tokens.length == 0) {
236       throw new MetaConfigException("Invalid format of property line: " +
237                                     a_token);
238     }
239     for (int i = 0; i < tokens.length; i++) {
240       m_currProperty.addValue(tokens[i].trim());
241     }
242   }
243
244   /**
245    * Called once the EOF is encountered while parsing the file.
246    *
247    * @throws MetaConfigException if parsing ends in an invalid state
248    *
249    * @author Siddhartha Azad
250    * @since 2.4
251    * */

252   private void endState()
253       throws MetaConfigException {
254     if (m_state != MetaConfig.PROPERTY && m_state != MetaConfig.VALUES) {
255       throw new MetaConfigException("Invalid format of JGAP MetaConfig "
256                                     + "file: " + METACON_FILENAME
257                                     + "Ending in Invalid state : "
258                                     + m_state);
259     }
260     if (m_currProperty != null) {
261       add(m_currName, m_currProperty);
262     }
263   }
264
265   /**
266    * Add a new ConfigProperty for a certain class to the hashtable of
267    * properties.
268    * @param currName name of the class to which the property belongs
269    * @param a_cp the ConfigProperty to be added to the class
270    *
271    * @author Siddhartha Azad
272    * @since 2.4
273    * */

274   private void add(final String JavaDoc currName, ConfigProperty a_cp) {
275     List props = (List) m_metaMap.get(currName);
276     if (null == props) {
277       props = Collections.synchronizedList(new ArrayList());
278       m_metaMap.put(currName, props);
279     }
280     props.add(a_cp);
281   }
282 }
283
Popular Tags