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