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