~sword-devel/jsword/trunk

« back to all changes in this revision

Viewing changes to jsword/java/common/org/crosswire/common/config/ReflectedChoice.java

  • Committer: joe
  • Date: 2002-10-08 21:36:18 UTC
  • Revision ID: svn-v4:a88caf3b-7e0a-0410-8d0d-cecb45342206:trunk:80
big config and comment update

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
package org.crosswire.common.config;
 
3
 
 
4
import java.io.Serializable;
 
5
import java.lang.reflect.InvocationTargetException;
 
6
import java.lang.reflect.Method;
 
7
 
 
8
import org.apache.log4j.Logger;
 
9
import org.crosswire.common.util.UserLevel;
 
10
import org.jdom.Element;
 
11
 
 
12
/**
 
13
 * Every Choice must be able to:<ul>
 
14
 * <li>get and set itself using a String</li>
 
15
 * <li>provide some simple help about itself</li>
 
16
 * <li>elect a user level for itself (Beginner, Intermediate, Advanced)</li>
 
17
 * <li>provide a GUI editor for itself</li>
 
18
 * </ul>
 
19
 * 
 
20
 * <p><table border='1' cellPadding='3' cellSpacing='0'>
 
21
 * <tr><td bgColor='white' class='TableRowColor'><font size='-7'>
 
22
 *
 
23
 * Distribution Licence:<br />
 
24
 * JSword is free software; you can redistribute it
 
25
 * and/or modify it under the terms of the GNU General Public License,
 
26
 * version 2 as published by the Free Software Foundation.<br />
 
27
 * This program is distributed in the hope that it will be useful,
 
28
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
29
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
30
 * General Public License for more details.<br />
 
31
 * The License is available on the internet
 
32
 * <a href='http://www.gnu.org/copyleft/gpl.html'>here</a>, or by writing to:
 
33
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 
34
 * MA 02111-1307, USA<br />
 
35
 * The copyright to this program is held by it's authors.
 
36
 * </font></td></tr></table>
 
37
 * @see docs.Licence
 
38
 * @author Joe Walker [joe at eireneh dot com]
 
39
 * @version $Id$
 
40
 */
 
41
public abstract class ReflectedChoice implements Choice, Serializable
 
