001: /* CredentialStore
002: *
003: * Created on Apr 1, 2004
004: *
005: * Copyright (C) 2004 Internet Archive.
006: *
007: * This file is part of the Heritrix web crawler (crawler.archive.org).
008: *
009: * Heritrix is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU Lesser Public License as published by
011: * the Free Software Foundation; either version 2.1 of the License, or
012: * any later version.
013: *
014: * Heritrix is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
017: * GNU Lesser Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser Public License
020: * along with Heritrix; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
022: */
023: package org.archive.crawler.datamodel;
024:
025: import java.lang.reflect.InvocationTargetException;
026: import java.util.Arrays;
027: import java.util.Collections;
028: import java.util.HashSet;
029: import java.util.Iterator;
030: import java.util.List;
031: import java.util.Set;
032: import java.util.logging.Logger;
033:
034: import javax.management.AttributeNotFoundException;
035: import javax.management.InvalidAttributeValueException;
036: import javax.management.MBeanException;
037: import javax.management.ReflectionException;
038:
039: import org.archive.crawler.datamodel.credential.Credential;
040: import org.archive.crawler.datamodel.credential.HtmlFormCredential;
041: import org.archive.crawler.datamodel.credential.Rfc2617Credential;
042: import org.archive.crawler.settings.CrawlerSettings;
043: import org.archive.crawler.settings.MapType;
044: import org.archive.crawler.settings.ModuleType;
045: import org.archive.crawler.settings.SettingsHandler;
046: import org.archive.crawler.settings.Type;
047:
048: /**
049: * Front door to the credential store.
050: *
051: * Come here to get at credentials.
052: *
053: * <p>See <a
054: * href="http://crawler.archive.org/proposals/auth/#credentialstoredesign">Credential
055: * Store Design</a>.
056: *
057: * @author stack
058: * @version $Revision: 4656 $, $Date: 2006-09-25 21:34:50 +0000 (Mon, 25 Sep 2006) $
059: */
060: public class CredentialStore extends ModuleType {
061:
062: private static final long serialVersionUID = -7916979754932063634L;
063:
064: private static Logger logger = Logger
065: .getLogger("org.archive.crawler.datamodel.CredentialStore");
066:
067: public static final String ATTR_NAME = "credential-store";
068:
069: /**
070: * Name of the contained credentials map type.
071: */
072: public static final String ATTR_CREDENTIALS = "credentials";
073:
074: /**
075: * List of possible credential types as a List.
076: *
077: * This types are inner classes of this credential type so they cannot
078: * be created without their being associated with a credential list.
079: */
080: private static final List credentialTypes;
081: // Initialize the credentialType data member.
082: static {
083: // Array of all known credential types.
084: Class[] tmp = { HtmlFormCredential.class,
085: Rfc2617Credential.class };
086: credentialTypes = Collections.unmodifiableList(Arrays
087: .asList(tmp));
088: }
089:
090: /**
091: * Constructor.
092: *
093: * @param name for this credential store.
094: */
095: public CredentialStore(String name) {
096: super (
097: name,
098: "Credentials used by heritrix"
099: + " authenticating. See http://crawler.archive.org/proposals/auth/"
100: + " for background.");
101:
102: Type t = addElementToDefinition(new MapType(ATTR_CREDENTIALS,
103: "Map of credentials.", Credential.class));
104: t.setOverrideable(true);
105: t.setExpertSetting(true);
106: }
107:
108: /**
109: * @return Unmodifable list of credential types.
110: */
111: public static List getCredentialTypes() {
112: return CredentialStore.credentialTypes;
113: }
114:
115: /**
116: * Get a credential store reference.
117: * @param context A settingshandler object.
118: * @return A credential store or null if we failed getting one.
119: */
120: public static CredentialStore getCredentialStore(
121: SettingsHandler context) {
122:
123: CredentialStore cs = null;
124:
125: try {
126: cs = (CredentialStore) context.getOrder().getAttribute(
127: CredentialStore.ATTR_NAME);
128: } catch (AttributeNotFoundException e) {
129: logger.severe("Failed to get credential store: "
130: + e.getMessage());
131: } catch (MBeanException e) {
132: logger.severe("Failed to get credential store: "
133: + e.getMessage());
134: } catch (ReflectionException e) {
135: logger.severe("Failed to get credential store: "
136: + e.getMessage());
137: }
138:
139: return cs;
140: }
141:
142: /**
143: * @param context Pass a CrawlURI, CrawlerSettings or UURI. Used to set
144: * context. If null, we use global context.
145: * @return A map of all credentials from passed context.
146: * @throws AttributeNotFoundException
147: */
148: protected MapType get(Object context)
149: throws AttributeNotFoundException {
150:
151: return (MapType) getAttribute(context, ATTR_CREDENTIALS);
152: }
153:
154: /**
155: * @param context Pass a CrawlURI, CrawlerSettings or UURI. Used to set
156: * context. If null, we use global context.
157: * @return An iterator or null.
158: */
159: public Iterator iterator(Object context) {
160:
161: MapType m = null;
162: try {
163: m = (MapType) getAttribute(context, ATTR_CREDENTIALS);
164: } catch (AttributeNotFoundException e) {
165: logger.severe("Failed get credentials: " + e.getMessage());
166: }
167: return (m == null) ? null : m.iterator(context);
168: }
169:
170: /**
171: * @param context Pass a CrawlURI, CrawlerSettings or UURI. Used to set
172: * context. If null, we use global context.
173: * @param name Name to give the manufactured credential. Should be unique
174: * else the add of the credential to the list of credentials will fail.
175: * @return Returns <code>name</code>'d credential.
176: * @throws AttributeNotFoundException
177: * @throws MBeanException
178: * @throws ReflectionException
179: */
180: public Credential get(Object context, String name)
181: throws AttributeNotFoundException, MBeanException,
182: ReflectionException {
183:
184: return (Credential) get(context).getAttribute(name);
185: }
186:
187: /**
188: * Create and add to the list a credential of the passed <code>type</code>
189: * giving the credential the passed <code>name</code>.
190: *
191: * @param context Pass a CrawlerSettings. Used to set
192: * context. If null, we use global context.
193: * @param name Name to give the manufactured credential. Should be unique
194: * else the add of the credential to the list of credentials will fail.
195: * @param type Type of credentials to get.
196: * @return The credential created and added to the list of credentials.
197: * @throws IllegalArgumentException
198: * @throws AttributeNotFoundException
199: * @throws InvocationTargetException
200: * @throws InvalidAttributeValueException
201: */
202: public Credential create(CrawlerSettings context, String name,
203: Class type) throws IllegalArgumentException,
204: InvocationTargetException, InvalidAttributeValueException,
205: AttributeNotFoundException {
206:
207: Credential result = (Credential) SettingsHandler
208: .instantiateModuleTypeFromClassName(name, type
209: .getName());
210: // Now add the just-created credential to the list.
211: get(context).addElement(context, result);
212: return result;
213: }
214:
215: /**
216: * Delete the credential <code>name</code>.
217: *
218: * @param context Pass a CrawlerSettings. Used to set
219: * context. If null, we use global context.
220: * @param credential Credential to delete.
221: * @throws IllegalArgumentException
222: * @throws AttributeNotFoundException
223: */
224: public void remove(CrawlerSettings context, Credential credential)
225: throws AttributeNotFoundException, IllegalArgumentException {
226:
227: remove(context, credential.getName());
228: }
229:
230: /**
231: * Delete the credential <code>name</code>.
232: *
233: * @param context Pass a CrawlerSettings. Used to set
234: * context. If null, we use global context.
235: * @param name Name of credential to delete.
236: * @throws IllegalArgumentException
237: * @throws AttributeNotFoundException
238: */
239: public void remove(CrawlerSettings context, String name)
240: throws IllegalArgumentException, AttributeNotFoundException {
241:
242: get(context).removeElement(context, name);
243: }
244:
245: /**
246: * Return set made up of all credentials of the passed
247: * <code>type</code>.
248: *
249: * @param context Pass a CrawlURI or a CrawlerSettings. Used to set
250: * context. If null, we use global context.
251: * @param type Type of the list to return. Type is some superclass of
252: * credentials.
253: * @return Unmodifable sublist of all elements of passed type.
254: */
255: public Set subset(CrawlURI context, Class type) {
256: return subset(context, type, null);
257: }
258:
259: /**
260: * Return set made up of all credentials of the passed
261: * <code>type</code>.
262: *
263: * @param context Pass a CrawlURI or a CrawlerSettings. Used to set
264: * context. If null, we use global context.
265: * @param type Type of the list to return. Type is some superclass of
266: * credentials.
267: * @param rootUri RootUri to match. May be null. In this case we return
268: * all. Currently we expect the CrawlServer name to equate to root Uri.
269: * Its not. Currently it doesn't distingush between servers of same name
270: * but different ports (e.g. http and https).
271: * @return Unmodifable sublist of all elements of passed type.
272: */
273: public Set<Credential> subset(CrawlURI context, Class type,
274: String rootUri) {
275:
276: Set<Credential> result = null;
277: Iterator i = iterator(context);
278: if (i != null) {
279: while (i.hasNext()) {
280: Credential c = (Credential) i.next();
281: if (!type.isInstance(c)) {
282: continue;
283: }
284: if (rootUri != null) {
285: String cd = null;
286: try {
287: cd = c.getCredentialDomain(context);
288: } catch (AttributeNotFoundException e) {
289: logger.severe("Failed to get cred domain: "
290: + context + ": " + e.getMessage());
291: }
292: if (cd == null) {
293: continue;
294: }
295: if (!rootUri.equalsIgnoreCase(cd)) {
296: continue;
297: }
298: }
299: if (result == null) {
300: result = new HashSet<Credential>();
301: }
302: result.add(c);
303: }
304: }
305: return result;
306: }
307: }
|