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.TopDocs; 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.ScoreDoc; 48 import org.apache.lucene.search.TermQuery; 49 import org.apache.lucene.search.WildcardQuery; 50 import org.apache.lucene.util.Version; 51 import org.apache.lucene.store.NIOFSDirectory; 52 53 import com.sun.star.script.XInvocation; 54 import com.sun.star.beans.XIntrospectionAccess; 55 56 import java.io.File; 57 58 /** This class capsulates the class, that implements the minimal component and a 59 * factory for creating the service (<CODE>__getComponentFactory</CODE>). 60 */ 61 public class HelpSearch 62 { 63 /** This class implements the component. At least the interfaces XServiceInfo, 64 * XTypeProvider, and XInitialization should be provided by the service. 65 */ 66 public static class _HelpSearch extends WeakBase 67 implements XServiceInfo, XInvocation 68 { 69 /** The service name, that must be used to get an instance of this service. 70 */ 71 static private final String __serviceName = 72 "com.sun.star.help.HelpSearch"; 73 static private final String aSearchMethodName = "search"; 74 75 /** The initial component contextr, that gives access to 76 * the service manager, supported singletons, ... 77 * It's often later used 78 */ 79 private XComponentContext m_cmpCtx; 80 81 /** The service manager, that gives access to all registered services. 82 * It's often later used 83 */ 84 private XMultiComponentFactory m_xMCF; 85 86 /** The constructor of the inner class has a XMultiServiceFactory parameter. 87 * @param xmultiservicefactoryInitialization A special service factory 88 * could be introduced while initializing. 89 */ _HelpSearch(XComponentContext xCompContext)90 public _HelpSearch(XComponentContext xCompContext) 91 { 92 try { 93 m_cmpCtx = xCompContext; 94 m_xMCF = m_cmpCtx.getServiceManager(); 95 } 96 catch( Exception e ) { 97 e.printStackTrace(); 98 } 99 } 100 101 /** This method returns an array of all supported service names. 102 * @return Array of supported service names. 103 */ getSupportedServiceNames()104 public String[] getSupportedServiceNames() 105 { 106 return getServiceNames(); 107 } 108 109 /** This method is a simple helper function to used in the 110 * static component initialisation functions as well as in 111 * getSupportedServiceNames. 112 */ getServiceNames()113 public static String[] getServiceNames() 114 { 115 String[] sSupportedServiceNames = { __serviceName }; 116 return sSupportedServiceNames; 117 } 118 119 /** This method returns true, if the given service will be 120 * supported by the component. 121 * @param sServiceName Service name. 122 * @return True, if the given service name will be supported. 123 */ supportsService( String sServiceName )124 public boolean supportsService( String sServiceName ) 125 { 126 return sServiceName.equals( __serviceName ); 127 } 128 129 /** Return the class name of the component. 130 * @return Class name of the component. 131 */ getImplementationName()132 public String getImplementationName() 133 { 134 return _HelpSearch.class.getName(); 135 } 136 137 //=================================================== 138 // XInvocation getIntrospection()139 public XIntrospectionAccess getIntrospection() 140 { 141 return null; 142 } 143 invoke( String aFunctionName, java.lang.Object[] aParams, short[][] aOutParamIndex, java.lang.Object[][] aOutParam )144 public Object invoke( String aFunctionName, java.lang.Object[] aParams, 145 short[][] aOutParamIndex, java.lang.Object[][] aOutParam ) 146 throws com.sun.star.lang.IllegalArgumentException, 147 com.sun.star.script.CannotConvertException, 148 com.sun.star.reflection.InvocationTargetException 149 { 150 String[] aRet = null; 151 if( !aFunctionName.equals( aSearchMethodName ) ) 152 throw new com.sun.star.lang.IllegalArgumentException(); 153 154 Object[] aScoreOutArray = new Object[1]; 155 aScoreOutArray[0] = null; 156 try 157 { 158 aRet = doQuery( aParams, aScoreOutArray ); 159 } 160 catch( Exception e ) 161 { 162 aRet = null; 163 } 164 165 Object aScoreArray = aScoreOutArray[0]; 166 if( aScoreArray == null ) 167 { 168 aOutParamIndex[0] = new short[0]; 169 aOutParam[0] = new Object[0]; 170 } 171 else 172 { 173 short nInParamCount = (short)aParams.length; 174 aOutParamIndex[0] = new short[1]; 175 aOutParamIndex[0][0] = nInParamCount; 176 aOutParam[0] = new Object[1]; 177 aOutParam[0][0] = aScoreArray; 178 } 179 180 Any aRetAny = new Any( new Type( String[].class ), aRet ); 181 return aRetAny; 182 } 183 setValue( String aPropertyName, java.lang.Object aValue )184 public void setValue( String aPropertyName, java.lang.Object aValue ) 185 throws com.sun.star.beans.UnknownPropertyException, 186 com.sun.star.script.CannotConvertException, 187 com.sun.star.reflection.InvocationTargetException { 188 throw new com.sun.star.beans.UnknownPropertyException(); 189 } 190 getValue( String aPropertyName )191 public Object getValue( String aPropertyName ) 192 throws com.sun.star.beans.UnknownPropertyException { 193 throw new com.sun.star.beans.UnknownPropertyException(); 194 } 195 hasMethod( String aMethodName )196 public boolean hasMethod( String aMethodName ) { 197 boolean bRet = (aMethodName.equals( aSearchMethodName ) ); 198 return bRet; 199 } hasProperty( String aName )200 public boolean hasProperty( String aName ) { 201 return false; 202 } 203 204 // Command line interface for testing doQuery( Object[] args, Object[] aScoreOutArray )205 private static String[] doQuery( Object[] args, Object[] aScoreOutArray ) throws Exception 206 { 207 String aLanguageStr = ""; 208 String aIndexStr = ""; 209 String aQueryStr = ""; 210 boolean bCaptionOnly = false; 211 212 int nParamCount = args.length; 213 String aStrs[] = new String[nParamCount]; 214 for( int i = 0 ; i < nParamCount ; i++ ) 215 { 216 try 217 { 218 aStrs[i] = AnyConverter.toString( args[i] ); 219 } 220 catch( IllegalArgumentException e ) 221 { 222 aStrs[i] = ""; 223 } 224 } 225 226 // TODO: Error handling 227 for( int i = 0 ; i < nParamCount ; i++ ) 228 { 229 if ("-lang".equals(aStrs[i]) ) 230 { 231 aLanguageStr = aStrs[i + 1]; 232 i++; 233 } 234 else if( "-index".equals(aStrs[i]) ) 235 { 236 aIndexStr = aStrs[i+1]; 237 i++; 238 } 239 else if( "-query".equals(aStrs[i]) ) 240 { 241 aQueryStr = aStrs[i+1]; 242 i++; 243 } 244 else if( "-caption".equals(aStrs[i]) ) 245 { 246 bCaptionOnly = true; 247 } 248 } 249 String[] aDocs = queryImpl( aLanguageStr, aIndexStr, aQueryStr, bCaptionOnly, aScoreOutArray ); 250 251 return aDocs; 252 } 253 queryImpl( String aLanguageStr, String aIndexStr, String aQueryStr, boolean bCaptionOnly, Object[] aScoreOutArray )254 private static String[] queryImpl( String aLanguageStr, String aIndexStr, String aQueryStr, 255 boolean bCaptionOnly, Object[] aScoreOutArray ) throws Exception 256 { 257 File aIndexFile = new File( aIndexStr ); 258 IndexReader reader = IndexReader.open( NIOFSDirectory.open( aIndexFile ), true ); 259 Searcher searcher = new IndexSearcher( reader ); 260 Analyzer analyzer = aLanguageStr.equals("ja") ? (Analyzer)new CJKAnalyzer(Version.LUCENE_29) : (Analyzer)new StandardAnalyzer(Version.LUCENE_29); 261 262 String aField; 263 if( bCaptionOnly ) 264 aField = "caption"; 265 else 266 aField = "content"; 267 268 Query aQuery; 269 if( aQueryStr.endsWith( "*" ) ) 270 aQuery = new WildcardQuery( new Term( aField, aQueryStr ) ); 271 else 272 aQuery = new TermQuery( new Term( aField, aQueryStr ) ); 273 274 // Perform search 275 TopDocs aHits = searcher.search( aQuery, 100 ); 276 int nHitCount = aHits.scoreDocs.length; 277 278 String aDocs[] = new String[nHitCount]; 279 float aScores[] = null; 280 aScores = new float[nHitCount]; 281 for( int iHit = 0 ; iHit < nHitCount ; iHit++ ) 282 { 283 ScoreDoc aDoc = aHits.scoreDocs[iHit]; 284 String aPath = searcher.doc(aDoc.doc).get( "path" ); 285 aDocs[iHit] = ( aPath != null ) ? aPath : ""; 286 aScores[iHit] = aDoc.score; 287 } 288 aScoreOutArray[0] = aScores; 289 290 reader.close(); 291 292 return aDocs; 293 } 294 } 295 296 /** 297 * Gives a factory for creating the service. 298 * This method is called by the <code>JavaLoader</code> 299 * <p> 300 * @return returns a <code>XSingleComponentFactory</code> for creating 301 * the component 302 * @param sImplName the name of the implementation for which a 303 * service is desired 304 * @see com.sun.star.comp.loader.JavaLoader 305 */ __getComponentFactory(String sImplName)306 public static XSingleComponentFactory __getComponentFactory(String sImplName) 307 { 308 XSingleComponentFactory xFactory = null; 309 310 if ( sImplName.equals( _HelpSearch.class.getName() ) ) 311 xFactory = Factory.createComponentFactory(_HelpSearch.class, 312 _HelpSearch.getServiceNames()); 313 314 return xFactory; 315 } 316 317 /** This method is a member of the interface for initializing an object 318 * directly after its creation. 319 * @param object This array of arbitrary objects will be passed to the 320 * component after its creation. 321 * @throws Exception Every exception will not be handled, but will be 322 * passed to the caller. 323 */ initialize( Object[] object )324 public void initialize( Object[] object ) 325 throws com.sun.star.uno.Exception { 326 /* The component describes what arguments its expected and in which 327 * order!At this point you can read the objects and can intialize 328 * your component using these objects. 329 */ 330 } 331 } 332