xref: /AOO41X/main/xmlhelp/source/com/sun/star/help/HelpSearch.java (revision 3b8558fd12b4776aa3c54a9fb2322537ca2a5e4c)
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