001: /* CredentialAvatar
002: *
003: * Created on Apr 23, 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.credential;
024:
025: import java.io.Serializable;
026: import java.util.Iterator;
027: import java.util.List;
028: import java.util.logging.Logger;
029:
030: import javax.management.AttributeNotFoundException;
031:
032: import org.archive.crawler.datamodel.CrawlURI;
033: import org.archive.crawler.datamodel.CredentialStore;
034: import org.archive.crawler.settings.SettingsHandler;
035:
036: /**
037: * A credential representation.
038: *
039: * Added to the CrawlServer upon successful authentication. Used as a marker
040: * of successful authentication event and for carrying credential
041: * payload to be used subsequently doing preemptive authentications (e.g.
042: * For case of RFC2617, needs to be offered everytime we're accessing inside
043: * a protected area). Also carried by the CrawlURI when cycling through
044: * processing chain trying a credential to see if it will authenticate.
045: *
046: * <p>This class exists because its not safe to keep references
047: * to the settings derived Credential classes so instead of keeping references
048: * to credential classes, we carry around this avatar.
049: *
050: * <p>Scope for avatars is crawlserver. Only used within a CrawlServer
051: * scope.
052: *
053: * <p>Immutable.
054: *
055: * @author stack
056: * @version $Revision: 4668 $, $Date: 2006-09-26 21:49:01 +0000 (Tue, 26 Sep 2006) $
057: */
058: public class CredentialAvatar implements Serializable {
059:
060: private static final long serialVersionUID = 4489542750898404807L;
061:
062: private static final Logger logger = Logger
063: .getLogger(CredentialAvatar.class.getName());
064:
065: /**
066: * Key for this credential avatar.
067: */
068: private final String key;
069:
070: /**
071: * Type represented by this avatar.
072: */
073: private final Class type;
074:
075: /**
076: * Data.
077: *
078: * May be null.
079: *
080: * <p>This used to be an Object and I used to store in here
081: * the httpclient AuthScheme but AuthScheme is not serializable
082: * and so there'd be trouble getting this payload to lie down
083: * in a bdb database. Changed it to String. That should be
084: * generic enough for credential purposes.
085: */
086: private final String payload;
087:
088: /**
089: * Constructor.
090: * @param type Type for this credential avatar.
091: * @param key Key for this credential avatar.
092: */
093: public CredentialAvatar(Class type, String key) {
094: this (type, key, null);
095: }
096:
097: /**
098: * Constructor.
099: * @param type Type for this credential avatar.
100: * @param key Key for this credential avatar.
101: * @param payload Data credential needs rerunning or preempting. May be
102: * null and then just the presence is used as signifier of successful
103: * auth.
104: */
105: public CredentialAvatar(Class type, String key, String payload) {
106: if (!checkType(type)) {
107: throw new IllegalArgumentException("Type is unrecognized: "
108: + type);
109: }
110: this .key = key;
111: this .type = type;
112: this .payload = payload;
113: }
114:
115: /**
116: * Shutdown default constructor.
117: */
118: private CredentialAvatar() {
119: super ();
120: this .key = null;
121: this .type = null;
122: this .payload = null;
123: }
124:
125: /**
126: * @param candidateType Type to check.
127: * @return True if this is a known credential type.
128: */
129: protected boolean checkType(Class candidateType) {
130: boolean result = false;
131: List types = CredentialStore.getCredentialTypes();
132: for (Iterator i = types.iterator(); i.hasNext();) {
133: if (((Class) i.next()).equals(candidateType)) {
134: result = true;
135: break;
136: }
137: }
138: return result;
139: }
140:
141: /**
142: * @return Returns the payload. May be null.
143: */
144: public String getPayload() {
145: return this .payload;
146: }
147:
148: /**
149: * @return Returns the key.
150: */
151: public String getKey() {
152: return this .key;
153: }
154:
155: /**
156: * @return Type represented by this avatar.
157: */
158: public Class getType() {
159: return this .type;
160: }
161:
162: /**
163: * @param otherType Class to match.
164: * @return True if this credential avatar is of same type.
165: */
166: public boolean match(Class otherType) {
167: return this .type.equals(otherType);
168: }
169:
170: /**
171: * @param otherType Credential to match.
172: * @param otherKey Key to test.
173: * @return True if this is avatar for passed credential.
174: */
175: public boolean match(Class otherType, String otherKey) {
176: return match(otherType)
177: && (otherKey != null && this .key != null && this .key
178: .equals(otherKey));
179: }
180:
181: public String toString() {
182: return getType() + "." + this .getKey();
183: }
184:
185: /**
186: * @param handler Settings handler.
187: * @param curi CrawlURI to use for context.
188: * @return The credential this avatar represents.
189: */
190: public Credential getCredential(SettingsHandler handler,
191: CrawlURI curi) {
192: Credential result = null;
193:
194: CredentialStore cs = CredentialStore
195: .getCredentialStore(handler);
196: if (cs == null) {
197: logger.severe("No credential store for " + curi);
198: return result;
199: }
200:
201: Iterator i = cs.iterator(curi);
202: if (i == null) {
203: logger.severe("Have CredentialAvatar " + toString()
204: + " but no iterator: " + curi);
205: return result;
206: }
207:
208: while (i.hasNext()) {
209: Credential c = (Credential) i.next();
210: if (!this .type.isInstance(c)) {
211: continue;
212: }
213: String credKey = null;
214: try {
215: credKey = c.getKey(curi);
216: } catch (AttributeNotFoundException e) {
217: logger.severe("Failed to get key for " + c + " from "
218: + curi);
219: }
220: if (credKey != null && credKey.equals(getKey())) {
221: result = c;
222: break;
223: }
224: }
225:
226: if (result == null) {
227: logger.severe("Have CredentialAvatar " + toString()
228: + " but no corresponding credential: " + curi);
229: }
230:
231: return result;
232: }
233: }
|