1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: HelpIndexer.java,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 package com
.sun
.star
.help
;
33 import com
.sun
.star
.lib
.uno
.helper
.WeakBase
;
34 import com
.sun
.star
.lang
.XServiceInfo
;
35 import com
.sun
.star
.script
.XInvocation
;
36 import com
.sun
.star
.beans
.XIntrospectionAccess
;
37 import com
.sun
.star
.uno
.AnyConverter
;
38 import com
.sun
.star
.uno
.XComponentContext
;
40 import java
.io
.FileInputStream
;
41 import java
.io
.FileOutputStream
;
42 import java
.util
.Arrays
;
43 import java
.util
.HashSet
;
44 import java
.util
.List
;
45 import java
.util
.zip
.ZipEntry
;
46 import java
.util
.zip
.ZipOutputStream
;
47 import java
.util
.zip
.CRC32
;
48 import org
.apache
.lucene
.analysis
.standard
.StandardAnalyzer
;
49 import org
.apache
.lucene
.analysis
.cjk
.CJKAnalyzer
;
50 import org
.apache
.lucene
.analysis
.Analyzer
;
51 import org
.apache
.lucene
.index
.IndexWriter
;
54 import java
.io
.FileNotFoundException
;
55 import java
.io
.IOException
;
56 import java
.util
.Date
;
58 public class HelpIndexer
extends WeakBase
59 implements XServiceInfo
, XInvocation
61 static private final String __serviceName
=
62 "com.sun.star.help.HelpIndexer";
63 static private final String aCreateIndexMethodName
= "createIndex";
69 public HelpIndexer(XComponentContext xCompContext
)
74 * @param args the command line arguments
76 public static void main( String
[] args
)
78 boolean bExtensionMode
= false;
79 mainImpl( args
, bExtensionMode
);
82 private static void mainImpl( String
[] args
, boolean bExtensionMode
)
84 String aDirToZipStr
= "";
85 String aSrcDirStr
= "";
86 String aLanguageStr
= "";
88 String aTargetZipFileStr
= "";
91 boolean bLang
= false;
93 boolean bZipDir
= false;
94 boolean bSrcDir
= false;
95 boolean bOutput
= false;
97 int nArgCount
= args
.length
;
98 for( int i
= 0 ; i
< nArgCount
; i
++ )
100 if( "-lang".equals(args
[i
]) )
102 if( i
+ 1 < nArgCount
)
104 aLanguageStr
= args
[i
+ 1];
109 else if( "-mod".equals(args
[i
]) )
111 if( i
+ 1 < nArgCount
)
113 aModule
= args
[i
+ 1];
118 else if( "-zipdir".equals(args
[i
]) )
120 if( i
+ 1 < nArgCount
)
122 aDirToZipStr
= args
[i
+ 1];
127 else if( "-srcdir".equals(args
[i
]) )
129 if( i
+ 1 < nArgCount
)
131 aSrcDirStr
= args
[i
+ 1];
136 else if( "-o".equals(args
[i
]) )
138 if( i
+ 1 < nArgCount
)
140 aTargetZipFileStr
= args
[i
+ 1];
147 if( !bLang
|| !bMod
|| !bZipDir
|| (!bOutput
&& !bExtensionMode
) )
152 System
.out
.println("Usage: HelpIndexer -lang ISOLangCode -mod HelpModule -zipdir TempZipDir -o OutputZipFile");
156 String aIndexDirName
= aModule
+ ".idxl";
157 File aIndexDir
= new File( aDirToZipStr
+ File
.separator
+ aIndexDirName
);
159 aSrcDirStr
= aDirToZipStr
;
160 File aCaptionFilesDir
= new File( aSrcDirStr
+ File
.separator
+ "caption" );
161 File aContentFilesDir
= new File( aSrcDirStr
+ File
.separator
+ "content" );
165 Date start
= new Date();
166 Analyzer analyzer
= aLanguageStr
.equals("ja") ?
(Analyzer
)new CJKAnalyzer() : (Analyzer
)new StandardAnalyzer();
167 IndexWriter writer
= new IndexWriter( aIndexDir
, analyzer
, true );
168 if( !bExtensionMode
)
169 System
.out
.println( "Lucene: Indexing to directory '" + aIndexDir
+ "'..." );
170 int nRet
= indexDocs( writer
, aModule
, bExtensionMode
, aCaptionFilesDir
, aContentFilesDir
);
173 if( !bExtensionMode
)
175 System
.out
.println();
176 System
.out
.println( "Optimizing ..." );
186 deleteRecursively( aCaptionFilesDir
);
187 deleteRecursively( aContentFilesDir
);
193 deleteRecursively( aIndexDir
);
195 if( !bExtensionMode
)
196 System
.out
.println( "Zipping ..." );
197 File aDirToZipFile
= new File( aDirToZipStr
);
198 createZipFile( aDirToZipFile
, aTargetZipFileStr
);
199 deleteRecursively( aDirToZipFile
);
202 Date end
= new Date();
203 if( !bExtensionMode
)
204 System
.out
.println(end
.getTime() - start
.getTime() + " total milliseconds");
206 catch (IOException e
)
211 System
.out
.println(" caught a " + e
.getClass() +
212 "\n with message: " + e
.getMessage());
217 private static int indexDocs(IndexWriter writer
, String aModule
, boolean bExtensionMode
,
218 File aCaptionFilesDir
, File aContentFilesDir
) throws IOException
220 if( !aCaptionFilesDir
.canRead() || !aCaptionFilesDir
.isDirectory() )
222 if( !bExtensionMode
)
223 System
.out
.println( "Not found: " + aCaptionFilesDir
);
226 if( !aContentFilesDir
.canRead() || !aContentFilesDir
.isDirectory() )
228 if( !bExtensionMode
)
229 System
.out
.println( "Not found: " + aContentFilesDir
);
233 String
[] aCaptionFiles
= aCaptionFilesDir
.list();
234 List aCaptionFilesList
= Arrays
.asList( aCaptionFiles
);
235 HashSet aCaptionFilesHashSet
= new HashSet( aCaptionFilesList
);
237 String
[] aContentFiles
= aContentFilesDir
.list();
238 List aContentFilesList
= Arrays
.asList( aContentFiles
);
239 HashSet aContentFilesHashSet
= new HashSet( aContentFilesList
);
241 // Loop over caption files and find corresponding content file
242 if( !bExtensionMode
)
243 System
.out
.println( "Indexing, adding files" );
244 int nCaptionFilesLen
= aCaptionFiles
.length
;
245 for( int i
= 0 ; i
< nCaptionFilesLen
; i
++ )
247 String aCaptionFileStr
= aCaptionFiles
[i
];
248 File aCaptionFile
= new File( aCaptionFilesDir
, aCaptionFileStr
);
249 File aContentFile
= null;
250 if( aContentFilesHashSet
.contains( aCaptionFileStr
) )
251 aContentFile
= new File( aContentFilesDir
, aCaptionFileStr
);
253 if( !bExtensionMode
)
254 System
.out
.print( "." );
255 writer
.addDocument( HelpFileDocument
.Document( aModule
, aCaptionFile
, aContentFile
) );
258 // Loop over content files to find remaining files not mapped to caption files
259 int nContentFilesLen
= aContentFiles
.length
;
260 for( int i
= 0 ; i
< nContentFilesLen
; i
++ )
262 String aContentFileStr
= aContentFiles
[i
];
263 if( !aCaptionFilesHashSet
.contains( aContentFileStr
) )
265 // Not already handled in caption files loop
266 File aCaptionFile
= null;
267 File aContentFile
= new File( aContentFilesDir
, aContentFileStr
);
268 if( !bExtensionMode
)
269 System
.out
.print( "." );
270 writer
.addDocument( HelpFileDocument
.Document( aModule
, aCaptionFile
, aContentFile
) );
276 public static void createZipFile( File aDirToZip
, String aTargetZipFileStr
)
277 throws FileNotFoundException
, IOException
279 FileOutputStream fos
= new FileOutputStream( aTargetZipFileStr
);
280 ZipOutputStream zos
= new ZipOutputStream( fos
);
282 File
[] aChildrenFiles
= aDirToZip
.listFiles();
283 int nFileCount
= aChildrenFiles
.length
;
284 for( int i
= 0 ; i
< nFileCount
; i
++ )
285 addToZipRecursively( zos
, aChildrenFiles
[i
], null );
290 public static void addToZipRecursively( ZipOutputStream zos
, File aFile
, String aBasePath
)
291 throws FileNotFoundException
, IOException
293 if( aFile
.isDirectory() )
295 String aDirName
= aFile
.getName();
296 if( aDirName
.equalsIgnoreCase( "caption" ) || aDirName
.equalsIgnoreCase( "content" ) )
299 File
[] aChildrenFiles
= aFile
.listFiles();
300 String aNewBasePath
= "";
301 if( aBasePath
!= null )
302 aNewBasePath
+= aBasePath
+ File
.separator
;
303 aNewBasePath
+= aDirName
;
305 int nFileCount
= aChildrenFiles
.length
;
306 for( int i
= 0 ; i
< nFileCount
; i
++ )
307 addToZipRecursively( zos
, aChildrenFiles
[i
], aNewBasePath
);
313 // read contents of file we are going to put in the zip
314 int fileLength
= (int) aFile
.length();
315 FileInputStream fis
= new FileInputStream( aFile
);
316 byte[] wholeFile
= new byte[fileLength
];
317 int bytesRead
= fis
.read( wholeFile
, 0, fileLength
);
320 String aFileName
= aFile
.getName();
321 String aEntryName
= "";
322 if( aBasePath
!= null )
323 aEntryName
+= aBasePath
+ "/";
324 aEntryName
+= aFileName
;
325 ZipEntry aZipEntry
= new ZipEntry( aEntryName
);
326 aZipEntry
.setTime( aFile
.lastModified() );
327 aZipEntry
.setSize( fileLength
);
329 int nMethod
= ( aFileName
.toLowerCase().endsWith( ".jar" ) )
330 ? ZipEntry
.STORED
: ZipEntry
.DEFLATED
;
331 aZipEntry
.setMethod( nMethod
);
333 CRC32 tempCRC
= new CRC32();
334 tempCRC
.update( wholeFile
, 0, wholeFile
.length
);
335 aZipEntry
.setCrc( tempCRC
.getValue() );
337 // write the contents into the zip element
338 zos
.putNextEntry( aZipEntry
);
339 zos
.write( wholeFile
, 0, fileLength
);
343 static public boolean deleteRecursively( File aFile
)
345 if( aFile
.isDirectory() )
347 File
[] aChildrenFiles
= aFile
.listFiles();
348 int nFileCount
= aChildrenFiles
.length
;
349 for( int i
= 0 ; i
< nFileCount
; i
++ )
351 File aChildrenFile
= aChildrenFiles
[i
];
352 boolean bSuccess
= deleteRecursively( aChildrenFile
);
358 return aFile
.delete();
361 //===================================================
363 public XIntrospectionAccess
getIntrospection()
368 public Object
invoke( String aFunctionName
, java
.lang
.Object
[] aParams
,
369 short[][] aOutParamIndex
, java
.lang
.Object
[][] aOutParam
)
370 throws com
.sun
.star
.lang
.IllegalArgumentException
,
371 com
.sun
.star
.script
.CannotConvertException
,
372 com
.sun
.star
.reflection
.InvocationTargetException
374 if( !aFunctionName
.equals( aCreateIndexMethodName
) )
375 throw new com
.sun
.star
.lang
.IllegalArgumentException();
377 aOutParamIndex
[0] = new short[0];
378 aOutParam
[0] = new Object
[0];
380 int nParamCount
= aParams
.length
;
381 String aStrs
[] = new String
[nParamCount
];
382 for( int i
= 0 ; i
< nParamCount
; i
++ )
386 aStrs
[i
] = AnyConverter
.toString( aParams
[i
] );
388 catch( IllegalArgumentException e
)
394 boolean bExtensionMode
= true;
395 mainImpl( aStrs
, bExtensionMode
);
400 public void setValue( String aPropertyName
, java
.lang
.Object aValue
)
401 throws com
.sun
.star
.beans
.UnknownPropertyException
,
402 com
.sun
.star
.script
.CannotConvertException
,
403 com
.sun
.star
.reflection
.InvocationTargetException
405 throw new com
.sun
.star
.beans
.UnknownPropertyException();
408 public Object
getValue( String aPropertyName
)
409 throws com
.sun
.star
.beans
.UnknownPropertyException
411 throw new com
.sun
.star
.beans
.UnknownPropertyException();
414 public boolean hasMethod( String aMethodName
)
416 boolean bRet
= (aMethodName
.equals( aCreateIndexMethodName
) );
419 public boolean hasProperty( String aName
) {
424 /** This method returns an array of all supported service names.
425 * @return Array of supported service names.
427 public String
[] getSupportedServiceNames()
429 return getServiceNames();
432 /** This method is a simple helper function to used in the
433 * static component initialisation functions as well as in
434 * getSupportedServiceNames.
436 public static String
[] getServiceNames()
438 String
[] sSupportedServiceNames
= { __serviceName
};
439 return sSupportedServiceNames
;
442 /** This method returns true, if the given service will be
443 * supported by the component.
444 * @param sServiceName Service name.
445 * @return True, if the given service name will be supported.
447 public boolean supportsService( String sServiceName
)
449 return sServiceName
.equals( __serviceName
);
452 /** Return the class name of the component.
453 * @return Class name of the component.
455 public String
getImplementationName()
457 return HelpIndexer
.class.getName();