001: /***************************************************************
002: * This file is part of the [fleXive](R) project.
003: *
004: * Copyright (c) 1999-2007
005: * UCS - unique computing solutions gmbh (http://www.ucs.at)
006: * All rights reserved
007: *
008: * The [fleXive](R) project is free software; you can redistribute
009: * it and/or modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation;
011: * either version 2 of the License, or (at your option) any
012: * later version.
013: *
014: * The GNU General Public License can be found at
015: * http://www.gnu.org/copyleft/gpl.html.
016: * A copy is found in the textfile GPL.txt and important notices to the
017: * license from the author are found in LICENSE.txt distributed with
018: * these libraries.
019: *
020: * This library is distributed in the hope that it will be useful,
021: * but WITHOUT ANY WARRANTY; without even the implied warranty of
022: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023: * GNU General Public License for more details.
024: *
025: * For further information about UCS - unique computing solutions gmbh,
026: * please see the company website: http://www.ucs.at
027: *
028: * For further information about [fleXive](R), please see the
029: * project website: http://www.flexive.org
030: *
031: *
032: * This copyright notice MUST APPEAR in all copies of the file!
033: ***************************************************************/package com.flexive.war.beans.cms;
034:
035: import com.flexive.faces.FxJsfUtils;
036: import com.flexive.shared.CacheAdmin;
037: import com.flexive.shared.EJBLookup;
038: import com.flexive.shared.FxContext;
039: import com.flexive.shared.interfaces.SearchEngine;
040: import com.flexive.shared.search.FxResultSet;
041: import com.flexive.shared.search.FxSQLSearchParams;
042:
043: import java.util.Hashtable;
044:
045: public class SearchProviderBean extends Hashtable<String, FxResultSet> {
046:
047: // TODO:
048: // When "group based" caching is used, the group key has to be created with the groups in sorted order,
049: // so that the group array [1,2] equals [2,1].
050: // Also the search must be run with a fake ticket, that does NOT take the users permissions into account, only
051: // those of the groups.
052:
053: private SearchEngine search;
054:
055: /**
056: * Default constructor
057: */
058: public SearchProviderBean() {
059: super (20);
060: search = EJBLookup.getSearchEngine();
061: }
062:
063: private static String getCacheKey(String query) {
064: String sGroups = "";
065: for (long grp : FxContext.get().getTicket().getGroups()) {
066: sGroups += "_" + grp;
067: }
068: return sGroups + query;
069: }
070:
071: public FxResultSet getFromCache(String query) {
072: try {
073: String key = getCacheKey(query);
074: String path = String.valueOf(SearchProviderBean.class);
075: FxResultSet result = (FxResultSet) CacheAdmin.getInstance()
076: .get(path, key);
077: if (result != null) {
078: long tstp = search.getLastContentChange(false);
079: if (tstp > result.getCreationTime()) {
080: CacheAdmin.getInstance().remove(path, key);
081: result = null;
082: }
083: }
084: return result;
085: } catch (Throwable t) {
086: return null;
087: }
088: }
089:
090: public void putToCache(String query, FxResultSet result) {
091: try {
092: CacheAdmin.getInstance().put(
093: String.valueOf(SearchProviderBean.class),
094: getCacheKey(query), result);
095: } catch (Throwable t) {
096: System.err
097: .println("Failed to put the getResult result in to the cache: "
098: + t.getMessage());
099: }
100: }
101:
102: /**
103: * This will perform a search.
104: * <p/>
105: * Results are stored within the request, and if the same query is issued again the
106: * result will be taken from this cache.
107: *
108: * @param query the search
109: * @return the resultset
110: */
111: public FxResultSet get(Object query) {
112: boolean fromCache = true;
113: long time = System.currentTimeMillis();
114: String sQuery = String.valueOf(query).trim();
115: // Evaluate JSF/faceltets expressions within the query
116: sQuery = FxJsfUtils.evalString(sQuery);
117: FxResultSet result = super .get(sQuery);
118: // Only issue the query if we didnt find it in the request cache
119: if (result == null) {
120: // Lookup the second cache
121: result = getFromCache(sQuery);
122: // Use the cache if possible, otherwise perform the query
123: if (result == null) {
124: try {
125: fromCache = false;
126: FxSQLSearchParams params = new FxSQLSearchParams();
127: params.setQueryTimeout(1000);
128: result = search.search(String.valueOf(sQuery), 0,
129: 100, null);
130: super .put(sQuery, result);
131: putToCache(sQuery, result);
132: } catch (Throwable t) {
133: System.err.println("Search failed: "
134: + t.getMessage());
135: return null;
136: }
137: }
138: }
139: if (!fromCache) {
140: System.out.print("SearchProviderBean: cache=" + fromCache
141: + ", time=" + (System.currentTimeMillis() - time));
142: }
143: return result;
144: }
145:
146: boolean initial = false;
147:
148: }
|