001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.console.securitymanager.realm;
017:
018: import java.io.Serializable;
019: import java.io.InputStream;
020: import java.io.IOException;
021: import java.util.List;
022: import java.util.ArrayList;
023: import java.util.Properties;
024: import java.util.Iterator;
025: import java.util.Map;
026: import java.util.HashMap;
027: import java.util.Collections;
028: import java.util.Comparator;
029: import org.apache.commons.logging.Log;
030: import org.apache.commons.logging.LogFactory;
031:
032: /**
033: * Describes an available login module, including how to create and configure it.
034: * Reads the list of available login modules from a properties file on the class path.
035: *
036: * @version $Rev: 611338 $ $Date: 2008-01-11 16:42:22 -0800 (Fri, 11 Jan 2008) $
037: */
038: public class MasterLoginModuleInfo implements Serializable {
039: private final static Log log = LogFactory
040: .getLog(MasterLoginModuleInfo.class);
041: private static MasterLoginModuleInfo[] allModules;
042: private String name;
043: private String className;
044: private boolean testable = true;
045: private OptionInfo[] options = new OptionInfo[0];
046:
047: private MasterLoginModuleInfo(String name, String className) {
048: this .name = name;
049: this .className = className;
050: }
051:
052: public OptionInfo[] getOptions() {
053: return options;
054: }
055:
056: public Map getOptionMap() {
057: Map map = new HashMap();
058: for (int i = 0; i < options.length; i++) {
059: OptionInfo info = options[i];
060: map.put(info.getName(), info);
061: }
062: return map;
063: }
064:
065: public String getName() {
066: return name;
067: }
068:
069: public String getClassName() {
070: return className;
071: }
072:
073: public boolean isTestable() {
074: return testable;
075: }
076:
077: private void setTestable(boolean testable) {
078: this .testable = testable;
079: }
080:
081: private void setOptions(OptionInfo[] options) {
082: this .options = options;
083: }
084:
085: public static MasterLoginModuleInfo[] getAllModules() {
086: if (allModules == null) {
087: allModules = loadModules();
088: }
089: return allModules;
090: }
091:
092: private static MasterLoginModuleInfo[] loadModules() {
093: List list = new ArrayList();
094: Map map = new HashMap(), fieldMap = new HashMap();
095: InputStream in = MasterLoginModuleInfo.class
096: .getResourceAsStream("/login-modules.properties");
097: if (in == null) {
098: log.error("Unable to locate login module properties file");
099: return null;
100: }
101: Properties props = new Properties();
102: try {
103: props.load(in);
104: } catch (IOException e) {
105: log.error("Unable to read login module properties file", e);
106: } finally {
107: try {
108: in.close();
109: } catch (java.io.IOException ignored) {
110: // ignore
111: }
112: }
113: for (Iterator it = props.keySet().iterator(); it.hasNext();) {
114: String key = (String) it.next();
115: if (key.startsWith("module.")) {
116: String name = key.substring(7, key.indexOf('.', 7));
117: MasterLoginModuleInfo info = (MasterLoginModuleInfo) map
118: .get(name);
119: if (info == null) {
120: info = new MasterLoginModuleInfo(props
121: .getProperty("module." + name + ".name"),
122: props.getProperty("module." + name
123: + ".class"));
124: String test = props.getProperty("module." + name
125: + ".testable");
126: if (test != null) {
127: info.setTestable(new Boolean(test.trim())
128: .booleanValue());
129: }
130: map.put(name, info);
131: list.add(info);
132: }
133: String prefix = "module." + name + ".field.";
134: if (key.startsWith(prefix)) {
135: String fieldName = key.substring(prefix.length(),
136: key.indexOf('.', prefix.length()));
137: List fields = (List) fieldMap.get(name);
138: if (fields == null) {
139: fields = new ArrayList();
140: fieldMap.put(name, fields);
141: }
142: OptionInfo option = null;
143: for (int i = 0; i < fields.size(); i++) {
144: OptionInfo opt = (OptionInfo) fields.get(i);
145: if (opt.getName().equals(fieldName)) {
146: option = opt;
147: break;
148: }
149: }
150: if (option == null) {
151: option = new OptionInfo(fieldName, props
152: .getProperty(prefix + fieldName
153: + ".displayName"), props
154: .getProperty(prefix + fieldName
155: + ".description"));
156: String test = props.getProperty(prefix
157: + fieldName + ".password");
158: if (test != null) {
159: option.setPassword(true);
160: }
161: test = props.getProperty(prefix + fieldName
162: + ".length");
163: if (test != null) {
164: option.setLength(Integer.parseInt(test
165: .trim()));
166: }
167: test = props.getProperty(prefix + fieldName
168: + ".displayOrder");
169: if (test != null) {
170: option.setDisplayOrder(Integer
171: .parseInt(test.trim()));
172: }
173: test = props.getProperty(prefix + fieldName
174: + ".blankAllowed");
175: if (test != null) {
176: option.setBlankAllowed("true"
177: .equalsIgnoreCase(test.trim()));
178: }
179: fields.add(option);
180: }
181: }
182: }
183: }
184: for (Iterator it = map.keySet().iterator(); it.hasNext();) {
185: String name = (String) it.next();
186: MasterLoginModuleInfo info = (MasterLoginModuleInfo) map
187: .get(name);
188: List fields = (List) fieldMap.get(name);
189: if (fields != null) {
190: Collections.sort(fields);
191: info.setOptions((OptionInfo[]) fields
192: .toArray(new OptionInfo[fields.size()]));
193: }
194: }
195: Collections.sort(list, new Comparator() {
196: public int compare(Object o1, Object o2) {
197: MasterLoginModuleInfo m1 = (MasterLoginModuleInfo) o1, m2 = (MasterLoginModuleInfo) o2;
198: if (m1.getName().equals("Other")) {
199: return 1;
200: } else if (m2.getName().equals("Other")) {
201: return -1;
202: } else {
203: return m1.getName().compareTo(m2.getName());
204: }
205: }
206: });
207: return (MasterLoginModuleInfo[]) list
208: .toArray(new MasterLoginModuleInfo[list.size()]);
209: }
210:
211: public final static class OptionInfo implements Serializable,
212: Comparable {
213: private final String name;
214: private final String displayName;
215: private final String description;
216: private boolean password = false;
217: private int length = 30;
218: private int displayOrder = 1;
219: private boolean blankAllowed = false;
220:
221: public OptionInfo(String name, String displayName,
222: String description) {
223: this .name = name;
224: this .displayName = displayName;
225: this .description = description;
226: }
227:
228: public String getName() {
229: return name;
230: }
231:
232: public String getDisplayName() {
233: return displayName;
234: }
235:
236: public String getDescription() {
237: return description;
238: }
239:
240: public boolean isPassword() {
241: return password;
242: }
243:
244: public void setPassword(boolean password) {
245: this .password = password;
246: }
247:
248: public int getLength() {
249: return length;
250: }
251:
252: public void setLength(int length) {
253: this .length = length;
254: }
255:
256: public int getDisplayOrder() {
257: return displayOrder;
258: }
259:
260: public void setDisplayOrder(int displayOrder) {
261: this .displayOrder = displayOrder;
262: }
263:
264: public int compareTo(Object o) {
265: return displayOrder - ((OptionInfo) o).displayOrder;
266: }
267:
268: public boolean isBlankAllowed() {
269: return this .blankAllowed;
270: }
271:
272: public void setBlankAllowed(boolean blankAllowed) {
273: this.blankAllowed = blankAllowed;
274: }
275: }
276: }
|