001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/search/tags/sakai_2-4-1/search-impl/impl/src/java/org/sakaiproject/search/component/service/impl/SearchListResponseImpl.java $
003: * $Id: SearchListResponseImpl.java 22719 2007-03-16 00:59:10Z dlhaines@umich.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.search.component.service.impl;
021:
022: import java.io.IOException;
023: import java.io.StringReader;
024: import java.util.ArrayList;
025: import java.util.Collection;
026: import java.util.Iterator;
027: import java.util.List;
028: import java.util.ListIterator;
029: import java.util.Stack;
030:
031: import org.apache.commons.logging.Log;
032: import org.apache.commons.logging.LogFactory;
033: import org.apache.lucene.analysis.Analyzer;
034: import org.apache.lucene.search.Query;
035: import org.sakaiproject.search.api.SearchIndexBuilder;
036: import org.sakaiproject.search.api.SearchList;
037: import org.sakaiproject.search.api.SearchResult;
038: import org.sakaiproject.search.api.SearchService;
039: import org.sakaiproject.search.filter.SearchItemFilter;
040: import org.xml.sax.Attributes;
041: import org.xml.sax.ContentHandler;
042: import org.xml.sax.InputSource;
043: import org.xml.sax.Locator;
044: import org.xml.sax.SAXException;
045: import org.xml.sax.XMLReader;
046: import org.xml.sax.helpers.AttributesImpl;
047: import org.xml.sax.helpers.XMLReaderFactory;
048:
049: /**
050: * @author ieb
051: */
052: public class SearchListResponseImpl implements SearchList,
053: ContentHandler {
054:
055: private static Log log = LogFactory
056: .getLog(SearchListResponseImpl.class);
057:
058: private Query query;
059:
060: private int start = 0;
061:
062: private int end = 500;
063:
064: private Analyzer analyzer;
065:
066: private SearchItemFilter filter;
067:
068: private SearchIndexBuilder searchIndexBuilder;
069:
070: private SearchService searchService;
071:
072: private List resultsList;
073:
074: private Stack stack;
075:
076: private Object errorMessage;
077:
078: private int size;
079:
080: private int fullsize;
081:
082: public SearchListResponseImpl(String response, Query query,
083: int start, int end, Analyzer analyzer,
084: SearchItemFilter filter,
085: SearchIndexBuilder searchIndexBuilder,
086: SearchService searchService) throws SAXException,
087: IOException {
088:
089: this .query = query;
090: this .start = start;
091: this .end = end;
092: this .analyzer = analyzer;
093: this .filter = filter;
094: this .searchIndexBuilder = searchIndexBuilder;
095: this .searchService = searchService;
096:
097: if (log.isDebugEnabled()) {
098: log.debug("search response: [" + response + "]");
099: }
100:
101: XMLReader xr = XMLReaderFactory.createXMLReader();
102: xr.setContentHandler(this );
103: InputSource is = new InputSource(new StringReader(response));
104: xr.parse(is);
105:
106: if (errorMessage != null) {
107: log
108: .error("Failed to perform remote request, remote exception was: \n"
109: + errorMessage);
110: throw new IOException("Failed to perform remote request ");
111: }
112:
113: }
114:
115: /**
116: * @{inheritDoc}
117: */
118: public Iterator iterator(final int startAt) {
119: return new Iterator() {
120: int counter = Math.max(startAt, start) - start;
121:
122: public boolean hasNext() {
123: return counter < resultsList.size();
124: }
125:
126: public Object next() {
127:
128: int this Hit = counter;
129: counter++;
130: if (log.isDebugEnabled()) {
131: log.debug("Iterator Getting item " + this Hit);
132: }
133: return filter.filter((SearchResult) resultsList
134: .get(this Hit));
135: }
136:
137: public void remove() {
138: throw new UnsupportedOperationException(
139: "Not Implemented");
140: }
141:
142: };
143: }
144:
145: public int size() {
146: return size;
147: }
148:
149: public int getFullSize() {
150: return fullsize;
151: }
152:
153: public boolean isEmpty() {
154: return (size() == 0);
155: }
156:
157: public boolean contains(Object arg0) {
158: throw new UnsupportedOperationException("Not Implemented");
159: }
160:
161: public Iterator iterator() {
162: return iterator(0);
163: }
164:
165: public Object[] toArray() {
166: Object[] o = new Object[size()];
167: for (int i = 0; i < o.length; i++) {
168:
169: o[i] = filter.filter((SearchResult) resultsList.get(i));
170: }
171: return o;
172: }
173:
174: public Object[] toArray(Object[] arg0) {
175: if (arg0 instanceof SearchResult[]) {
176: return toArray();
177: }
178: return null;
179: }
180:
181: public boolean add(Object arg0) {
182: throw new UnsupportedOperationException("Not Implemented");
183: }
184:
185: public boolean remove(Object arg0) {
186: throw new UnsupportedOperationException("Not Implemented");
187: }
188:
189: public boolean containsAll(Collection arg0) {
190: throw new UnsupportedOperationException("Not Implemented");
191: }
192:
193: public boolean addAll(Collection arg0) {
194: throw new UnsupportedOperationException("Not Implemented");
195: }
196:
197: public boolean addAll(int arg0, Collection arg1) {
198: throw new UnsupportedOperationException("Not Implemented");
199: }
200:
201: public boolean removeAll(Collection arg0) {
202: throw new UnsupportedOperationException("Not Implemented");
203: }
204:
205: public boolean retainAll(Collection arg0) {
206: throw new UnsupportedOperationException("Not Implemented");
207: }
208:
209: public void clear() {
210: throw new UnsupportedOperationException("Not Implemented");
211: }
212:
213: public Object get(int arg0) {
214: return filter.filter((SearchResult) resultsList.get(arg0));
215: }
216:
217: public Object set(int arg0, Object arg1) {
218: throw new UnsupportedOperationException("Not Implemented");
219: }
220:
221: public void add(int arg0, Object arg1) {
222: throw new UnsupportedOperationException("Not Implemented");
223:
224: }
225:
226: public Object remove(int arg0) {
227: throw new UnsupportedOperationException("Not Implemented");
228: }
229:
230: public int indexOf(Object arg0) {
231: throw new UnsupportedOperationException("Not Implemented");
232: }
233:
234: public int lastIndexOf(Object arg0) {
235: throw new UnsupportedOperationException("Not Implemented");
236: }
237:
238: public ListIterator listIterator() {
239: throw new UnsupportedOperationException("Not Implemented");
240: }
241:
242: public ListIterator listIterator(int arg0) {
243: throw new UnsupportedOperationException("Not Implemented");
244: }
245:
246: public List subList(int arg0, int arg1) {
247: throw new UnsupportedOperationException("Not Implemented");
248: }
249:
250: public int getStart() {
251: return start;
252: }
253:
254: public void characters(char[] ch, int start, int length)
255: throws SAXException {
256:
257: StackElement se = (StackElement) stack.peek();
258: se.append(ch, start, length);
259: }
260:
261: public void endDocument() throws SAXException {
262: }
263:
264: public void endElement(String uri, String localName, String qName)
265: throws SAXException {
266: if (log.isDebugEnabled()) {
267: log.debug("End Element uri:" + uri + " ln:" + localName
268: + " qn:" + qName);
269: }
270: StackElement se = (StackElement) stack.pop();
271: if ("error".equals(localName)) {
272: errorMessage = se.getContent();
273: log.error("Error Message found from remote search "
274: + errorMessage);
275: } else if ("result".equals(localName)) {
276:
277: SearchResult sr;
278: try {
279: sr = new SearchResultResponseImpl(se.getAttributes(),
280: query, analyzer, searchIndexBuilder,
281: searchService);
282: } catch (IOException e) {
283: throw new SAXException(e.getMessage(), e);
284: }
285: resultsList.add(sr);
286: if (log.isDebugEnabled()) {
287: log.debug("Added Search Result " + resultsList.size());
288: }
289: } else if ("results".equals(localName)) {
290: fullsize = Integer.parseInt(se.getAttributes().getValue(
291: "fullsize"));
292: start = Integer.parseInt(se.getAttributes().getValue(
293: "start"));
294: size = Integer
295: .parseInt(se.getAttributes().getValue("size"));
296:
297: }
298: }
299:
300: public void endPrefixMapping(String prefix) throws SAXException {
301: }
302:
303: public void ignorableWhitespace(char[] ch, int start, int length)
304: throws SAXException {
305: }
306:
307: public void processingInstruction(String target, String data)
308: throws SAXException {
309: }
310:
311: public void setDocumentLocator(Locator locator) {
312: }
313:
314: public void skippedEntity(String name) throws SAXException {
315: }
316:
317: public void startDocument() throws SAXException {
318: resultsList = new ArrayList();
319: stack = new Stack();
320:
321: }
322:
323: public void startElement(String uri, String localName,
324: String qName, Attributes atts) throws SAXException {
325: if (log.isDebugEnabled()) {
326: log.debug("Start Element uri:" + uri + " ln:" + localName
327: + " qn:" + qName);
328: }
329: StackElement se = new StackElement(uri, localName, qName, atts);
330: stack.push(se);
331: }
332:
333: public void startPrefixMapping(String prefix, String uri)
334: throws SAXException {
335: }
336:
337: public class StackElement {
338:
339: private String uri;
340:
341: private String localName;
342:
343: private String name;
344:
345: private Attributes atts;
346:
347: private StringBuffer content;
348:
349: public StackElement(String uri, String localName, String name,
350: Attributes atts) {
351: this .uri = uri;
352: this .localName = localName;
353: this .name = name;
354: this .atts = new AttributesImpl(atts);
355: this .content = new StringBuffer();
356: }
357:
358: public Attributes getAttributes() {
359: // TODO Auto-generated method stub
360: return atts;
361: }
362:
363: public String getContent() {
364: // TODO Auto-generated method stub
365: return content.toString();
366: }
367:
368: public void append(char[] ch, int start, int length) {
369: content.append(ch, start, length);
370:
371: }
372:
373: }
374:
375: }
|