001: package edu.indiana.lib.osid.base.repository.http;
002:
003: import edu.indiana.lib.osid.base.repository.*;
004:
005: import edu.indiana.lib.twinpeaks.net.*;
006: import edu.indiana.lib.twinpeaks.search.*;
007: import edu.indiana.lib.twinpeaks.util.*;
008:
009: import java.io.*;
010: import java.net.*;
011: import java.lang.*;
012: import java.util.*;
013:
014: import javax.xml.parsers.*;
015:
016: import org.w3c.dom.*;
017: import org.w3c.dom.html.*;
018: import org.xml.sax.*;
019:
020: public class Repository extends
021: edu.indiana.lib.osid.base.repository.Repository {
022: private static org.apache.commons.logging.Log _log = edu.indiana.lib.twinpeaks.util.LogUtils
023: .getLog(Repository.class);
024:
025: private java.util.Vector assetVector = new java.util.Vector();
026:
027: private org.osid.id.IdManager idManager = null;
028: private org.osid.shared.Id id = null;
029: private String idString = null;
030:
031: private String displayName = null;
032: private String description = null;
033:
034: private String url = null;
035:
036: private org.osid.shared.Type repositoryType = new Type(
037: "sakaibrary", "repository", "metasearch");
038: private org.osid.shared.Type assetType = new Type("mit.edu",
039: "asset", "library_content");
040: private org.osid.shared.Type thumbnailType = new Type("mit.edu",
041: "partStructure", "thumbnail");
042: private org.osid.shared.Type urlType = new Type("mit.edu",
043: "partStructure", "URL");
044:
045: private java.util.Vector searchTypeVector = new java.util.Vector();
046: private java.util.Vector queryHandlerVector = new java.util.Vector();
047: private java.util.Vector responseHandlerVector = new java.util.Vector();
048:
049: private AssetIterator assetIterator = null;
050:
051: private org.osid.shared.Type searchPropertiesType = new Type(
052: "sakaibrary", "properties", "asynchMetasearch");
053: private org.osid.shared.Type searchStatusPropertiesType = new Type(
054: "sakaibrary", "properties", "metasearchStatus");
055:
056: private org.osid.shared.Properties searchStatusProperties = null;
057: private org.osid.shared.Properties searchProperties = null;
058:
059: protected Repository(String displayName, String description,
060: String idString, java.util.Vector searchTypeVector,
061: java.util.Vector queryHandlerVector,
062: java.util.Vector responseHandlerVector,
063: org.osid.id.IdManager idManager)
064: throws org.osid.repository.RepositoryException {
065: this .displayName = displayName;
066: this .description = description;
067: this .idString = idString;
068: this .searchTypeVector = searchTypeVector;
069: this .queryHandlerVector = queryHandlerVector;
070: this .responseHandlerVector = responseHandlerVector;
071: this .idManager = idManager;
072: this .id = null;
073:
074: try {
075: this .id = idManager.getId(this .idString);
076: } catch (Throwable t) {
077: _log.error(t.getMessage());
078: }
079: _log.debug("new HTTP Repository(): " + displayName + ", id: "
080: + this .id);
081: }
082:
083: public String getDisplayName()
084: throws org.osid.repository.RepositoryException {
085: return this .displayName;
086: }
087:
088: public String getDescription()
089: throws org.osid.repository.RepositoryException {
090: return this .description;
091: }
092:
093: public org.osid.shared.Id getId()
094: throws org.osid.repository.RepositoryException {
095: return this .id;
096: }
097:
098: public org.osid.shared.Type getType()
099: throws org.osid.repository.RepositoryException {
100: return this .repositoryType;
101: }
102:
103: public org.osid.shared.TypeIterator getAssetTypes()
104: throws org.osid.repository.RepositoryException {
105: java.util.Vector results = new java.util.Vector();
106: try {
107: results.addElement(this .assetType);
108: return new TypeIterator(results);
109: } catch (Throwable t) {
110: _log.error(t.getMessage());
111: throw new org.osid.repository.RepositoryException(
112: org.osid.OsidException.OPERATION_FAILED);
113: }
114: }
115:
116: public org.osid.repository.RecordStructureIterator getRecordStructures()
117: throws org.osid.repository.RepositoryException {
118: java.util.Vector results = new java.util.Vector();
119: results.addElement(RecordStructure.getInstance());
120: return new RecordStructureIterator(results);
121: }
122:
123: public org.osid.repository.RecordStructureIterator getMandatoryRecordStructures(
124: org.osid.shared.Type assetType)
125: throws org.osid.repository.RepositoryException {
126: if (assetType == null) {
127: throw new org.osid.repository.RepositoryException(
128: org.osid.shared.SharedException.NULL_ARGUMENT);
129: }
130: if (assetType.isEqual(this .assetType)) {
131: java.util.Vector results = new java.util.Vector();
132: results.addElement(RecordStructure.getInstance());
133: return new RecordStructureIterator(results);
134: }
135: throw new org.osid.repository.RepositoryException(
136: org.osid.shared.SharedException.UNKNOWN_TYPE);
137: }
138:
139: public org.osid.shared.TypeIterator getSearchTypes()
140: throws org.osid.repository.RepositoryException {
141: java.util.Vector results = new java.util.Vector();
142: try {
143: return new TypeIterator(this .searchTypeVector);
144: } catch (Throwable t) {
145: _log.error(t.getMessage());
146: throw new org.osid.repository.RepositoryException(
147: org.osid.OsidException.OPERATION_FAILED);
148: }
149: }
150:
151: public org.osid.shared.TypeIterator getStatusTypes()
152: throws org.osid.repository.RepositoryException {
153: java.util.Vector results = new java.util.Vector();
154: try {
155: results.addElement(new Type("mit.edu", "asset", "valid"));
156: return new TypeIterator(results);
157: } catch (Throwable t) {
158: _log.error(t.getMessage());
159: throw new org.osid.repository.RepositoryException(
160: org.osid.OsidException.OPERATION_FAILED);
161: }
162: }
163:
164: public org.osid.shared.Type getStatus(org.osid.shared.Id assetId)
165: throws org.osid.repository.RepositoryException {
166: return new Type("mit.edu", "asset", "valid");
167: }
168:
169: public boolean validateAsset(org.osid.shared.Id assetId)
170: throws org.osid.repository.RepositoryException {
171: return true;
172: }
173:
174: public org.osid.repository.AssetIterator getAssetsBySearch(
175: java.io.Serializable searchCriteria,
176: org.osid.shared.Type searchType,
177: org.osid.shared.Properties searchProperties)
178: throws org.osid.repository.RepositoryException {
179: QueryBase queryBase;
180: SearchResultBase resultHandler;
181: SessionContext sessionContext;
182:
183: if (searchCriteria == null) {
184: throw new org.osid.repository.RepositoryException(
185: org.osid.shared.SharedException.NULL_ARGUMENT);
186: }
187:
188: if (!(searchCriteria instanceof String)) {
189: throw new org.osid.repository.RepositoryException(
190: org.osid.OsidException.OPERATION_FAILED);
191: }
192:
193: if (searchType == null) {
194: throw new org.osid.repository.RepositoryException(
195: org.osid.shared.SharedException.NULL_ARGUMENT);
196: }
197:
198: if (searchProperties == null) {
199: throw new org.osid.repository.RepositoryException(
200: org.osid.shared.SharedException.NULL_ARGUMENT);
201: }
202:
203: try {
204: org.osid.shared.Type type;
205: String criteria;
206: String sessionId;
207: boolean doRange;
208:
209: sessionId = (String) searchProperties.getProperty("guid");
210: if (StringUtils.isNull(sessionId)) {
211: throw new org.osid.repository.RepositoryException(
212: org.osid.shared.SharedException.NULL_ARGUMENT);
213: }
214:
215: /*
216: doRange = "rangeRequest".equalsIgnoreCase((String) searchProperties.getProperty("action"));
217: if ((doRange) && (assetIterator == null))
218: {
219: throw new org.osid.repository.RepositoryException("Initial search cannot be a range request");
220: }
221: */
222: doRange = false;
223:
224: type = (org.osid.shared.Type) (this .searchTypeVector
225: .elementAt(0));
226: if (!type.isEqual(searchType)) {
227: throw new org.osid.repository.RepositoryException(
228: org.osid.shared.SharedException.UNKNOWN_TYPE);
229: }
230:
231: this .searchProperties = searchProperties;
232:
233: criteria = (String) searchCriteria;
234: sessionContext = SessionContext.getInstance(sessionId);
235: queryBase = doQuery(criteria, this .getDisplayName(),
236: searchProperties, sessionContext);
237: resultHandler = getResponseHandler(queryBase);
238:
239: if (doRange) {
240: assetIterator.initialize(searchProperties);
241: } else {
242: assetIterator = new AssetIterator(
243: this .getDisplayName(), queryBase,
244: resultHandler, searchProperties, this .getId(),
245: sessionContext);
246: }
247: } catch (Throwable throwable) {
248: throwable.printStackTrace();
249: _log.error(throwable.getMessage());
250:
251: throw new org.osid.repository.RepositoryException(
252: org.osid.OsidException.OPERATION_FAILED);
253: }
254:
255: return assetIterator;
256: }
257:
258: public org.osid.repository.RecordStructureIterator getRecordStructuresByType(
259: org.osid.shared.Type recordStructureType)
260: throws org.osid.repository.RepositoryException {
261: if (recordStructureType == null) {
262: throw new org.osid.repository.RepositoryException(
263: org.osid.shared.SharedException.NULL_ARGUMENT);
264: }
265: if (recordStructureType.isEqual(new Type("mit.edu",
266: "recordStructure", "wellFormed"))) {
267: java.util.Vector results = new java.util.Vector();
268: // don't return the content's strucutre even if it matches, since this that is a separate and special case
269: results.addElement(RecordStructure.getInstance());
270: return new RecordStructureIterator(results);
271: }
272: throw new org.osid.repository.RepositoryException(
273: org.osid.shared.SharedException.UNKNOWN_TYPE);
274: }
275:
276: public org.osid.shared.PropertiesIterator getProperties()
277: throws org.osid.repository.RepositoryException {
278: java.util.Vector results = new java.util.Vector();
279:
280: try {
281: if (searchProperties != null) {
282: searchStatusProperties = getStatusProperties((String) searchProperties
283: .getProperty("guid"));
284:
285: results.addElement(searchProperties);
286: results.addElement(searchStatusProperties);
287: }
288:
289: return new PropertiesIterator(results);
290: } catch (Throwable throwable) {
291: _log.error(throwable.getMessage());
292: throw new org.osid.repository.RepositoryException(
293: org.osid.OsidException.OPERATION_FAILED);
294: }
295: }
296:
297: public org.osid.shared.Properties getPropertiesByType(
298: org.osid.shared.Type propertiesType)
299: throws org.osid.repository.RepositoryException {
300: if (propertiesType == null) {
301: throw new org.osid.repository.RepositoryException(
302: org.osid.shared.SharedException.NULL_ARGUMENT);
303: }
304:
305: try {
306: org.osid.shared.PropertiesIterator iterator = getProperties();
307:
308: while (iterator.hasNextProperties()) {
309: org.osid.shared.Properties properties = iterator
310: .nextProperties();
311:
312: if (properties.getType().isEqual(propertiesType)) {
313: return properties;
314: }
315: }
316: } catch (org.osid.shared.SharedException exception) {
317: throw new org.osid.repository.RepositoryException(
318: org.osid.OsidException.OPERATION_FAILED);
319: }
320: throw new org.osid.repository.RepositoryException(
321: org.osid.shared.SharedException.UNKNOWN_TYPE);
322: }
323:
324: public org.osid.shared.TypeIterator getPropertyTypes()
325: throws org.osid.repository.RepositoryException {
326: java.util.Vector results = new java.util.Vector();
327:
328: results.addElement(searchPropertiesType);
329: results.addElement(searchStatusPropertiesType);
330:
331: try {
332: return new TypeIterator(results);
333: } catch (Throwable t) {
334: _log.error(t.getMessage());
335: throw new org.osid.repository.RepositoryException(
336: org.osid.OsidException.OPERATION_FAILED);
337: }
338: }
339:
340: protected void addAsset(org.osid.repository.Asset asset)
341: throws org.osid.repository.RepositoryException {
342: this .assetVector.addElement(asset);
343: }
344:
345: public boolean supportsUpdate()
346: throws org.osid.repository.RepositoryException {
347: return false;
348: }
349:
350: public boolean supportsVersioning()
351: throws org.osid.repository.RepositoryException {
352: return false;
353: }
354:
355: /*
356: * Local Helpers
357: */
358:
359: /**
360: * Returns a new result set name for this transaction
361: * @param sessionId Session ID (guid)
362: * @return A shared Properties object reflecting the current status
363: */
364: private org.osid.shared.Properties getStatusProperties(
365: String sessionId)
366: throws org.osid.repository.RepositoryException {
367: SessionContext sessionContext;
368:
369: ArrayList dbList = new ArrayList();
370: HashMap statusMap = new HashMap();
371: String status = null;
372: int active = 0;
373: int hits = 0;
374: int estimate = 0;
375:
376: try {
377: sessionContext = SessionContext.getInstance(sessionId);
378:
379: for (Iterator iterator = StatusUtils
380: .getStatusMapEntrySetIterator(sessionContext); iterator
381: .hasNext();) {
382: Map.Entry entry = (Map.Entry) iterator.next();
383: HashMap targetMap = (HashMap) entry.getValue();
384: HashMap singleMap;
385: boolean targetActive;
386:
387: dbList.add(entry.getKey());
388: targetActive = false;
389:
390: status = (String) targetMap.get("STATUS");
391: if (status.equals("ACTIVE")) {
392: active++;
393: targetActive = true;
394: }
395: hits += Integer
396: .parseInt((String) targetMap.get("HITS"));
397: estimate += Integer.parseInt((String) targetMap
398: .get("ESTIMATE"));
399:
400: singleMap = new HashMap();
401:
402: singleMap.put("status", status);
403: singleMap.put("statusMessage", (String) targetMap
404: .get("STATUS_MESSAGE"));
405: singleMap.put("numRecordsFetched", new Integer(
406: (String) targetMap.get("HITS")));
407: singleMap.put("numRecordsFound", new Integer(
408: (String) targetMap.get("ESTIMATE")));
409: singleMap.put("numRecordsMerged", new Integer(0));
410:
411: statusMap.put(entry.getKey(), singleMap);
412: }
413:
414: _log.debug(this .getDisplayName() + ": " + active
415: + " searches active");
416:
417: statusMap.put("databaseNames", dbList);
418:
419: statusMap.put("status", sessionContext.get("STATUS"));
420: statusMap.put("statusMessage", sessionContext
421: .get("STATUS_MESSAGE"));
422:
423: statusMap.put("numRecordsFetched", new Integer(hits));
424: statusMap.put("numRecordsFound", new Integer(estimate));
425: statusMap.put("numRecordsMerged", new Integer(0));
426:
427: statusMap
428: .put("delayHint", new Integer((active * 2 * 1024)));
429:
430: return new SharedProperties(statusMap,
431: searchStatusPropertiesType);
432: } catch (Throwable throwable) {
433: _log.error(throwable.getMessage());
434: throw new org.osid.repository.RepositoryException(
435: org.osid.OsidException.OPERATION_FAILED);
436: }
437: }
438:
439: /**
440: * Select a query handler for the requested database
441: * @param sessionContext Session context
442: * @param name Database name (eg ERIC)
443: * @return Query handler
444: */
445: private QueryBase selectQueryHandler(SessionContext sessionContext,
446: String name) {
447: SearchSource source = SearchSource.getSourceByName(name);
448: QueryBase handler;
449:
450: try {
451: handler = source.getQueryHandler();
452: } catch (Exception exception) {
453: throw new SearchException(exception.toString());
454: }
455: /*
456: * Initialize and return the query handler
457: */
458: handler.initialize(sessionContext);
459: return handler;
460: }
461:
462: /**
463: * Execute an HTTP query for a standard search operation
464: * @param request The servlet request block for this transaction
465: * @param sessionContext Session context for this user
466: * @param database Database name
467: */
468: private QueryBase doQuery(String searchString, String database,
469: org.osid.shared.Properties searchProperties,
470: SessionContext sessionContext)
471: throws org.osid.repository.RepositoryException,
472: org.osid.shared.SharedException {
473: QueryBase query;
474: HashMap parameterMap;
475: ArrayList<String> targetList;
476: StringBuffer targetBuffer;
477:
478: parameterMap = new HashMap();
479: parameterMap.put("searchString", searchString);
480: parameterMap.put("database", database);
481:
482: parameterMap.put("guid", searchProperties.getProperty("guid"));
483: parameterMap
484: .put("url", searchProperties.getProperty("baseUrl"));
485: parameterMap.put("username", searchProperties
486: .getProperty("username"));
487: parameterMap.put("password", searchProperties
488: .getProperty("password"));
489: parameterMap.put("sortBy", searchProperties
490: .getProperty("sortBy"));
491: parameterMap.put("pageSize", searchProperties
492: .getProperty("pageSize"));
493: parameterMap.put("startRecord", searchProperties
494: .getProperty("startRecord"));
495: parameterMap.put("maxRecords", searchProperties
496: .getProperty("maxRecords"));
497:
498: parameterMap.put("action", "startSearch"); // or "requestRange"
499: /*
500: * Add in the target database list
501: */
502: targetBuffer = new StringBuffer();
503: targetList = (java.util.ArrayList<String>) searchProperties
504: .getProperty("databaseIds");
505:
506: for (int i = 0; i < targetList.size(); i++) {
507: if (i > 0) {
508: targetBuffer.append(' ');
509: }
510: targetBuffer.append(targetList.get(i));
511: }
512: parameterMap.put("targets", targetBuffer.toString());
513: /*
514: * Allow the embedded configuration to override the URL, username and password
515: */
516: if (SearchSource.getConfiguredParameter(database, "url") != null) {
517: parameterMap.put("url", SearchSource
518: .getConfiguredParameter(database, "url"));
519: }
520:
521: if (SearchSource.getConfiguredParameter(database, "username") != null) {
522: parameterMap.put("username", SearchSource
523: .getConfiguredParameter(database, "username"));
524: }
525:
526: if (SearchSource.getConfiguredParameter(database, "password") != null) {
527: parameterMap.put("password", SearchSource
528: .getConfiguredParameter(database, "password"));
529: }
530:
531: query = selectQueryHandler(sessionContext, database);
532: query.parseRequest(parameterMap);
533: query.doQuery();
534:
535: return query;
536: }
537:
538: /**
539: * Select a search result handler for this source
540: * @param name Source name
541: * @return Search result handler
542: */
543: private SearchResultBase selectSearchResultHandler(String name) {
544: SearchSource source = SearchSource.getSourceByName(name);
545: SearchResultBase handler;
546:
547: try {
548: handler = source.getSearchResultHandler();
549: } catch (Exception exception) {
550: throw new SearchException(exception.toString());
551: }
552: return handler;
553: }
554:
555: /**
556: * Locate the appropriate response handler
557: * @param query Query handler
558: */
559: private SearchResultBase getResponseHandler(QueryBase query) {
560: SearchResultBase searchResult;
561:
562: searchResult = selectSearchResultHandler(query
563: .getRequestParameter("database"));
564: return searchResult;
565: }
566: }
|