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