001: /*
002: * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions
006: * are met:
007: *
008: * - Redistributions of source code must retain the above copyright
009: * notice, this list of conditions and the following disclaimer.
010: *
011: * - Redistribution in binary form must reproduce the above copyright
012: * notice, this list of conditions and the following disclaimer in
013: * the documentation and/or other materials provided with the
014: * distribution.
015: *
016: * Neither the name of Sun Microsystems, Inc. or the names of
017: * contributors may be used to endorse or promote products derived
018: * from this software without specific prior written permission.
019: *
020: * This software is provided "AS IS," without a warranty of any
021: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
022: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
023: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
024: * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
025: * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
026: * DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
027: * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
028: * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
029: * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
030: * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE,
031: * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
032: *
033: * You acknowledge that Software is not designed, licensed or intended
034: * any nuclear facility.
035: */
036:
037: package com.sun.portal.search.providers.faces;
038:
039: import com.sun.portal.search.demo.Search;
040: import com.sun.portal.search.soif.SOIF;
041: import com.sun.portal.search.soif.SOIFInputStream;
042: import com.sun.web.ui.component.Tab;
043: import com.sun.web.ui.component.Hyperlink;
044: import java.util.ArrayList;
045: import java.util.logging.Level;
046: import java.util.logging.Logger;
047: import javax.faces.component.UIParameter;
048: import javax.faces.context.FacesContext;
049: import javax.faces.model.ArrayDataModel;
050:
051: public class SearchDatabase {
052: String rdmServer;
053: String[] databases;
054: private String categoryRoot = "ROOT";
055: String scope;
056: ArrayDataModel hits = null;
057: int currentPage = 1;
058: private int numberPerPage = 10;
059: int total = 0;
060: String viewOrder;
061: private static Logger logger = SearchLogger
062: .getLogger(SearchDatabase.class);
063: private String pageAction = "";
064: private boolean selected = true;
065: SearchHandler searchHandler;
066: private String withinCategory;
067: public static final int MERGE_ITERATE = 1;
068: public static final int MERGE_SERIALIZE = 2;
069: private int mergeMode = MERGE_ITERATE;
070:
071: String displayName;
072: Tab tabUI = null;
073: ArrayList cachedResults = null;
074: public static final String TARGET_BROWSE_ID_PREFIX = "browse_";
075: public static final String TARGET_SEARCH_ID_PREFIX = "search_";
076: public static final String TAB_ID_PREFIX = "search_";
077:
078: public static final String DatabaseNameSeperator = ",";
079: private String uiId = null;
080: private String viewAttributes = "rd-display-url,hl-url, hl-title,title,hl-description,description,classification, author, rd-last-changed, virtual-db, channelname";
081:
082: /**
083: * Creates a new instance of SearchDatabase
084: */
085: public SearchDatabase(SearchHandler searchHandler,
086: String searchUrl, String database, String displayName) {
087: this .searchHandler = searchHandler;
088: this .rdmServer = searchUrl;
089: this .databases = database.split(DatabaseNameSeperator);
090: this .displayName = displayName;
091: }
092:
093: public SearchDatabase(SearchHandler searchHandler,
094: String searchUrl, String[] databases, String displayName) {
095: this .searchHandler = searchHandler;
096: this .rdmServer = searchUrl;
097: this .databases = databases;
098: this .displayName = displayName;
099: }
100:
101: public String getCategoryRoot() {
102: return searchHandler.getCategoryRoot();
103: }
104:
105: /**
106: * Getting the search result
107: * @return SearchHits
108: */
109: public ArrayDataModel getHits() {
110: if (hits != null) {
111: return hits;
112: }
113: if (cachedResults == null) {
114: cachedResults = new ArrayList();
115: for (int i = 0; i < databases.length; i++) {
116:
117: Search s = new Search();
118: s.setRDMServer(rdmServer);
119: s.setSessionID(searchHandler.getSessionId());
120: s.setViewAttributes(viewAttributes);
121: String defaultType = SearchHitFactory.HIT_COMMUNITY_CONTENT;
122: if (databases[i].indexOf("_communities_") >= 0) {
123: defaultType = SearchHitFactory.HIT_COMMUNITY;
124: s.setRDMType("rd-request");
125: s.setQueryLanguage("search");
126: } else if (databases[i].indexOf("taxonomy") >= 0) {
127: defaultType = SearchHitFactory.HIT_CATEGORY;
128: s.setRDMType("taxonomy-request");
129: s.setViewAttributes(null);
130:
131: }
132: s.setQueryLanguage("search");
133: s.setScope(this .getQuery());
134:
135: //s.setFirstHit((currentPage-1) * numberPerPage + 1);
136: //s.setViewHits(numberPerPage);
137: if (viewOrder != null) {
138: s.setViewOrder(viewOrder);
139: }
140:
141: s.setDatabase(databases[i]);
142: CachedResult cr = new CachedResult(this , s, defaultType);
143: cachedResults.add(cr);
144: }
145: }
146: ArrayList results = new ArrayList();
147: total = 0;
148: if (this .mergeMode == MERGE_ITERATE) {
149: Integer[] totals = new Integer[databases.length];
150: Integer[] starts = new Integer[databases.length];
151: for (int i = 0; i < databases.length; i++) {
152: CachedResult cr = (CachedResult) cachedResults.get(i);
153: totals[i] = new Integer(cr.getTotal());
154: total += totals[i].intValue();
155: starts[i] = new Integer(1);
156: }
157:
158: boolean more = true;
159:
160: for (int i = 1; more && i <= currentPage * numberPerPage;) {
161: more = false;
162: for (int j = 0; j < databases.length; j++) {
163:
164: if (starts[j].compareTo(totals[j]) <= 0) {
165: more = true;
166: if (i >= (currentPage - 1) * numberPerPage + 1) {
167: CachedResult cr = (CachedResult) cachedResults
168: .get(j);
169: results.add(cr.getHitAt(starts[j]
170: .intValue()));
171:
172: }
173: i++;
174: starts[j] = new Integer(
175: starts[j].intValue() + 1);
176: }
177: }
178: }
179: }
180:
181: hits = new ArrayDataModel(results.toArray());
182: return hits;
183:
184: }
185:
186: public int getTotal() {
187: getHits();
188: return this .total;
189: }
190:
191: public int getStartCount() {
192: getHits();
193: return (currentPage - 1) * this .numberPerPage + 1;
194: }
195:
196: public int getEndCount() {
197: return (getStartCount() + hits.getRowCount() - 1);
198: }
199:
200: public boolean getHasNextPage() {
201: getHits();
202: return (this .currentPage * this .numberPerPage < this .total);
203: }
204:
205: public boolean getHasPrePage() {
206: getHits();
207: return this .currentPage > 1;
208: }
209:
210: public String nextPage() {
211: hits = null;
212: this .currentPage++;
213: return pageAction;
214: }
215:
216: public String prePage() {
217: hits = null;
218: if (currentPage > 1) {
219: currentPage--;
220: }
221: return pageAction;
222: }
223:
224: public boolean isSelected() {
225: return selected;
226: }
227:
228: public void setSelected(boolean selected) {
229: this .selected = selected;
230: }
231:
232: public void setBrowsedCategory(String category) {
233: this .setScope(null);
234: this .setWithinCategory(category);
235: }
236:
237: public String getQuery() {
238: if (this .withinCategory != null) {
239: if (this .scope != null) {
240: return scope + "<and> classification=\""
241: + withinCategory + "\"";
242: } else {
243: return "classification=\"" + withinCategory + "\"";
244: }
245:
246: }
247: return scope;
248: }
249:
250: public String getScope() {
251: return scope;
252: }
253:
254: public void setScope(String scope) {
255: this .scope = scope;
256: }
257:
258: public void reset() {
259: this .hits = null;
260: this .currentPage = 1;
261: this .withinCategory = null;
262: hits = null;
263: this .cachedResults = null;
264: this .scope = null;
265: }
266:
267: public String getDisplayName() {
268: return displayName;
269: }
270:
271: public void setDisplayName(String name) {
272: displayName = name;
273: }
274:
275: public SearchHandler getSearchHandler() {
276: return this .searchHandler;
277: }
278:
279: public String getWithinCategory() {
280: return withinCategory;
281: }
282:
283: public void setWithinCategory(String withinCategory) {
284: this .withinCategory = withinCategory;
285: }
286:
287: public String searchDatabase() {
288: this .searchHandler.setCurrentSearchDatabase(this );
289: return searchHandler.doSearch();
290: }
291:
292: public String browseDatabase() {
293: this .searchHandler.setCurrentSearchDatabase(this );
294: return searchHandler.doBrowse();
295: }
296:
297: public Tab getTabUI() {
298: if (tabUI != null) {
299: return tabUI;
300: }
301: tabUI = new Tab(getDisplayName());
302: tabUI.setId(TAB_ID_PREFIX + getUiId());
303: return tabUI;
304: }
305:
306: Hyperlink targetLink;
307:
308: public Hyperlink getTargetLink() {
309: if (targetLink == null) {
310: targetLink = new Hyperlink();
311: targetLink.setId(TARGET_SEARCH_ID_PREFIX + getUiId());
312: targetLink.setText(this .getDisplayName());
313: targetLink.setAction(FacesContext.getCurrentInstance()
314: .getApplication().createMethodBinding(
315: "#{"
316: + this .searchHandler
317: .getDoTargetMethod() + "}",
318: null));
319: UIParameter p = new UIParameter();
320: p.setName("targetDb");
321: p.setValue(getUiId());
322: targetLink.getChildren().add(p);
323:
324: }
325: return targetLink;
326: }
327:
328: Hyperlink browseTargetLink;
329:
330: public Hyperlink getBrowseTargetLink() {
331: if (browseTargetLink == null) {
332: browseTargetLink = new Hyperlink();
333: browseTargetLink.setId(TARGET_BROWSE_ID_PREFIX + getUiId());
334: browseTargetLink.setText(this .getDisplayName());
335: browseTargetLink.setAction(FacesContext
336: .getCurrentInstance().getApplication()
337: .createMethodBinding(
338: "#{"
339: + this .searchHandler
340: .getDoBrowseTargetMethod()
341: + "}", null));
342: UIParameter p = new UIParameter();
343: p.setName("targetDb");
344: p.setValue(getUiId());
345: browseTargetLink.getChildren().add(p);
346:
347: }
348: return browseTargetLink;
349: }
350:
351: public void setTabUI(Tab t) {
352:
353: }
354:
355: public class MyTab extends Tab {
356: SearchDatabase searchDatabase;
357:
358: public SearchDatabase getMyDatabase() {
359: return searchDatabase;
360: }
361: }
362:
363: public String getUiId() {
364: return this .uiId;
365: }
366:
367: public void setUiId(String id) {
368: this .uiId = id;
369: }
370:
371: class CachedResult {
372: Search s;
373: ArrayList rds = new ArrayList();
374: int cachedSize = 50;
375: int cachedStart = 1;
376: int total = -1;
377: String defaultType;
378: SearchDatabase sourceDb;
379: int start = 1;
380:
381: CachedResult(SearchDatabase sourceDb, Search s,
382: String defaultType) {
383: this .s = s;
384: this .sourceDb = sourceDb;
385: this .defaultType = defaultType;
386: }
387:
388: private void updateCache(int index) {
389: rds.clear();
390: start = index - cachedSize / 2;
391: if (start < 0) {
392: start = 1;
393: }
394: s.setFirstHit(start);
395: s.setViewHits(cachedSize);
396: s.doQuery();
397: total = s.getHitCount();
398: SOIFInputStream resultStream = s.getResultStream();
399: if (resultStream == null) {
400: logger.severe("PSCPL_CSPACF00104");
401: } else {
402: SOIF soif;
403: try {
404: for (soif = resultStream.readSOIF(); soif != null; soif = resultStream
405: .readSOIF()) {
406: String schemaName = soif.getSchemaName();
407: if (schemaName.equalsIgnoreCase("document")
408: || schemaName
409: .equalsIgnoreCase("classification")) {
410: SearchHit hit = SearchHitFactory
411: .getInstance().createHit(soif,
412: defaultType);
413: hit.setSourceDatabase(sourceDb);
414: hit.setSourceDatabaseName(s.getDatabase());
415: rds.add(hit);
416: }
417: }
418: } catch (java.io.IOException e) {
419: logger.log(Level.SEVERE, "PSCPL_CSPACF00105", e);
420: }
421: }
422: }
423:
424: public int getTotal() {
425: if (total == -1) {
426: updateCache(1);
427: }
428: return total;
429: }
430:
431: SearchHit getHitAt(int index) {
432:
433: if (total < 0 || index < start
434: || (index < total && index >= start + rds.size())) {
435: this .updateCache(index);
436: }
437: return (SearchHit) rds.get(index - start);
438: }
439:
440: }
441:
442: public int getNumberPerPage() {
443: return numberPerPage;
444: }
445:
446: public void setNumberPerPage(int numberPerPage) {
447: this .numberPerPage = numberPerPage;
448: }
449:
450: public String getViewAttributes() {
451: return viewAttributes;
452: }
453:
454: public void setViewAttributes(String viewAttributes) {
455: this .viewAttributes = viewAttributes;
456: }
457:
458: public String getViewOrder() {
459: return viewOrder;
460: }
461:
462: public void setViewOrder(String viewOrder) {
463: this.viewOrder = viewOrder;
464: }
465:
466: }
|