42
{
 
43
    /**
 
44
     * Simple ctor so there is a default
 
45
     */
 
46
    public void init(Element option) throws StartupException
 
47
    {
 
48
        // The important 3 things saying what we update and how we describe ourselves
 
49
        Element introspector = option.getChild("introspect");
 
50
        if (introspector == null)
 
51
            throw new StartupException("Missing introspect element in config.xml");
 
52
 
 
53
        String clazzname = introspector.getAttributeValue("class");
 
54
        propertyname = introspector.getAttributeValue("property");
 
55
 
 
56
        log.debug("Looking up "+clazzname+".set"+propertyname+"("+getConvertionClass().getName()+" arg0)");
 
57
 
 
58
        try
 
59
        {
 
60
            clazz = Class.forName(clazzname);
 
61
        }
 
62
        catch (ClassNotFoundException ex)
 
63
        {
 
64
            throw new StartupException("Specified class not found "+clazz.getName(), ex);
 
65
        }
 
66
 
 
67
        try
 
68
        {
 
69
            setter = clazz.getMethod("set"+propertyname, new Class[] { getConvertionClass() });
 
70
        }
 
71
        catch (NoSuchMethodException ex)
 
72
        {
 
73
            throw new StartupException("Specified method not found "+clazz.getName()+".set"+propertyname+"("+getConvertionClass().getName()+" arg0)", ex);
 
74
        }
 
75
 
 
76
        try
 
77
        {
 
78
            try
 
79
            {
 
80
                getter = clazz.getMethod("get"+propertyname, new Class[0]);
 
81
            }
 
82
            catch (Exception ex)
 
83
            {
 
84
                getter = clazz.getMethod("is"+propertyname, new Class[0]);
 
85
            }
 
86
        }
 
87
        catch (NoSuchMethodException ex)
 
88
        {
 
89
            throw new StartupException("Specified method not found "+clazz.getName()+".get"+propertyname+"()", ex);
 
90
        }
 
91
 
 
92
        if (getter.getReturnType() != getConvertionClass())
 
93
        {
 
94
            log.debug("Not using "+propertyname+" from "+clazz.getName()+" because the return type of the getter is not "+getConvertionClass().getName());
 
95
            throw new StartupException("Mismatch of return types, found: "+getter.getReturnType()+" required:"+getConvertionClass());
 
96
        }
 
97
 
 
98
        // Help text
 
99
        Element childele = option.getChild("help");
 
100
        if (childele == null)
 
101
            helptext = "";
 
102
        helptext = childele.getTextTrim();
 
103
 
 
104
        // 2 optional config attrubites
 
105
        level = UserLevel.forName(option.getAttributeValue("level"));
 
106
        String priorityname = option.getAttributeValue("priority");
 
107
        if (priorityname == null)
 
108
            priority = ReflectedChoice.PRIORITY_NORMAL;
 
109
        else
 
110
            priority = Integer.parseInt(priorityname);
 
111
    }
 
112
 
 
113
    /**
 
114
     * Convert from a reflection return value to a String for storage
 
115
     */
 
116
    public abstract String convertToString(Object orig);
 
117
 
 
118
    /**
 
119
     * Convert from a stored string to an object to use with relfection
 
120
     */
 
121
    public abstract Object convertToObject(String orig);
 
122
 
 
123
    /**
 
124
     * Get some help on this Field. In this case we are just providing
 
125
     * a default help text, that isn't much use.
 
126
     * @return The default help text
 
127
     */
 
128
    public String getHelpText()
 
129
    {
 
130
        return helptext;
 
131
    }
 
132
 
 
133
    /**
 
134
     * Get some help on this Field. In this case we are just providing
 
135
     * a default help text, that isn't much use.
 
136
     * @return The default help text
 
137
     */
 
138
    public void setHelpText(String helptext)
 
139
    {
 
140
        this.helptext = helptext;
 
141
    }
 
142
 
 
143
    /**
 
144
     * Gets a default user level (beginner to advanced)
 
145
     * @return The user level
 
146
     */
 
147
    public UserLevel getUserLevel()
 
148
    {
 
149
        return level;
 
150
    }
 
151
 
 
152
    /**
 
153
     * Gets a default user level (beginner to advanced)
 
154
     * @param level The user level
 
155
     */
 
156
    protected void setUserLevel(UserLevel level)
 
157
    {
 
158
        this.level = level;
 
159
    }
 
160
 
 
161
    /**
 
162
     * Is this Choice OK to write out to a file, or should we use settings
 
163
     * in this run of the program, but forget them for next time. A
 
164
     * typical use of this is for password configuration.
 
165
     * @return True if it is safe to store the value in a config file.
 
166
     */
 
167
    public boolean isSaveable()
 
168
    {
 
169
        return true;
 
170
    }
 
171
 
 
172
    /**
 
173
     * Sometimes we need to ensure that we configure items in a certain
 
174
     * order, the config package moves the changes to the application
 
175
     * starting with the highest priority, moving to the lowest
 
176
     * @return A priority level
 
177
     */
 
178
    public int getPriority()
 
179
    {
 
180
        return priority;
 
181
    }
 
182
 
 
183
    /**
 
184
     * Sometimes we need to ensure that we configure items in a certain
 
185
     * order, the config package moves the changes to the application
 
186
     * starting with the highest priority, moving to the lowest
 
187
     * @param priority A priority level
 
188
     */
 
189
    public void setPriority(int priority)
 
190
    {
 
191
        this.priority = priority;
 
192
    }
 
193
 
 
194
    /**
 
195
     * Do we need to restart the program in order for this change to have
 
196
     * effect?
 
197
     * @return True if a restart is required
 
198
     */
 
199
    public boolean requiresRestart()
 
200
    {
 
201
        return false;
 
202
    }
 
203
 
 
204
    /**
 
205
     * @see org.crosswire.common.config.Choice#getString()
 
206
     */
 
207
    public String getString()
 
208
    {
 
209
        try
 
210
        {
 
211
            Object retval = getter.invoke(null, new Object[0]);
 
212
            return convertToString(retval);
 
213
        }
 
214
        catch (IllegalAccessException ex)
 
215
        {
 
216
            log.error("Illegal access getting value from "+clazz.getName()+"."+getter.getName(), ex);
 
217
            return "";
 
218
        }
 
219
        catch (InvocationTargetException ex)
 
220
        {
 
221
            log.error("Failed to get value from "+clazz.getName()+"."+getter.getName(), ex);
 
222
            return "";
 
223
        }
 
224
    }
 
225
 
 
226
    /**
 
227
     * @see org.crosswire.common.config.Choice#setString(String)
 
228
     */
 
229
    public void setString(String value) throws Exception
 
230
    {
 
231
        setter.invoke(null, new Object[] { convertToObject(value) });
 
232
    }
 
233
 
 
234
    /** The highest level priority generally for system level stuff */
 
235
    public static final int PRIORITY_SYSTEM = 10;
 
236
 
 
237
    /** The priority level for important but non system level stuff */
 
238
    public static final int PRIORITY_EXTENDER = 9;
 
239
 
 
240
    /** The priority level for important but non system level stuff */
 
241
    public static final int PRIORITY_HIGHEST = 8;
 
242
 
 
243
    /** The priority level for normal use */
 
244
    public static final int PRIORITY_NORMAL = 6;
 
245
 
 
246
    /** The priority level for creating items for later configuring */
 
247
    public static final int PRIORITY_CTOR = 4;
 
248
 
 
249
    /** The priority level for configuring previously created items */
 
250
    public static final int PRIORITY_ACCESSOR = 2;
 
251
 
 
252
    /** The lowest level priority generally for system level stuff */
 
253
    public static final int PRIORITY_LOWEST = 0;
 
254
 
 
255
    private Class clazz;
 
256
    private String propertyname;
 
257
 
 
258
    /**
 
259
     * The method to call to get the value
 
260
     */
 
261
    private Method getter;
 
262
 
 
263
    /**
 
264
     * The method to call to set the value
 
265
     */
 
266
    private Method setter;
 
267
 
 
268
    /**
 
269
     * The help text (tooltip) for this item
 
270
     */
 
271
    private String helptext = "No help available";
 
272
 
 
273
    /**
 
274
     * The userlevel
 
275
     */
 
276
    private UserLevel level = UserLevel.BEGINNER;
 
277
 
 
278
    /**
 
279
     * The priority of this config level
 
280
     */
 
281
    private int priority = PRIORITY_NORMAL;
 
282
 
 
283
    /**
 
284
     * The log stream
 
285
     */
 
286
    protected static Logger log = Logger.getLogger(ReflectedChoice.class);
 
287
}