xref: /AOO41X/main/xmlhelp/source/com/sun/star/help/HelpSearch.java (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 package com.sun.star.help;
29 
30 import com.sun.star.lib.uno.helper.Factory;
31 import com.sun.star.lang.XMultiComponentFactory;
32 import com.sun.star.lang.XSingleComponentFactory;
33 import com.sun.star.lib.uno.helper.WeakBase;
34 import com.sun.star.uno.XComponentContext;
35 import com.sun.star.registry.XRegistryKey;
36 import com.sun.star.lang.XServiceInfo;
37 import com.sun.star.uno.Type;
38 import com.sun.star.uno.Any;
39 import com.sun.star.uno.AnyConverter;
40 
41 import org.apache.lucene.analysis.Analyzer;
42 import org.apache.lucene.analysis.standard.StandardAnalyzer;
43 import org.apache.lucene.analysis.cjk.CJKAnalyzer;
44 import org.apache.lucene.document.Document;
45 import org.apache.lucene.index.IndexReader;
46 import org.apache.lucene.index.Term;
47 import org.apache.lucene.search.Hits;
48 import org.apache.lucene.search.IndexSearcher;
49 import org.apache.lucene.search.Query;
50 import org.apache.lucene.search.Searcher;
51 import org.apache.lucene.search.TermQuery;
52 import org.apache.lucene.search.WildcardQuery;
53 
54 import com.sun.star.script.XInvocation;
55 import com.sun.star.beans.XIntrospectionAccess;
56 
57 /** This class capsulates the class, that implements the minimal component and a
58  * factory for creating the service (<CODE>__getComponentFactory</CODE>).
59  */
60 public class HelpSearch
61 {
62     /** This class implements the component. At least the interfaces XServiceInfo,
63      * XTypeProvider, and XInitialization should be provided by the service.
64      */
65     public static class _HelpSearch extends WeakBase
66         implements XServiceInfo, XInvocation
67     {
68         /** The service name, that must be used to get an instance of this service.
69          */
70         static private final String __serviceName =
71             "com.sun.star.help.HelpSearch";
72         static private final String aSearchMethodName = "search";
73 
74         /** The initial component contextr, that gives access to
75          * the service manager, supported singletons, ...
76          * It's often later used
77          */
78         private XComponentContext m_cmpCtx;
79 
80         /** The service manager, that gives access to all registered services.
81          * It's often later used
82          */
83         private XMultiComponentFactory m_xMCF;
84 
85         /** The constructor of the inner class has a XMultiServiceFactory parameter.
86          * @param xmultiservicefactoryInitialization A special service factory
87          * could be introduced while initializing.
88          */
89         public _HelpSearch(XComponentContext xCompContext)
90         {
91             try {
92                 m_cmpCtx = xCompContext;
93                 m_xMCF = m_cmpCtx.getServiceManager();
94             }
95             catch( Exception e ) {
96                 e.printStackTrace();
97             }
98         }
99 
100         /** This method returns an array of all supported service names.
101          * @return Array of supported service names.
102          */
103         public String[] getSupportedServiceNames()
104         {
105             return getServiceNames();
106         }
107 
108         /** This method is a simple helper function to used in the
109          * static component initialisation functions as well as in
110          * getSupportedServiceNames.
111          */
112         public static String[] getServiceNames()
113         {
114             String[] sSupportedServiceNames = { __serviceName };
115             return sSupportedServiceNames;
116         }
117 
118         /** This method returns true, if the given service will be
119          * supported by the component.
120          * @param sServiceName Service name.
121          * @return True, if the given service name will be supported.
122          */
123         public boolean supportsService( String sServiceName )
124         {
125             return sServiceName.equals( __serviceName );
126         }
127 
128         /** Return the class name of the component.
129          * @return Class name of the component.
130          */
131         public String getImplementationName()
132         {
133             return  _HelpSearch.class.getName();
134         }
135 
136         //===================================================
137         // XInvocation
138         public XIntrospectionAccess getIntrospection()
139         {
140             return  null;
141         }
142 
143         public Object invoke( String aFunctionName, java.lang.Object[] aParams,
144             short[][] aOutParamIndex, java.lang.Object[][] aOutParam )
145                 throws  com.sun.star.lang.IllegalArgumentException,
146                         com.sun.star.script.CannotConvertException,
147                         com.sun.star.reflection.InvocationTargetException
148         {
149             String[] aRet = null;
150             if( !aFunctionName.equals( aSearchMethodName ) )
151                 throw new com.sun.star.lang.IllegalArgumentException();
152 
153             Object[] aScoreOutArray = new Object[1];
154             aScoreOutArray[0] = null;
155             try
156             {
157                 aRet =  doQuery( aParams, aScoreOutArray );
158             }
159             catch( Exception e )
160             {
161                 aRet = null;
162             }
163 
164             Object aScoreArray = aScoreOutArray[0];
165             if( aScoreArray == null )
166             {
167                 aOutParamIndex[0] = new short[0];
168                 aOutParam[0] = new Object[0];
169             }
170             else
171             {
172                 short nInParamCount = (short)aParams.length;
173                 aOutParamIndex[0] = new short[1];
174                 aOutParamIndex[0][0] = nInParamCount;
175                 aOutParam[0] = new Object[1];
176                 aOutParam[0][0] = aScoreArray;
177             }
178 
179             Any aRetAny = new Any( new Type( String[].class ), aRet );
180             return aRetAny;
181         }
182 
183         public void setValue( String aPropertyName, java.lang.Object aValue )
184             throws  com.sun.star.beans.UnknownPropertyException,
185                     com.sun.star.script.CannotConvertException,
186                     com.sun.star.reflection.InvocationTargetException {
187             throw new com.sun.star.beans.UnknownPropertyException();
188         }
189 
190         public Object getValue( String aPropertyName )
191             throws com.sun.star.beans.UnknownPropertyException {
192             throw new com.sun.star.beans.UnknownPropertyException();
193         }
194 
195         public boolean hasMethod( String aMethodName ) {
196             boolean bRet = (aMethodName.equals( aSearchMethodName ) );
197             return bRet;
198         }
199         public boolean hasProperty( String aName ) {
200             return false;
201         }
202 
203         // Command line interface for testing
204         private static String[] doQuery( Object[] args, Object[] aScoreOutArray ) throws Exception
205         {
206             String aLanguageStr = "";
207             String aIndexStr = "";
208             String aQueryStr = "";
209             boolean bCaptionOnly = false;
210 
211             int nParamCount = args.length;
212             String aStrs[] = new String[nParamCount];
213             for( int i = 0 ; i < nParamCount ; i++ )
214             {
215                 try
216                 {
217                     aStrs[i] = AnyConverter.toString( args[i] );
218                 }
219                 catch( IllegalArgumentException e )
220                 {
221                     aStrs[i] = "";
222                 }
223             }
224 
225             // TODO: Error handling
226             for( int i = 0 ; i < nParamCount ; i++ )
227             {
228                 if ("-lang".equals(aStrs[i]) )
229                 {
230                     aLanguageStr = aStrs[i + 1];
231                     i++;
232                 }
233                 else if( "-index".equals(aStrs[i]) )
234                 {
235                     aIndexStr = aStrs[i+1];
236                     i++;
237                 }
238                 else if( "-query".equals(aStrs[i]) )
239                 {
240                     aQueryStr = aStrs[i+1];
241                     i++;
242                 }
243                 else if( "-caption".equals(aStrs[i]) )
244                 {
245                     bCaptionOnly = true;
246                 }
247             }
248             String[] aDocs = queryImpl( aLanguageStr, aIndexStr, aQueryStr, bCaptionOnly, aScoreOutArray );
249 
250             return aDocs;
251         }
252 
253         private static String[] queryImpl( String aLanguageStr, String aIndexStr, String aQueryStr,
254             boolean bCaptionOnly, Object[] aScoreOutArray ) throws Exception
255         {
256             IndexReader reader = IndexReader.open( aIndexStr );
257             Searcher searcher = new IndexSearcher( reader );
258             Analyzer analyzer = aLanguageStr.equals("ja") ? (Analyzer)new CJKAnalyzer() : (Analyzer)new StandardAnalyzer();
259 
260             String aField;
261             if( bCaptionOnly )
262                 aField = "caption";
263             else
264                 aField = "content";
265 
266             Query aQuery;
267             if( aQueryStr.endsWith( "*" ) )
268                 aQuery = new WildcardQuery( new Term( aField, aQueryStr ) );
269             else
270                 aQuery = new TermQuery( new Term( aField, aQueryStr ) );
271 
272             // Perform search
273             Hits aHits = searcher.search( aQuery );
274             int nHitCount = aHits.length();
275 
276             String aDocs[] = new String[nHitCount];
277             float aScores[] = null;
278             aScores = new float[nHitCount];
279             for( int iHit = 0 ; iHit < nHitCount ; iHit++ )
280             {
281                 Document aDoc = aHits.doc( iHit );
282                 String aPath = aDoc.get( "path" );
283                 aDocs[iHit] = ( aPath != null ) ? aPath : "";
284                 aScores[iHit] = aHits.score( iHit );
285             }
286             aScoreOutArray[0] = aScores;
287 
288             reader.close();
289 
290             return aDocs;
291         }
292     }
293 
294     /**
295      * Gives a factory for creating the service.
296      * This method is called by the <code>JavaLoader</code>
297      * <p>
298      * @return  returns a <code>XSingleComponentFactory</code> for creating
299      *          the component
300      * @param   sImplName the name of the implementation for which a
301      *          service is desired
302      * @see     com.sun.star.comp.loader.JavaLoader
303      */
304     public static XSingleComponentFactory __getComponentFactory(String sImplName)
305     {
306         XSingleComponentFactory xFactory = null;
307 
308         if ( sImplName.equals( _HelpSearch.class.getName() ) )
309             xFactory = Factory.createComponentFactory(_HelpSearch.class,
310                                              _HelpSearch.getServiceNames());
311 
312         return xFactory;
313     }
314 
315         /** This method is a member of the interface for initializing an object
316          * directly after its creation.
317          * @param object This array of arbitrary objects will be passed to the
318          * component after its creation.
319          * @throws Exception Every exception will not be handled, but will be
320          * passed to the caller.
321          */
322         public void initialize( Object[] object )
323             throws com.sun.star.uno.Exception {
324             /* The component describes what arguments its expected and in which
325              * order!At this point you can read the objects and can intialize
326              * your component using these objects.
327              */
328         }
329 }
330