Source Code Cross Referenced for SearchServiceImpl.java in  » ERP-CRM-Financial » sakai » org » sakaiproject » search » component » service » impl » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » ERP CRM Financial » sakai » org.sakaiproject.search.component.service.impl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**********************************************************************************
0002:         * $URL: https://source.sakaiproject.org/svn/search/tags/sakai_2-4-1/search-impl/impl/src/java/org/sakaiproject/search/component/service/impl/SearchServiceImpl.java $
0003:         * $Id: SearchServiceImpl.java 29315 2007-04-20 14:28:12Z ajpoland@iupui.edu $
0004:         ***********************************************************************************
0005:         *
0006:         * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
0007:         *
0008:         * Licensed under the Educational Community License, Version 1.0 (the "License");
0009:         * you may not use this file except in compliance with the License.
0010:         * You may obtain a copy of the License at
0011:         *
0012:         *      http://www.opensource.org/licenses/ecl1.php
0013:         *
0014:         * Unless required by applicable law or agreed to in writing, software
0015:         * distributed under the License is distributed on an "AS IS" BASIS,
0016:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017:         * See the License for the specific language governing permissions and
0018:         * limitations under the License.
0019:         *
0020:         **********************************************************************************/package org.sakaiproject.search.component.service.impl;
0021:
0022:        import java.io.IOException;
0023:        import java.io.PrintWriter;
0024:        import java.io.StringWriter;
0025:        import java.security.GeneralSecurityException;
0026:        import java.security.MessageDigest;
0027:        import java.text.MessageFormat;
0028:        import java.util.ArrayList;
0029:        import java.util.Date;
0030:        import java.util.HashMap;
0031:        import java.util.Iterator;
0032:        import java.util.List;
0033:        import java.util.Map;
0034:
0035:        import org.apache.commons.httpclient.HostConfiguration;
0036:        import org.apache.commons.httpclient.HttpClient;
0037:        import org.apache.commons.httpclient.HttpConnectionManager;
0038:        import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
0039:        import org.apache.commons.httpclient.methods.PostMethod;
0040:        import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
0041:        import org.apache.commons.logging.Log;
0042:        import org.apache.commons.logging.LogFactory;
0043:        import org.apache.lucene.index.Term;
0044:        import org.apache.lucene.index.TermFreqVector;
0045:        import org.apache.lucene.queryParser.ParseException;
0046:        import org.apache.lucene.queryParser.QueryParser;
0047:        import org.apache.lucene.search.BooleanClause;
0048:        import org.apache.lucene.search.BooleanQuery;
0049:        import org.apache.lucene.search.Filter;
0050:        import org.apache.lucene.search.Hits;
0051:        import org.apache.lucene.search.IndexSearcher;
0052:        import org.apache.lucene.search.Query;
0053:        import org.apache.lucene.search.Sort;
0054:        import org.apache.lucene.search.TermQuery;
0055:        import org.sakaiproject.authz.cover.SecurityService;
0056:        import org.sakaiproject.component.api.ComponentManager;
0057:        import org.sakaiproject.component.cover.ServerConfigurationService;
0058:        import org.sakaiproject.event.api.EventTrackingService;
0059:        import org.sakaiproject.event.api.NotificationEdit;
0060:        import org.sakaiproject.event.api.NotificationService;
0061:        import org.sakaiproject.search.api.SearchIndexBuilder;
0062:        import org.sakaiproject.search.api.SearchList;
0063:        import org.sakaiproject.search.api.SearchResult;
0064:        import org.sakaiproject.search.api.SearchService;
0065:        import org.sakaiproject.search.api.SearchStatus;
0066:        import org.sakaiproject.search.api.TermFrequency;
0067:        import org.sakaiproject.search.component.Messages;
0068:        import org.sakaiproject.search.filter.SearchItemFilter;
0069:        import org.sakaiproject.search.index.IndexStorage;
0070:        import org.sakaiproject.search.model.SearchWriterLock;
0071:        import org.sakaiproject.tool.api.SessionManager;
0072:        import org.sakaiproject.user.api.User;
0073:        import org.sakaiproject.user.api.UserDirectoryService;
0074:
0075:        /**
0076:         * The search service
0077:         * 
0078:         * @author ieb
0079:         */
0080:        public class SearchServiceImpl implements  SearchService {
0081:
0082:            private static Log log = LogFactory.getLog(SearchServiceImpl.class);
0083:
0084:            /**
0085:             * Optional dependencies
0086:             */
0087:            private List triggerFunctions;
0088:
0089:            /**
0090:             * the notification object
0091:             */
0092:            private NotificationEdit notification = null;
0093:
0094:            /**
0095:             * init completed
0096:             */
0097:            private boolean initComplete = false;
0098:
0099:            /**
0100:             * the currently running index searcher
0101:             */
0102:            private IndexSearcher runningIndexSearcher;
0103:
0104:            /**
0105:             * The index builder dependency
0106:             */
0107:            private SearchIndexBuilder searchIndexBuilder;
0108:
0109:            private long reloadStart;
0110:
0111:            private long reloadEnd;
0112:
0113:            private NotificationService notificationService;
0114:
0115:            private IndexStorage indexStorage = null;
0116:
0117:            private SearchItemFilter filter;
0118:
0119:            private Map luceneFilters = new HashMap();
0120:
0121:            private Map luceneSorters = new HashMap();
0122:
0123:            private String defaultFilter = null;
0124:
0125:            private String defaultSorter = null;
0126:
0127:            private EventTrackingService eventTrackingService;
0128:
0129:            private UserDirectoryService userDirectoryService;
0130:
0131:            private SessionManager sessionManager;
0132:
0133:            private String sharedKey = null;
0134:
0135:            private String searchServerUrl = null;
0136:
0137:            private boolean searchServer = false;
0138:
0139:            private ThreadLocal localSearch = new ThreadLocal();
0140:
0141:            private HttpClient httpClient;
0142:
0143:            private HttpConnectionManagerParams httpParams = new HttpConnectionManagerParams();
0144:
0145:            private HttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();
0146:
0147:            private boolean diagnostics;
0148:
0149:            private long lastGet;
0150:
0151:            private Object reloadObjectSemaphore = new Object();
0152:
0153:            private boolean inreload = false;
0154:
0155:            /**
0156:             * Register a notification action to listen to events and modify the search
0157:             * index
0158:             */
0159:            public void init() {
0160:
0161:                ComponentManager cm = org.sakaiproject.component.cover.ComponentManager
0162:                        .getInstance();
0163:                notificationService = (NotificationService) load(cm,
0164:                        NotificationService.class.getName());
0165:                searchIndexBuilder = (SearchIndexBuilder) load(cm,
0166:                        SearchIndexBuilder.class.getName());
0167:                eventTrackingService = (EventTrackingService) load(cm,
0168:                        EventTrackingService.class.getName());
0169:                sessionManager = (SessionManager) load(cm, SessionManager.class
0170:                        .getName());
0171:                userDirectoryService = (UserDirectoryService) load(cm,
0172:                        UserDirectoryService.class.getName());
0173:
0174:                try {
0175:                    if (log.isDebugEnabled()) {
0176:                        log.debug("init start"); //$NON-NLS-1$
0177:                        log.debug("checking setup"); //$NON-NLS-1$
0178:                    }
0179:                    if (indexStorage == null) {
0180:                        log.error(" indexStorage must be set"); //$NON-NLS-1$
0181:                        throw new RuntimeException("Must set indexStorage"); //$NON-NLS-1$
0182:
0183:                    }
0184:                    if (searchIndexBuilder == null) {
0185:                        log.error(" searchIndexBuilder must be set"); //$NON-NLS-1$
0186:                        throw new RuntimeException(
0187:                                "Must set searchIndexBuilder"); //$NON-NLS-1$
0188:                    }
0189:                    if (filter == null) {
0190:                        log
0191:                                .error("filter must be set, even if its a null filter"); //$NON-NLS-1$
0192:                        throw new RuntimeException("Must set filter"); //$NON-NLS-1$
0193:                    }
0194:                    if (eventTrackingService == null) {
0195:                        log.error("Event Tracking Service was not found"); //$NON-NLS-1$
0196:                        throw new RuntimeException(
0197:                                "Event Tracking Service was not found"); //$NON-NLS-1$
0198:                    }
0199:                    if (sessionManager == null) {
0200:                        log.error("Session Manager was not found"); //$NON-NLS-1$
0201:                        throw new RuntimeException(
0202:                                "Session Manager was not found"); //$NON-NLS-1$
0203:                    }
0204:                    if (userDirectoryService == null) {
0205:                        log.error("User Directory Service was not found"); //$NON-NLS-1$
0206:                        throw new RuntimeException(
0207:                                "User Directory Service was not found"); //$NON-NLS-1$
0208:                    }
0209:
0210:                    // register a transient notification for resources
0211:                    notification = notificationService
0212:                            .addTransientNotification();
0213:
0214:                    // add all the functions that are registered to trigger search index
0215:                    // modification
0216:
0217:                    notification
0218:                            .setFunction(SearchService.EVENT_TRIGGER_SEARCH);
0219:                    if (triggerFunctions != null) {
0220:                        for (Iterator ifn = triggerFunctions.iterator(); ifn
0221:                                .hasNext();) {
0222:                            String function = (String) ifn.next();
0223:                            notification.addFunction(function);
0224:                            if (log.isDebugEnabled()) {
0225:                                log.debug("Adding Search Register " + function); //$NON-NLS-1$
0226:                            }
0227:                        }
0228:                    }
0229:
0230:                    // set the filter to any site related resource
0231:                    notification.setResourceFilter("/"); //$NON-NLS-1$
0232:
0233:                    // set the action
0234:                    notification.setAction(new SearchNotificationAction(
0235:                            searchIndexBuilder));
0236:
0237:                    // Configure params for the Connection Manager
0238:                    httpParams.setDefaultMaxConnectionsPerHost(20);
0239:                    httpParams.setMaxTotalConnections(30);
0240:
0241:                    // This next line may not be necessary since we specified default 2
0242:                    // lines ago, but here it is anyway
0243:                    httpParams.setMaxConnectionsPerHost(
0244:                            HostConfiguration.ANY_HOST_CONFIGURATION, 20);
0245:
0246:                    // Set up the connection manager
0247:                    httpConnectionManager.setParams(httpParams);
0248:
0249:                    // Finally set up the static multithreaded HttpClient
0250:                    httpClient = new HttpClient(httpConnectionManager);
0251:
0252:                    initComplete = true;
0253:                    if (log.isDebugEnabled()) {
0254:                        log.debug("init end"); //$NON-NLS-1$
0255:                    }
0256:                } catch (Throwable t) {
0257:                    log.error("Failed to start ", t); //$NON-NLS-1$
0258:                }
0259:
0260:            }
0261:
0262:            private Object load(ComponentManager cm, String name) {
0263:                Object o = cm.get(name);
0264:                if (o == null) {
0265:                    log.error("Cant find Spring component named " + name); //$NON-NLS-1$
0266:                }
0267:                return o;
0268:            }
0269:
0270:            /**
0271:             * @return Returns the triggerFunctions.
0272:             */
0273:            public List getTriggerFunctions() {
0274:                return triggerFunctions;
0275:            }
0276:
0277:            /**
0278:             * @param triggerFunctions
0279:             *        The triggerFunctions to set.
0280:             */
0281:            public void setTriggerFunctions(List triggerFunctions) {
0282:                if (initComplete)
0283:                    throw new RuntimeException(
0284:                            " use register function at runtime, setTriggerFucntions is for Spring IoC only"); //$NON-NLS-1$
0285:                this .triggerFunctions = triggerFunctions;
0286:            }
0287:
0288:            /**
0289:             * {@inheritDoc}
0290:             */
0291:            public void registerFunction(String function) {
0292:                notification.addFunction(function);
0293:                if (log.isDebugEnabled()) {
0294:                    log.debug("Adding Function " + function); //$NON-NLS-1$
0295:                }
0296:            }
0297:
0298:            /**
0299:             * {@inheritDoc}
0300:             * 
0301:             * @param indexFilter
0302:             */
0303:            public SearchList search(String searchTerms, List contexts,
0304:                    int start, int end) {
0305:                return search(searchTerms, contexts, start, end, defaultFilter,
0306:                        defaultSorter);
0307:            }
0308:
0309:            public SearchList search(String searchTerms, List contexts,
0310:                    int start, int end, String filterName, String sorterName) {
0311:                try {
0312:                    BooleanQuery query = new BooleanQuery();
0313:                    BooleanQuery contextQuery = new BooleanQuery();
0314:                    for (Iterator i = contexts.iterator(); i.hasNext();) {
0315:                        // Setup query so that it will allow results from any
0316:                        // included site, not all included sites.
0317:                        contextQuery.add(
0318:                                new TermQuery(new Term(
0319:                                        SearchService.FIELD_SITEID, (String) i
0320:                                                .next())),
0321:                                BooleanClause.Occur.SHOULD);
0322:                        // This would require term to be in all sites :-(
0323:                        // contextQuery.add(new TermQuery(new Term(
0324:                        // SearchService.FIELD_SITEID, (String) i.next())),
0325:                        // BooleanClause.Occur.MUST);
0326:                    }
0327:
0328:                    QueryParser qp = new QueryParser(
0329:                            SearchService.FIELD_CONTENTS, indexStorage
0330:                                    .getAnalyzer());
0331:                    Query textQuery = qp.parse(searchTerms);
0332:                    query.add(contextQuery, BooleanClause.Occur.MUST);
0333:                    query.add(textQuery, BooleanClause.Occur.MUST);
0334:                    log.info("Compiled Query is " + query.toString()); //$NON-NLS-1$
0335:
0336:                    if (localSearch.get() == null && searchServerUrl != null
0337:                            && searchServerUrl.length() > 0) {
0338:                        try {
0339:                            PostMethod post = new PostMethod(searchServerUrl);
0340:                            String userId = sessionManager
0341:                                    .getCurrentSessionUserId();
0342:                            StringBuffer sb = new StringBuffer();
0343:                            for (Iterator ci = contexts.iterator(); ci
0344:                                    .hasNext();) {
0345:                                sb.append(ci.next()).append(";"); //$NON-NLS-1$
0346:                            }
0347:                            String contextParam = sb.toString();
0348:                            post.setParameter(REST_CHECKSUM, digestCheck(
0349:                                    userId, searchTerms));
0350:                            post.setParameter(REST_CONTEXTS, contextParam);
0351:                            post.setParameter(REST_END, String.valueOf(end));
0352:                            post
0353:                                    .setParameter(REST_START, String
0354:                                            .valueOf(start));
0355:                            post.setParameter(REST_TERMS, searchTerms);
0356:                            post.setParameter(REST_USERID, userId);
0357:
0358:                            int status = httpClient.executeMethod(post);
0359:                            if (status != 200) {
0360:                                throw new RuntimeException(
0361:                                        "Failed to perform remote search, http status was " + status); //$NON-NLS-1$
0362:                            }
0363:
0364:                            String response = post.getResponseBodyAsString();
0365:                            return new SearchListResponseImpl(response,
0366:                                    textQuery, start, end, indexStorage
0367:                                            .getAnalyzer(), filter,
0368:                                    searchIndexBuilder, this );
0369:                        } catch (Exception ex) {
0370:
0371:                            log.error("Remote Search Failed ", ex); //$NON-NLS-1$
0372:                            throw new IOException(ex.getMessage());
0373:                        }
0374:
0375:                    } else {
0376:
0377:                        IndexSearcher indexSearcher = getIndexSearcher(false);
0378:                        if (indexSearcher != null) {
0379:                            Hits h = null;
0380:                            Filter indexFilter = (Filter) luceneFilters
0381:                                    .get(filterName);
0382:                            Sort indexSorter = (Sort) luceneSorters
0383:                                    .get(sorterName);
0384:                            if (log.isDebugEnabled()) {
0385:                                log.debug("Using Filter " + filterName + ":" //$NON-NLS-1$ //$NON-NLS-2$
0386:                                        + indexFilter
0387:                                        + " and " + sorterName + ":" //$NON-NLS-1$ //$NON-NLS-2$
0388:                                        + indexSorter);
0389:                            }
0390:                            if (indexFilter != null && indexSorter != null) {
0391:                                h = indexSearcher.search(query, indexFilter,
0392:                                        indexSorter);
0393:                            } else if (indexFilter != null) {
0394:                                h = indexSearcher.search(query, indexFilter);
0395:                            } else if (indexSorter != null) {
0396:                                h = indexSearcher.search(query, indexSorter);
0397:                            } else {
0398:                                h = indexSearcher.search(query);
0399:                            }
0400:                            if (log.isDebugEnabled()) {
0401:                                log.debug("Got " + h.length() + " hits"); //$NON-NLS-1$ //$NON-NLS-2$
0402:                            }
0403:                            eventTrackingService
0404:                                    .post(eventTrackingService.newEvent(
0405:                                            EVENT_SEARCH, EVENT_SEARCH_REF
0406:                                                    + textQuery.toString(),
0407:                                            true,
0408:                                            NotificationService.PREF_IMMEDIATE));
0409:                            return new SearchListImpl(h, textQuery, start, end,
0410:                                    indexStorage.getAnalyzer(), filter,
0411:                                    searchIndexBuilder, this );
0412:                        } else {
0413:                            throw new RuntimeException(
0414:                                    "Failed to start the Lucene Searche Engine"); //$NON-NLS-1$
0415:                        }
0416:                    }
0417:
0418:                } catch (ParseException e) {
0419:                    throw new RuntimeException("Failed to parse Query ", e); //$NON-NLS-1$
0420:                } catch (IOException e) {
0421:                    throw new RuntimeException("Failed to run Search ", e); //$NON-NLS-1$
0422:                }
0423:            }
0424:
0425:            /**
0426:             * {@inheritDoc}
0427:             */
0428:            public void reload() {
0429:                getIndexSearcher(true);
0430:            }
0431:
0432:            public void forceReload() {
0433:                reloadStart = 0;
0434:            }
0435:
0436:            public IndexSearcher getIndexSearcher(boolean reload) {
0437:                long reloadWaitEnd = System.currentTimeMillis() + 10L * 1000L;
0438:                if (inreload) {
0439:                    long waitStart = System.currentTimeMillis();
0440:                    log.info("Waiting for Index Reload to complete");
0441:                    while (inreload
0442:                            && (System.currentTimeMillis() < reloadWaitEnd)) {
0443:                        /*
0444:                         * When a reload is in progress we must wait here on a timeout
0445:                         * for it to have some chance of finishing. If it doesnt finish,
0446:                         * we will just grab the index searcher anyway It may cause
0447:                         * problems, but we cant throttle request threads for more than
0448:                         * 10 seconds.
0449:                         */
0450:                        Thread.yield();
0451:                    }
0452:                    log.info("Reload Complete, request paused for "
0453:                            + (System.currentTimeMillis() - waitStart) + "ms");
0454:                    if (System.currentTimeMillis() > reloadWaitEnd) {
0455:                        log.warn(" Index Reload Timeout, trying old Index ");
0456:                    }
0457:                }
0458:                if (runningIndexSearcher == null
0459:                        || (reload && !searchIndexBuilder.isLocalLock())) {
0460:
0461:                    long lastUpdate = indexStorage.getLastUpdate();
0462:
0463:                    if (lastUpdate > reloadStart
0464:                            || runningIndexSearcher == null) {
0465:                        synchronized (reloadObjectSemaphore) {
0466:                            /*
0467:                             * If we just go for reload, tehn there is a chance that
0468:                             * there will be an active search request depending on
0469:                             * search segments that are about to be deleted. on the
0470:                             * basis that a search typically < 100ms to complete and
0471:                             * release retrieve the results in fact it often takes <
0472:                             * 20ms, we should not try and reload if an index searcher
0473:                             * was retrieved in the last 100ms. That will prevent us
0474:                             * removing search index files from form an active search
0475:                             * load. The next problem that will happen is that searchers
0476:                             * will come in here when the index is being reloaded. This
0477:                             * is less of a problem, but we should probably throttle
0478:                             * while the load is going on to prevent a index sercher
0479:                             * that is in the process of being reloaded get into a
0480:                             * request cycle.
0481:                             */
0482:
0483:                            long endWait = System.currentTimeMillis() + 20L * 1000L;
0484:                            while ((System.currentTimeMillis() < endWait)
0485:                                    && (System.currentTimeMillis() < lastGet + 100L)) {
0486:                                Thread.yield();
0487:                            }
0488:
0489:                            /*
0490:                             * Danger Zone, if something gets in here it may loose
0491:                             * segments.
0492:                             */
0493:                            inreload = true;
0494:                            try {
0495:                                /**
0496:                                 * check again if we really need to reload, annother
0497:                                 * thread could have been in progress
0498:                                 */
0499:                                lastUpdate = indexStorage.getLastUpdate();
0500:                                if (lastUpdate > reloadStart
0501:                                        || runningIndexSearcher == null) {
0502:                                    reloadStart = System.currentTimeMillis();
0503:                                    /*
0504:                                     * Did we fail to get a reload lock, if so we just
0505:                                     * have to ignore the reload request and wait for
0506:                                     * the next one ?
0507:                                     */
0508:                                    if (System.currentTimeMillis() < endWait) {
0509:
0510:                                        if (log.isDebugEnabled()) {
0511:                                            log
0512:                                                    .debug("Reloading Index, force=" + reload); //$NON-NLS-1$
0513:                                        }
0514:                                        try {
0515:
0516:                                            // dont leave closing the index searcher to
0517:                                            // the
0518:                                            // GC.
0519:                                            // It
0520:                                            // may
0521:                                            // not happen fast enough.
0522:
0523:                                            IndexSearcher newRunningIndexSearcher = indexStorage
0524:                                                    .getIndexSearcher();
0525:
0526:                                            IndexSearcher oldRunningIndexSearcher = runningIndexSearcher;
0527:                                            runningIndexSearcher = newRunningIndexSearcher;
0528:
0529:                                            if (oldRunningIndexSearcher != null) {
0530:                                                try {
0531:                                                    indexStorage
0532:                                                            .closeIndexSearcher(oldRunningIndexSearcher);
0533:                                                } catch (Exception ex) {
0534:                                                    log
0535:                                                            .error(
0536:                                                                    "Failed to close old searcher ", ex); //$NON-NLS-1$
0537:                                                }
0538:                                            }
0539:
0540:                                            reloadEnd = System
0541:                                                    .currentTimeMillis();
0542:                                            if (diagnostics) {
0543:                                                log
0544:                                                        .info("Index Reloaded containing "
0545:                                                                + getNDocs()
0546:                                                                + " active documents and  "
0547:                                                                + getPendingDocs()
0548:                                                                + " pending documents in "
0549:                                                                + (reloadEnd - reloadStart)
0550:                                                                + "ms");
0551:                                            }
0552:                                        } catch (IOException e) {
0553:                                            reloadStart = reloadEnd;
0554:                                        }
0555:                                    } else {
0556:                                        log
0557:                                                .warn("Unable to reload index, there was too much search "
0558:                                                        + "activity on this node, will try again on the next "
0559:                                                        + "index reload event ");
0560:                                    }
0561:                                }
0562:                            } finally {
0563:                                inreload = false;
0564:                            }
0565:
0566:                        }
0567:                    } else {
0568:                        if (log.isDebugEnabled()) {
0569:                            log.debug("No Reload lastUpdate " + lastUpdate //$NON-NLS-1$
0570:                                    + " < lastReload " + reloadStart); //$NON-NLS-1$
0571:                        }
0572:
0573:                    }
0574:                }
0575:
0576:                lastGet = System.currentTimeMillis();
0577:                return runningIndexSearcher;
0578:            }
0579:
0580:            public void refreshInstance() {
0581:                searchIndexBuilder.refreshIndex();
0582:
0583:            }
0584:
0585:            public void rebuildInstance() {
0586:                searchIndexBuilder.rebuildIndex();
0587:            }
0588:
0589:            public void refreshSite(String currentSiteId) {
0590:                searchIndexBuilder.refreshIndex(currentSiteId);
0591:            }
0592:
0593:            public void rebuildSite(String currentSiteId) {
0594:                searchIndexBuilder.rebuildIndex(currentSiteId);
0595:
0596:            }
0597:
0598:            public String getStatus() {
0599:
0600:                String lastLoad = (new Date(reloadEnd)).toString();
0601:                String loadTime = String
0602:                        .valueOf((double) (0.001 * (reloadEnd - reloadStart)));
0603:                SearchWriterLock lock = searchIndexBuilder.getCurrentLock();
0604:                List lockNodes = searchIndexBuilder.getNodeStatus();
0605:
0606:                return Messages.getString("SearchServiceImpl.40") + lastLoad + Messages.getString("SearchServiceImpl.38") + loadTime + Messages.getString("SearchServiceImpl.37"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
0607:            }
0608:
0609:            public int getNDocs() {
0610:                try {
0611:                    return getIndexSearcher(false).getIndexReader().numDocs();
0612:                } catch (Exception e) {
0613:                    return -1;
0614:                }
0615:            }
0616:
0617:            public int getPendingDocs() {
0618:                return searchIndexBuilder.getPendingDocuments();
0619:            }
0620:
0621:            public List getAllSearchItems() {
0622:                return searchIndexBuilder.getAllSearchItems();
0623:            }
0624:
0625:            public List getSiteMasterSearchItems() {
0626:                return searchIndexBuilder.getSiteMasterSearchItems();
0627:            }
0628:
0629:            public List getGlobalMasterSearchItems() {
0630:                return searchIndexBuilder.getGlobalMasterSearchItems();
0631:            }
0632:
0633:            public SearchStatus getSearchStatus() {
0634:                String ll = Messages.getString("SearchServiceImpl.36"); //$NON-NLS-1$
0635:                String lt = ""; //$NON-NLS-1$
0636:                if (reloadEnd != 0) {
0637:                    ll = (new Date(reloadEnd)).toString();
0638:                    lt = String
0639:                            .valueOf((double) (0.001 * (reloadEnd - reloadStart)));
0640:                }
0641:                final String lastLoad = ll;
0642:                final String loadTime = lt;
0643:                final SearchWriterLock lock = searchIndexBuilder
0644:                        .getCurrentLock();
0645:                final List lockNodes = searchIndexBuilder.getNodeStatus();
0646:                final String pdocs = String.valueOf(getPendingDocs());
0647:                final String ndocs = String.valueOf(getNDocs());
0648:
0649:                return new SearchStatus() {
0650:                    public String getLastLoad() {
0651:                        return lastLoad;
0652:                    }
0653:
0654:                    public String getLoadTime() {
0655:                        return loadTime;
0656:                    }
0657:
0658:                    public String getCurrentWorker() {
0659:                        return lock.getNodename();
0660:                    }
0661:
0662:                    public String getCurrentWorkerETC() {
0663:                        if (SecurityService.isSuperUser()) {
0664:                            return MessageFormat
0665:                                    .format(
0666:                                            Messages
0667:                                                    .getString("SearchServiceImpl.35"), //$NON-NLS-1$
0668:                                            new Object[] {
0669:                                                    lock.getExpires(),
0670:                                                    searchIndexBuilder
0671:                                                            .getLastDocument(),
0672:                                                    searchIndexBuilder
0673:                                                            .getLastElapsed(),
0674:                                                    searchIndexBuilder
0675:                                                            .getCurrentDocument(),
0676:                                                    searchIndexBuilder
0677:                                                            .getCurrentElapsed(),
0678:                                                    ServerConfigurationService
0679:                                                            .getServerIdInstance() });
0680:                        } else {
0681:                            return MessageFormat
0682:                                    .format(
0683:                                            Messages
0684:                                                    .getString("SearchServiceImpl.39"), new Object[] { lock //$NON-NLS-1$
0685:                                                    .getExpires() });
0686:                        }
0687:                    }
0688:
0689:                    public List getWorkerNodes() {
0690:                        List l = new ArrayList();
0691:                        for (Iterator i = lockNodes.iterator(); i.hasNext();) {
0692:                            SearchWriterLock swl = (SearchWriterLock) i.next();
0693:                            Object[] result = new Object[3];
0694:                            result[0] = swl.getNodename();
0695:                            result[1] = swl.getExpires();
0696:                            if (lock.getNodename().equals(swl.getNodename())) {
0697:                                result[2] = Messages
0698:                                        .getString("SearchServiceImpl.47"); //$NON-NLS-1$
0699:                            } else {
0700:                                result[2] = Messages
0701:                                        .getString("SearchServiceImpl.48"); //$NON-NLS-1$
0702:                            }
0703:                            l.add(result);
0704:                        }
0705:                        return l;
0706:                    }
0707:
0708:                    public String getNDocuments() {
0709:                        return ndocs;
0710:                    }
0711:
0712:                    public String getPDocuments() {
0713:                        return pdocs;
0714:                    }
0715:
0716:                };
0717:
0718:            }
0719:
0720:            public boolean removeWorkerLock() {
0721:                return searchIndexBuilder.removeWorkerLock();
0722:
0723:            }
0724:
0725:            /**
0726:             * @return Returns the indexStorage.
0727:             */
0728:            public IndexStorage getIndexStorage() {
0729:                return indexStorage;
0730:            }
0731:
0732:            /**
0733:             * @param indexStorage
0734:             *        The indexStorage to set.
0735:             */
0736:            public void setIndexStorage(IndexStorage indexStorage) {
0737:                this .indexStorage = indexStorage;
0738:            }
0739:
0740:            /**
0741:             * @return Returns the filter.
0742:             */
0743:            public SearchItemFilter getFilter() {
0744:                return filter;
0745:            }
0746:
0747:            /**
0748:             * @param filter
0749:             *        The filter to set.
0750:             */
0751:            public void setFilter(SearchItemFilter filter) {
0752:                this .filter = filter;
0753:            }
0754:
0755:            /**
0756:             * @return Returns the defaultFilter.
0757:             */
0758:            public String getDefaultFilter() {
0759:                return defaultFilter;
0760:            }
0761:
0762:            /**
0763:             * @param defaultFilter
0764:             *        The defaultFilter to set.
0765:             */
0766:            public void setDefaultFilter(String defaultFilter) {
0767:                this .defaultFilter = defaultFilter;
0768:            }
0769:
0770:            /**
0771:             * @return Returns the defaultSorter.
0772:             */
0773:            public String getDefaultSorter() {
0774:                return defaultSorter;
0775:            }
0776:
0777:            /**
0778:             * @param defaultSorter
0779:             *        The defaultSorter to set.
0780:             */
0781:            public void setDefaultSorter(String defaultSorter) {
0782:                this .defaultSorter = defaultSorter;
0783:            }
0784:
0785:            /**
0786:             * @return Returns the luceneFilters.
0787:             */
0788:            public Map getLuceneFilters() {
0789:                return luceneFilters;
0790:            }
0791:
0792:            /**
0793:             * @param luceneFilters
0794:             *        The luceneFilters to set.
0795:             */
0796:            public void setLuceneFilters(Map luceneFilters) {
0797:                this .luceneFilters = luceneFilters;
0798:            }
0799:
0800:            /**
0801:             * @return Returns the luceneSorters.
0802:             */
0803:            public Map getLuceneSorters() {
0804:                return luceneSorters;
0805:            }
0806:
0807:            /**
0808:             * @param luceneSorters
0809:             *        The luceneSorters to set.
0810:             */
0811:            public void setLuceneSorters(Map luceneSorters) {
0812:                this .luceneSorters = luceneSorters;
0813:            }
0814:
0815:            public List getSegmentInfo() {
0816:                return indexStorage.getSegmentInfoList();
0817:            }
0818:
0819:            public TermFrequency getTerms(int documentId) throws IOException {
0820:                final TermFreqVector tf = getIndexSearcher(false)
0821:                        .getIndexReader().getTermFreqVector(documentId,
0822:                                FIELD_CONTENTS);
0823:                // TODO Auto-generated method stub
0824:                return new TermFrequency() {
0825:                    public String[] getTerms() {
0826:                        if (tf != null) {
0827:                            return tf.getTerms();
0828:                        }
0829:                        return new String[0];
0830:                    }
0831:
0832:                    public int[] getFrequencies() {
0833:                        if (tf != null) {
0834:                            return tf.getTermFrequencies();
0835:                        }
0836:                        return new int[0];
0837:                    }
0838:                };
0839:            }
0840:
0841:            public String searchXML(Map parameterMap) {
0842:                String userid = null;
0843:                String searchTerms = null;
0844:                String checksum = null;
0845:                String contexts = null;
0846:                String ss = null;
0847:                String se = null;
0848:                try {
0849:                    if (!searchServer) {
0850:                        throw new Exception(Messages
0851:                                .getString("SearchServiceImpl.49")); //$NON-NLS-1$
0852:                    }
0853:                    String[] useridA = (String[]) parameterMap.get(REST_USERID);
0854:                    String[] searchTermsA = (String[]) parameterMap
0855:                            .get(REST_TERMS);
0856:                    String[] checksumA = (String[]) parameterMap
0857:                            .get(REST_CHECKSUM);
0858:                    String[] contextsA = (String[]) parameterMap
0859:                            .get(REST_CONTEXTS);
0860:                    String[] ssA = (String[]) parameterMap.get(REST_START);
0861:                    String[] seA = (String[]) parameterMap.get(REST_END);
0862:
0863:                    StringBuffer sb = new StringBuffer();
0864:                    sb.append("<?xml version=\"1.0\"?>"); //$NON-NLS-1$
0865:
0866:                    boolean requestError = false;
0867:                    if (useridA == null || useridA.length != 1) {
0868:                        requestError = true;
0869:                    } else {
0870:                        userid = useridA[0];
0871:                    }
0872:                    if (searchTermsA == null || searchTermsA.length != 1) {
0873:                        requestError = true;
0874:                    } else {
0875:                        searchTerms = searchTermsA[0];
0876:                    }
0877:                    if (checksumA == null || checksumA.length != 1) {
0878:                        requestError = true;
0879:                    } else {
0880:                        checksum = checksumA[0];
0881:                    }
0882:                    if (contextsA == null || contextsA.length != 1) {
0883:                        requestError = true;
0884:                    } else {
0885:                        contexts = contextsA[0];
0886:                    }
0887:                    if (ssA == null || ssA.length != 1) {
0888:                        requestError = true;
0889:                    } else {
0890:                        ss = ssA[0];
0891:                    }
0892:                    if (seA == null || seA.length != 1) {
0893:                        requestError = true;
0894:                    } else {
0895:                        se = seA[0];
0896:                    }
0897:
0898:                    if (requestError) {
0899:                        throw new Exception(Messages
0900:                                .getString("SearchServiceImpl.34")); //$NON-NLS-1$
0901:
0902:                    }
0903:
0904:                    int searchStart = Integer.parseInt(ss);
0905:                    int searchEnd = Integer.parseInt(se);
0906:                    String[] ctxa = contexts.split(";"); //$NON-NLS-1$
0907:                    List ctx = new ArrayList(ctxa.length);
0908:                    for (int i = 0; i < ctxa.length; i++) {
0909:                        ctx.add(ctxa[i]);
0910:                    }
0911:
0912:                    if (sharedKey != null && sharedKey.length() > 0) {
0913:                        String check = digestCheck(userid, searchTerms);
0914:                        if (!check.equals(checksum)) {
0915:                            throw new Exception(Messages
0916:                                    .getString("SearchServiceImpl.53")); //$NON-NLS-1$
0917:                        }
0918:                    }
0919:
0920:                    org.sakaiproject.tool.api.Session s = sessionManager
0921:                            .startSession();
0922:                    User u = userDirectoryService.getUser("admin"); //$NON-NLS-1$
0923:                    s.setUserId(u.getId());
0924:                    sessionManager.setCurrentSession(s);
0925:                    localSearch.set("localsearch"); //$NON-NLS-1$
0926:                    try {
0927:
0928:                        SearchList sl = search(searchTerms, ctx, searchStart,
0929:                                searchEnd);
0930:                        sb.append("<results "); //$NON-NLS-1$
0931:                        sb.append(" fullsize=\"").append(sl.getFullSize()) //$NON-NLS-1$
0932:                                .append("\" "); //$NON-NLS-1$
0933:                        sb
0934:                                .append(" start=\"").append(sl.getStart()).append("\" "); //$NON-NLS-1$ //$NON-NLS-2$
0935:                        sb.append(" size=\"").append(sl.size()).append("\" "); //$NON-NLS-1$ //$NON-NLS-2$
0936:                        sb.append(" >"); //$NON-NLS-1$
0937:                        for (Iterator si = sl.iterator(); si.hasNext();) {
0938:                            SearchResult sr = (SearchResult) si.next();
0939:                            sr.toXMLString(sb);
0940:                        }
0941:                        sb.append("</results>"); //$NON-NLS-1$
0942:                        return sb.toString();
0943:                    } finally {
0944:                        sessionManager.setCurrentSession(null);
0945:                        localSearch.set(null);
0946:                    }
0947:                } catch (Exception ex) {
0948:                    StringBuffer sb = new StringBuffer();
0949:                    sb.append("<?xml version=\"1.0\"?>"); //$NON-NLS-1$
0950:                    sb.append("<fault>"); //$NON-NLS-1$
0951:                    sb.append("<request>"); //$NON-NLS-1$
0952:                    sb.append("<![CDATA["); //$NON-NLS-1$
0953:                    sb
0954:                            .append(" userid = ").append(StringUtils.xmlEscape(userid)).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$
0955:                    sb
0956:                            .append(" searchTerms = ").append(StringUtils.xmlEscape(searchTerms)).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$
0957:                    sb
0958:                            .append(" checksum = ").append(StringUtils.xmlEscape(checksum)).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$
0959:                    sb
0960:                            .append(" contexts = ").append(StringUtils.xmlEscape(contexts)).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$
0961:                    sb
0962:                            .append(" ss = ").append(StringUtils.xmlEscape(ss)).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$
0963:                    sb
0964:                            .append(" se = ").append(StringUtils.xmlEscape(se)).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$
0965:                    sb.append("]]>"); //$NON-NLS-1$
0966:                    sb.append("</request>"); //$NON-NLS-1$
0967:                    sb.append("<error>"); //$NON-NLS-1$
0968:                    sb.append("<![CDATA["); //$NON-NLS-1$
0969:                    try {
0970:                        StringWriter sw = new StringWriter();
0971:                        PrintWriter pw = new PrintWriter(sw);
0972:                        ex.printStackTrace(pw);
0973:                        pw.flush();
0974:                        sb.append(sw.toString());
0975:                        pw.close();
0976:                        sw.close();
0977:                    } catch (Exception ex2) {
0978:                        sb
0979:                                .append(
0980:                                        "Failed to serialize exception " + ex.getMessage()) //$NON-NLS-1$
0981:                                .append("\n"); //$NON-NLS-1$
0982:                        sb.append("Case:  " + ex2.getMessage()); //$NON-NLS-1$
0983:
0984:                    }
0985:                    sb.append("]]>"); //$NON-NLS-1$
0986:                    sb.append("</error>"); //$NON-NLS-1$
0987:                    sb.append("</fault>"); //$NON-NLS-1$
0988:                    return sb.toString();
0989:                }
0990:            }
0991:
0992:            private String digestCheck(String userid, String searchTerms)
0993:                    throws GeneralSecurityException, IOException {
0994:                MessageDigest sha1 = MessageDigest.getInstance("SHA1"); //$NON-NLS-1$
0995:                String chstring = sharedKey + userid + searchTerms;
0996:                return byteArrayToHexStr(sha1
0997:                        .digest(chstring.getBytes("UTF-8"))); //$NON-NLS-1$
0998:            }
0999:
1000:            private static String byteArrayToHexStr(byte[] data) {
1001:                char[] chars = new char[data.length * 2];
1002:                for (int i = 0; i < data.length; i++) {
1003:                    byte current = data[i];
1004:                    int hi = (current & 0xF0) >> 4;
1005:                    int lo = current & 0x0F;
1006:                    chars[2 * i] = (char) (hi < 10 ? ('0' + hi)
1007:                            : ('A' + hi - 10));
1008:                    chars[2 * i + 1] = (char) (lo < 10 ? ('0' + lo)
1009:                            : ('A' + lo - 10));
1010:                }
1011:                return new String(chars);
1012:            }
1013:
1014:            /**
1015:             * @return the sharedKey
1016:             */
1017:            public String getSharedKey() {
1018:                return sharedKey;
1019:            }
1020:
1021:            /**
1022:             * @param sharedKey
1023:             *        the sharedKey to set
1024:             */
1025:            public void setSharedKey(String sharedKey) {
1026:                this .sharedKey = sharedKey;
1027:            }
1028:
1029:            /**
1030:             * @return the searchServerUrl
1031:             */
1032:            public String getSearchServerUrl() {
1033:                return searchServerUrl;
1034:            }
1035:
1036:            /**
1037:             * @param searchServerUrl
1038:             *        the searchServerUrl to set
1039:             */
1040:            public void setSearchServerUrl(String searchServerUrl) {
1041:                this .searchServerUrl = searchServerUrl;
1042:            }
1043:
1044:            /**
1045:             * @return the searchServer
1046:             */
1047:            public boolean isSearchServer() {
1048:                return searchServer;
1049:            }
1050:
1051:            /**
1052:             * @param searchServer
1053:             *        the searchServer to set
1054:             */
1055:            public void setSearchServer(boolean searchServer) {
1056:                this .searchServer = searchServer;
1057:            }
1058:
1059:            /*
1060:             * (non-Javadoc)
1061:             * 
1062:             * @see org.sakaiproject.search.api.Diagnosable#disableDiagnostics()
1063:             */
1064:            public void disableDiagnostics() {
1065:                diagnostics = false;
1066:                indexStorage.disableDiagnostics();
1067:                searchIndexBuilder.disableDiagnostics();
1068:
1069:            }
1070:
1071:            /*
1072:             * (non-Javadoc)
1073:             * 
1074:             * @see org.sakaiproject.search.api.Diagnosable#enableDiagnostics()
1075:             */
1076:            public void enableDiagnostics() {
1077:                diagnostics = true;
1078:                indexStorage.enableDiagnostics();
1079:                searchIndexBuilder.enableDiagnostics();
1080:            }
1081:
1082:            /*
1083:             * (non-Javadoc)
1084:             * 
1085:             * @see org.sakaiproject.search.api.Diagnosable#hasDiagnostics()
1086:             */
1087:            public boolean hasDiagnostics() {
1088:                return diagnostics;
1089:            }
1090:
1091:            public boolean getDiagnostics() {
1092:                return diagnostics;
1093:            }
1094:
1095:            public void setDiagnostics(boolean diagnostics) {
1096:                if (diagnostics) {
1097:                    enableDiagnostics();
1098:                } else {
1099:                    disableDiagnostics();
1100:                }
1101:            }
1102:
1103:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.