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

Last change on this file since 1303 was 1303, checked in by bln4, 5 years ago

Moved the static field USER_NOBODY to AuthenticatorBrowser from Browser as it makes more sense there.
Added functionality to log out, equiv to closing Expeditee and starting it again.

File size: 10.3 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.Iterator;
25import java.util.LinkedList;
26import java.util.List;
27
28import org.expeditee.gui.AttributeValuePair;
29import org.expeditee.gui.Frame;
30import org.expeditee.gui.FrameCreator;
31import org.expeditee.gui.MessageBay;
32import org.expeditee.items.Text;
33import org.expeditee.items.widgets.Password;
34import org.expeditee.reflection.PackageLoader;
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 public static void resetAllSettings() {
124 for (PageDescriptor pd : _pages.values()) {
125 for (VariableSetting s : pd.settingsList) {
126 s.reset();
127 }
128 }
129 }
130
131 /**
132 * Sets all the simple settings.
133 *
134 * @param text
135 * @param prefix
136 *
137 * @return List of VariableSettings that were changed
138 */
139 private static List<VariableSetting> parseSettings(Text text, String prefix) {
140
141 List<VariableSetting> set = new LinkedList<VariableSetting>();
142
143 Frame child = text.getChild();
144
145 if(child == null) return set;
146
147 String settingsPage = prefix + text.getText().trim().toLowerCase().replaceAll("^@", "");
148 PageDescriptor pd = _pages.get(settingsPage);
149 if(pd == null) return set;
150
151 try {
152 // set the fields
153 List<Text> items = child.getBodyTextItems(false);
154 List<Text> annotations = new LinkedList<Text>(child.getAnnotationItems());
155 List<Frame> seen = new LinkedList<Frame>(); // to avoid getting stuck in a loop
156 seen.add(child);
157 // find all the frames for this settings page
158 while(!annotations.isEmpty()) {
159 Text annotation = annotations.remove(0);
160 Frame next = annotation.getChild();
161 if(next != null && !seen.contains(next)) {
162 items.addAll(next.getBodyTextItems(false));
163 annotations.addAll(next.getAnnotationItems());
164 seen.add(next);
165 }
166 }
167
168 // parse all the settings items on this page
169 for(Text t : items) {
170 AttributeValuePair avp = new AttributeValuePair(t.getText(), false);
171 try {
172 String settingName = avp.getAttributeOrValue().trim().toLowerCase();
173 // System.out.println(avp.getAttributeOrValue().trim().toLowerCase().replaceAll("^@", ""));
174 Setting s = pd.settings.get(settingName);//.replaceAll("^@", ""));
175 if(s == null) {
176 if(settingName.startsWith("//") || settingName.startsWith("@")) {
177 continue;
178 }
179 // System.out.println("Couldn't find setting \"" + settingName + "\"");
180 List<String> validPages = new LinkedList<String>();
181 // if the setting isn't found on the current page, check all child pages
182 for(String k : _pages.keySet()) {
183 if(k.startsWith(settingsPage) && k.length() > settingsPage.length()) {
184 // System.out.println(k + " is a child of " + settingsPage);
185 PageDescriptor cpd = _pages.get(k);
186 Setting tmp = cpd.settings.get(settingName);
187 if(tmp != null) {
188 // System.out.println("Found setting in subpage: " + k);
189 s = tmp;
190 validPages.add(k);
191 }
192 }
193 }
194
195 if(s == null) continue;
196
197 if(validPages.size() > 1) {
198 StringBuffer warnMessage = new StringBuffer("Found multiple matching settings in the following settings subpages: ");
199 String lastPage = "";
200 for(String page : validPages) {
201 warnMessage.append("\"" + page + "\",");
202 lastPage = page;
203 }
204 warnMessage.deleteCharAt(warnMessage.length() - 1);
205 warnMessage.append(" - choosing " + lastPage);
206 MessageBay.warningMessage(warnMessage.toString());
207 }
208 }
209
210 if(s.setSetting(t) && s instanceof VariableSetting) set.add((VariableSetting) s);
211
212 } catch (Exception e) {
213 e.printStackTrace();
214 }
215 }
216
217 // call the onParsed method if one exists
218 if(pd.onParsed != null) {
219 pd.onParsed.invoke(null, text);
220 }
221
222 } catch (Exception e) {
223 e.printStackTrace();
224 return set;
225 }
226
227 // if the page was a settings page, check if it has any subpages
228 for(Text t : child.getTextItems()) {
229 set.addAll(parseSettings(t, settingsPage + "."));
230 }
231 return set;
232 }
233
234 public static void generateSettingsTree(Text link) {
235 generateSettingsTree("settings", link);
236 }
237
238 private static void generateSettingsTree(String page, Text text) {
239 Frame parent = text.getParentOrCurrentFrame();
240 FrameCreator frames = new FrameCreator(parent.getFramesetName(), parent.getPath(), page, FrameCreator.ExistingFramesetOptions.AppendSegregatedFrames, false);
241 text.setLink(frames.getName());
242
243 // Add subpages of the current page by recursing
244 for (String k: _pages.keySet()) {
245 if (k.startsWith(page.toLowerCase()) && !k.equals(page)) {
246 String name = k.substring(page.length() + 1);
247 if (name.indexOf('.') != -1) {
248 continue;
249 }
250 System.out.println("@Settings: Generating " + name);
251 generateSettingsTree(k, frames.addText(name.substring(0, 1).toUpperCase() + name.substring(1), null, null, null, false));
252 }
253 }
254
255 // Start building current page
256 frames.setLastY(frames.getLastY() + 20);
257 // Add Settings of the current page
258 PageDescriptor pd = _pages.get(page);
259 if (pd == null) {
260 frames.save();
261 return;
262 }
263
264
265 Iterator<String> keys = pd.orderedEntries.stream().map(t -> t.toLowerCase()).iterator();
266 while(keys.hasNext()) {
267 String key = keys.next();
268 Setting setting = pd.settings.get(key);
269 if (setting == null) {
270 continue;
271 }
272
273 // Keep track of were we are placing items on Frames.
274 int x = 0, y = 0;
275
276 if (key.equals("pass")) {
277 // Special case for Password widgets
278 Text passwordWidgetText = frames.addText("iw: org.expeditee.items.widgets.Passwsord", null, null, null, false);
279 Password pw = new Password(passwordWidgetText, null);
280 pw.setPassword("");
281 frames.getCurrentFrame().removeItem(passwordWidgetText);
282 frames.getCurrentFrame().addAllItems(pw.getItems());
283 x = passwordWidgetText.getX() + passwordWidgetText.getBoundsWidth();
284 y = passwordWidgetText.getY();
285 } else {
286 // Determine the content for a setting label.
287 String name = key.substring(0, 1).toUpperCase() + key.substring(1);
288
289 // Construct and add text representation for setting.
290 // If a setting has no initialised value then it is not included.
291 Text settingRepresentation = setting.generateRepresentation(name, frames.getCurrentFrame().getFramesetName()).copy();
292 if (settingRepresentation.getBounds() == null) {
293 continue;
294 }
295 settingRepresentation.setID(frames.getCurrentFrame().getNextItemID());
296 frames.addItem(settingRepresentation, false);
297 x = settingRepresentation.getX() + settingRepresentation.getBoundsWidth();
298 y = settingRepresentation.getY();
299 }
300
301 x = Math.max(250, x + 20);
302 // Add tooltip for setting
303 Text tooltip = frames.getCurrentFrame().addText(x, y, "// " + setting.getTooltip(), null);
304 tooltip.rebuild(true);
305 if (tooltip.getY() + tooltip.getBoundsHeight() > frames.getLastY()) {
306 frames.setLastY(tooltip.getY() + tooltip.getBoundsHeight());
307 }
308 }
309
310 frames.save();
311 }
312}
Note: See TracBrowser for help on using the repository browser.