source: trunk/src/org/expeditee/settings/Settings.java@ 1121

Last change on this file since 1121 was 1121, checked in by bln4, 6 years ago
File size: 10.1 KB
Line 
1/**
2 * Settings.java
3 * Copyright (C) 2010 New Zealand Digital Library, http://expeditee.org
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19package org.expeditee.settings;
20
21import java.lang.reflect.Field;
22import java.lang.reflect.Method;
23import java.util.HashMap;
24import java.util.LinkedList;
25import java.util.List;
26
27import org.expeditee.gui.AttributeValuePair;
28import org.expeditee.gui.Frame;
29import org.expeditee.gui.FrameCreator;
30import org.expeditee.gui.MessageBay;
31import org.expeditee.items.Text;
32import org.expeditee.items.widgets.Password;
33import org.expeditee.reflection.PackageLoader;
34import org.expeditee.setting.GenericSetting;
35import org.expeditee.setting.Setting;
36import org.expeditee.setting.VariableSetting;
37
38public abstract class Settings {
39
40 public static final String SETTINGS_PACKAGE_PARENT = "org.expeditee.";
41 public static final String SETTINGS_PACKAGE = SETTINGS_PACKAGE_PARENT + "settings.";
42
43 private static final class PageDescriptor {
44
45 private final HashMap<String, Setting> settings = new HashMap<String, Setting>();
46 private final List<String> orderedEntries = new LinkedList<String>();
47 private final List<VariableSetting> settingsList = new LinkedList<VariableSetting>();
48 private final Method onParsed;
49
50 private PageDescriptor(Class<?> clazz) {
51
52 // populate map of settings
53 for(Field f : clazz.getFields()) {
54 // Only allow classes that inherit from Setting
55 if(!Setting.class.isAssignableFrom(f.getType())) continue;
56
57 try {
58 Setting s = (Setting) f.get(null);
59 settings.put(f.getName().toLowerCase(), s);
60 if (s instanceof VariableSetting) settingsList.add((VariableSetting) s);
61 orderedEntries.add(f.getName());
62 } catch (Exception e) {
63 e.printStackTrace();
64 }
65 }
66
67 Method m = null;
68
69 try {
70 m = clazz.getMethod("onParsed", Text.class);
71 } catch(Exception e) {
72 // System.err.println(clazz.getName() + " has no onParsed(Text t) callback");
73 }
74
75 this.onParsed = m;
76 }
77 }
78
79 private static HashMap<String, PageDescriptor> _pages = new HashMap<String, PageDescriptor>();
80
81 private static boolean _init = false;
82
83 public static void Init()
84 {
85 if(_init) return;
86
87 _init = true;
88
89 try {
90 for(Class<?> clazz : PackageLoader.getClassesNew(SETTINGS_PACKAGE)) {
91 // Ignore this class since it's the controller
92 if(clazz.equals(Settings.class)) continue;
93
94 String settingsPageName = clazz.getPackage().getName().toLowerCase().substring(SETTINGS_PACKAGE_PARENT.length());
95 // System.out.println(settingsPage + " : " + clazz.getName());
96 _pages.put(settingsPageName, new PageDescriptor(clazz));
97 }
98
99 } catch (Exception e) {
100 e.printStackTrace();
101 }
102 }
103
104 /** Parses the settings tree, then resets any settings that were not set. */
105 public static void parseSettings(Text text)
106 {
107 List<VariableSetting> set = parseSettings(text, "");
108 List<VariableSetting> toDefault = new LinkedList<VariableSetting>();
109
110 for(PageDescriptor pd : _pages.values()) toDefault.addAll(pd.settingsList);
111
112 toDefault.removeAll(set);
113
114 for(VariableSetting s : toDefault) {
115 try {
116 s.reset();
117 } catch (Exception e) {
118 e.printStackTrace();
119 }
120 }
121 }
122
123 /**
124 * Sets all the simple settings.
125 *
126 * @param text
127 * @param prefix
128 *
129 * @return List of VariableSettings that were changed
130 */
131 private static List<VariableSetting> parseSettings(Text text, String prefix) {
132
133 List<VariableSetting> set = new LinkedList<VariableSetting>();
134
135 Frame child = text.getChild();
136
137 if(child == null) return set;
138
139 String settingsPage = prefix + text.getText().trim().toLowerCase().replaceAll("^@", "");
140 PageDescriptor pd = _pages.get(settingsPage);
141 if(pd == null) return set;
142
143 try {
144 // set the fields
145 List<Text> items = child.getBodyTextItems(false);
146 List<Text> annotations = new LinkedList<Text>(child.getAnnotationItems());
147 List<Frame> seen = new LinkedList<Frame>(); // to avoid getting stuck in a loop
148 seen.add(child);
149 // find all the frames for this settings page
150 while(!annotations.isEmpty()) {
151 Text annotation = annotations.remove(0);
152 Frame next = annotation.getChild();
153 if(next != null && !seen.contains(next)) {
154 items.addAll(next.getBodyTextItems(false));
155 annotations.addAll(next.getAnnotationItems());
156 seen.add(next);
157 }
158 }
159
160 // parse all the settings items on this page
161 for(Text t : items) {
162 AttributeValuePair avp = new AttributeValuePair(t.getText(), false);
163 try {
164 String settingName = avp.getAttributeOrValue().trim().toLowerCase();
165 // System.out.println(avp.getAttributeOrValue().trim().toLowerCase().replaceAll("^@", ""));
166 Setting s = pd.settings.get(settingName);//.replaceAll("^@", ""));
167 if(s == null) {
168 if(settingName.startsWith("//") || settingName.startsWith("@")) {
169 continue;
170 }
171 // System.out.println("Couldn't find setting \"" + settingName + "\"");
172 List<String> validPages = new LinkedList<String>();
173 // if the setting isn't found on the current page, check all child pages
174 for(String k : _pages.keySet()) {
175 if(k.startsWith(settingsPage) && k.length() > settingsPage.length()) {
176 // System.out.println(k + " is a child of " + settingsPage);
177 PageDescriptor cpd = _pages.get(k);
178 Setting tmp = cpd.settings.get(settingName);
179 if(tmp != null) {
180 // System.out.println("Found setting in subpage: " + k);
181 s = tmp;
182 validPages.add(k);
183 }
184 }
185 }
186
187 if(s == null) continue;
188
189 if(validPages.size() > 1) {
190 StringBuffer warnMessage = new StringBuffer("Found multiple matching settings in the following settings subpages: ");
191 String lastPage = "";
192 for(String page : validPages) {
193 warnMessage.append("\"" + page + "\",");
194 lastPage = page;
195 }
196 warnMessage.deleteCharAt(warnMessage.length() - 1);
197 warnMessage.append(" - choosing " + lastPage);
198 MessageBay.warningMessage(warnMessage.toString());
199 }
200 }
201
202 if(s.setSetting(t) && s instanceof VariableSetting) set.add((VariableSetting) s);
203
204 } catch (Exception e) {
205 e.printStackTrace();
206 }
207 }
208
209 // call the onParsed method if one exists
210 if(pd.onParsed != null) {
211 pd.onParsed.invoke(null, text);
212 }
213
214 } catch (Exception e) {
215 e.printStackTrace();
216 return set;
217 }
218
219 // if the page was a settings page, check if it has any subpages
220 for(Text t : child.getTextItems()) {
221 set.addAll(parseSettings(t, settingsPage + "."));
222 }
223 return set;
224 }
225
226 public static void generateSettingsTree(Text link)
227 {
228 generateSettingsTree("settings", link);
229 }
230
231 /** Generates settings tree */
232 private static void generateSettingsTree(String page, Text text)
233 {
234 FrameCreator frames = new FrameCreator(text.getParentOrCurrentFrame().getFramesetName(), text.getParentOrCurrentFrame().getPath(), page, false, false);
235 // Frame frame = FrameIO.CreateFrame(text.getParentOrCurrentFrame().getFramesetName(), page, null);
236 text.setLink(frames.getName());
237
238 // add subpages of the current page
239 for(String k : _pages.keySet()) {
240 if(k.startsWith(page.toLowerCase()) && !k.equals(page)) {
241 String name = k.substring(page.length() + 1);
242 if(name.indexOf('.') != -1) {
243 continue;
244 }
245 System.out.println("Generating " + name);
246 generateSettingsTree(k, frames.addText(name.substring(0, 1).toUpperCase() + name.substring(1), null, null, null, false));
247 }
248 }
249
250 frames.setLastY(frames.getLastY() + 20);
251
252 // add settings of the current page
253 PageDescriptor pd = _pages.get(page);
254 if(pd != null) {
255 for(String str : pd.orderedEntries) {
256 String key = str.toLowerCase();
257 Setting s = pd.settings.get(key);
258 if(s == null) {
259 continue;
260 }
261 String name = str.substring(0, 1).toUpperCase() + str.substring(1);
262 String value = "";
263 if(s instanceof GenericSetting && ((GenericSetting<?>) s).isPrimitive()) {
264 if(((GenericSetting<?>) s).get() != null) {
265 value = ": " + ((GenericSetting<?>) s).get();
266 } else {
267 value = ": ";
268 }
269 }
270 int x = 0, y = 0;
271 Text t;
272 if(key.equals("pass")) {
273 t = frames.addText("iw: org.expeditee.items.widgets.Password", null, null, null, false);
274 Password pw = new Password(t, null);
275 pw.setPassword((String) value);
276 frames.getCurrentFrame().removeItem(t);
277 frames.getCurrentFrame().addAllItems(pw.getItems());
278 x = pw.getX() + pw.getWidth();
279 y = pw.getY();
280 } else {
281 if(s instanceof GenericSetting && ((GenericSetting<?>) s).getType().equals(Text.class)) {
282 t = (Text) ((GenericSetting<?>)s).get();
283 if(t == null) {
284 System.err.println("Failed to get Text setting \"" + str + "\"");
285 continue;
286 }
287 t = t.copy();
288 t.setID(frames.getCurrentFrame().getNextItemID());
289 t.setText(name);
290 frames.addItem(t, false);
291 } else {
292 t = frames.addText(name + value, null, null, null, false);
293 }
294 x = t.getX() + t.getBoundsWidth();
295 y = t.getY();
296 }
297 x = Math.max(250, x + 20);
298 Text tt = frames.getCurrentFrame().addText(x, y, "// " + s.getTooltip(), null);
299 // rebuild to get the correct height since setWidth() doesn't immediately rebuild
300 tt.rebuild(true);
301 if(tt.getY() + tt.getBoundsHeight() > frames.getLastY()) {
302 frames.setLastY(tt.getY() + tt.getBoundsHeight());
303 }
304 }
305 }
306
307 frames.save();
308 //FrameIO.SaveFrame(frame);
309 }
310}
Note: See TracBrowser for help on using the repository browser.