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

Last change on this file since 919 was 919, checked in by jts21, 10 years ago

Added license headers to all files, added full GPL3 license file, moved license header generator script to dev/bin/scripts

File size: 10.5 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.DisplayIO;
29import org.expeditee.gui.Frame;
30import org.expeditee.gui.FrameCreator;
31import org.expeditee.gui.FrameIO;
32import org.expeditee.gui.FrameUtils;
33import org.expeditee.gui.MessageBay;
34import org.expeditee.items.Item;
35import org.expeditee.items.Text;
36import org.expeditee.items.widgets.Password;
37import org.expeditee.reflection.PackageLoader;
38import org.expeditee.setting.GenericSetting;
39import org.expeditee.setting.Setting;
40import org.expeditee.setting.VariableSetting;
41
42public abstract class Settings {
43
44 public static final String SETTINGS_PACKAGE_PARENT = "org.expeditee.";
45 public static final String SETTINGS_PACKAGE = SETTINGS_PACKAGE_PARENT + "settings.";
46
47 private static final class PageDescriptor {
48
49 private final HashMap<String, Setting> settings = new HashMap<String, Setting>();
50 private final List<String> orderedEntries = new LinkedList<String>();
51 private final List<VariableSetting> settingsList = new LinkedList<VariableSetting>();
52 private final Method onParsed;
53
54 private PageDescriptor(Class<?> clazz) {
55
56 // populate map of settings
57 for(Field f : clazz.getFields()) {
58 // only allow valid types
59 if(! Setting.class.isAssignableFrom(f.getType())) {
60 continue;
61 }
62 try {
63 Setting s = (Setting) f.get(null);
64 settings.put(f.getName().toLowerCase(), s);
65 if(s instanceof VariableSetting) {
66 settingsList.add((VariableSetting) s);
67 }
68 orderedEntries.add(f.getName());
69 } catch (Exception e) {
70 e.printStackTrace();
71 }
72 }
73 Method m = null;
74 try {
75 m = clazz.getMethod("onParsed", Text.class);
76 } catch(Exception e) {
77 // System.err.println(clazz.getName() + " has no onParsed(Text t) callback");
78 }
79 this.onParsed = m;
80 }
81 }
82 private static HashMap<String, PageDescriptor> _pages = new HashMap<String, PageDescriptor>();
83
84 private static boolean _init = false;
85 public static void Init() {
86 if(_init) return;
87 _init = true;
88 try {
89 for(Class<?> clazz : PackageLoader.getClassesNew(SETTINGS_PACKAGE)) {
90 // Ignore this class since it's the controller
91 if(clazz.equals(Settings.class)) {
92 continue;
93 }
94 String settingsPage = clazz.getPackage().getName().toLowerCase().substring(SETTINGS_PACKAGE_PARENT.length());
95 // System.out.println(settingsPage + " : " + clazz.getName());
96 _pages.put(settingsPage, new PageDescriptor(clazz));
97 }
98
99 } catch (Exception e) {
100 e.printStackTrace();
101 }
102 FrameUtils.ParseProfile(FrameIO.LoadProfile(UserSettings.ProfileName.get()));
103 }
104
105 /**
106 * Parses the settings tree, then resets any settings that were not set
107 */
108 public static void parseSettings(Text text) {
109 List<VariableSetting> set = parseSettings(text, "");
110 List<VariableSetting> toDefault = new LinkedList<VariableSetting>();
111 for(PageDescriptor pd : _pages.values()) {
112 toDefault.addAll(pd.settingsList);
113 }
114 toDefault.removeAll(set);
115 for(VariableSetting s : toDefault) {
116 try {
117 // System.out.println("Resetting " + s.getTooltip());
118 s.reset();
119 // System.out.println("Set " + f.getName() + " to default value " + f.get(null));
120 } catch (Exception e) {
121 e.printStackTrace();
122 }
123 }
124 }
125
126 /**
127 * Sets all the simple settings.
128 *
129 * @param text
130 * @param prefix
131 *
132 * @return List of VariableSettings that were changed
133 */
134 private static List<VariableSetting> parseSettings(Text text, String prefix) {
135
136 List<VariableSetting> set = new LinkedList<VariableSetting>();
137 Frame child = text.getChild();
138 if(child == null) {
139 return set;
140 }
141 String settingsPage = prefix + text.getText().trim().toLowerCase().replaceAll("^@", "");
142 PageDescriptor pd = _pages.get(settingsPage);
143 if(pd == null) {
144 return set;
145 }
146 try {
147 // set the fields
148 List<Text> items = child.getBodyTextItems(false);
149 List<Text> annotations = new LinkedList<Text>(child.getAnnotationItems());
150 List<Frame> seen = new LinkedList<Frame>(); // to avoid getting stuck in a loop
151 seen.add(child);
152 // find all the frames for this settings page
153 while(!annotations.isEmpty()) {
154 Text annotation = annotations.remove(0);
155 Frame next = annotation.getChild();
156 if(next != null && !seen.contains(next)) {
157 items.addAll(next.getBodyTextItems(false));
158 annotations.addAll(next.getAnnotationItems());
159 seen.add(next);
160 }
161 }
162 // parse all the settings items on this page
163 for(Text t : items) {
164 AttributeValuePair avp = new AttributeValuePair(t.getText(), false);
165 try {
166 String settingName = avp.getAttributeOrValue().trim().toLowerCase();
167 // System.out.println(avp.getAttributeOrValue().trim().toLowerCase().replaceAll("^@", ""));
168 Setting s = pd.settings.get(settingName);//.replaceAll("^@", ""));
169 if(s == null) {
170 if(settingName.startsWith("//") || settingName.startsWith("@")) {
171 continue;
172 }
173 // System.out.println("Couldn't find setting \"" + settingName + "\"");
174 List<String> validPages = new LinkedList<String>();
175 // if the setting isn't found on the current page, check all child pages
176 for(String k : _pages.keySet()) {
177 if(k.startsWith(settingsPage) && k.length() > settingsPage.length()) {
178 // System.out.println(k + " is a child of " + settingsPage);
179 PageDescriptor cpd = _pages.get(k);
180 Setting tmp = cpd.settings.get(settingName);
181 if(tmp != null) {
182 // System.out.println("Found setting in subpage: " + k);
183 s = tmp;
184 validPages.add(k);
185 }
186 }
187 }
188 // System.out.println(s);
189 if(s == null) {
190 continue;
191 }
192 if(validPages.size() > 1) {
193 StringBuffer warnMessage = new StringBuffer("Found multiple matching settings in the following settings subpages: ");
194 String lastPage = "";
195 for(String page : validPages) {
196 warnMessage.append("\"" + page + "\",");
197 lastPage = page;
198 }
199 warnMessage.deleteCharAt(warnMessage.length() - 1);
200 warnMessage.append(" - choosing " + lastPage);
201 MessageBay.warningMessage(warnMessage.toString());
202 }
203 }
204 if(s.setSetting(t) && s instanceof VariableSetting) {
205 set.add((VariableSetting) s);
206 }
207 } catch (Exception e) {
208 e.printStackTrace();
209 }
210 }
211 // call the onParsed method if one exists
212 if(pd.onParsed != null) {
213 pd.onParsed.invoke(null, text);
214 }
215 } catch (Exception e) {
216 e.printStackTrace();
217 return set;
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 generateSettingsTree("settings", link);
228 }
229
230 /**
231 *
232 * Generates settings tree
233 *
234 */
235 private static void generateSettingsTree(String page, Text text) {
236 FrameCreator frames = new FrameCreator(text.getParentOrCurrentFrame().getFramesetName(), text.getParentOrCurrentFrame().getPath(), page, false, false);
237 // Frame frame = FrameIO.CreateFrame(text.getParentOrCurrentFrame().getFramesetName(), page, null);
238 text.setLink(frames.getName());
239
240 // add subpages of the current page
241 for(String k : _pages.keySet()) {
242 if(k.startsWith(page.toLowerCase()) && !k.equals(page)) {
243 String name = k.substring(page.length() + 1);
244 if(name.indexOf('.') != -1) {
245 continue;
246 }
247 System.out.println("Generating " + name);
248 generateSettingsTree(k, frames.addText(name.substring(0, 1).toUpperCase() + name.substring(1), null, null, null, false));
249 }
250 }
251
252 frames.setLastY(frames.getLastY() + 20);
253
254 // add settings of the current page
255 PageDescriptor pd = _pages.get(page);
256 if(pd != null) {
257 for(String str : pd.orderedEntries) {
258 String key = str.toLowerCase();
259 Setting s = pd.settings.get(key);
260 if(s == null) {
261 continue;
262 }
263 String name = str.substring(0, 1).toUpperCase() + str.substring(1);
264 String value = "";
265 if(s instanceof GenericSetting && ((GenericSetting<?>) s).isPrimitive()) {
266 if(((GenericSetting<?>) s).get() != null) {
267 value = ": " + ((GenericSetting<?>) s).get();
268 } else {
269 value = ": ";
270 }
271 }
272 int x = 0, y = 0;
273 Text t;
274 if(key.equals("pass")) {
275 t = frames.addText("iw: org.expeditee.items.widgets.Password", null, null, null, false);
276 Password pw = new Password(t, null);
277 pw.setPassword((String) value);
278 frames.getCurrentFrame().removeItem(t);
279 frames.getCurrentFrame().addAllItems(pw.getItems());
280 x = pw.getX() + pw.getWidth();
281 y = pw.getY();
282 } else {
283 if(s instanceof GenericSetting && ((GenericSetting<?>) s).getType().equals(Text.class)) {
284 t = (Text) ((GenericSetting<?>)s).get();
285 if(t == null) {
286 System.err.println("Failed to get Text setting \"" + str + "\"");
287 continue;
288 }
289 t = t.copy();
290 t.setID(frames.getCurrentFrame().getNextItemID());
291 t.setText(name);
292 frames.addItem(t, false);
293 } else {
294 t = frames.addText(name + value, null, null, null, false);
295 }
296 x = t.getX() + t.getBoundsWidth();
297 y = t.getY();
298 }
299 x = Math.max(250, x + 20);
300 Text tt = frames.getCurrentFrame().addText(x, y, "// " + s.getTooltip(), null);
301 // rebuild to get the correct height since setWidth() doesn't immediately rebuild
302 tt.rebuild(true);
303 if(tt.getY() + tt.getBoundsHeight() > frames.getLastY()) {
304 frames.setLastY(tt.getY() + tt.getBoundsHeight());
305 }
306 }
307 }
308
309 frames.save();
310 //FrameIO.SaveFrame(frame);
311 }
312}
Note: See TracBrowser for help on using the repository browser.