xref: /AOO41X/main/l10ntools/source/help/HelpIndexerTool.java (revision 54628ca40d27d15cc98fe861da7fff7e60c2f7d6)
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 java.io.FileInputStream;
27 import java.io.FileOutputStream;
28 import java.util.Arrays;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.zip.ZipEntry;
32 import java.util.zip.ZipOutputStream;
33 import java.util.zip.CRC32;
34 import org.apache.lucene.analysis.standard.StandardAnalyzer;
35 import org.apache.lucene.analysis.cjk.CJKAnalyzer;
36 import org.apache.lucene.analysis.Analyzer;
37 import org.apache.lucene.index.IndexWriter;
38 import org.apache.lucene.util.Version;
39 import org.apache.lucene.store.NIOFSDirectory;
40 
41 import java.io.File;
42 import java.io.FileNotFoundException;
43 import java.io.IOException;
44 import java.util.Date;
45 
46 public class HelpIndexerTool
47 {
48     public HelpIndexerTool()
49     {
50     }
51 
52 
53     /**
54      * @param args the command line arguments
55      */
56     public static void main( String[] args )
57     {
58         boolean bExtensionMode = false;
59         mainImpl( args, bExtensionMode );
60     }
61 
62     public static void mainImpl( String[] args, boolean bExtensionMode )
63     {
64         String aDirToZipStr = "";
65         String aSrcDirStr = "";
66         String aLanguageStr = "";
67         String aModule = "";
68         String aTargetZipFileStr = "";
69         String aCfsName = "";
70         String aSegmentName = "";
71 
72         // Scan arguments
73         //If this tool is invoked in the build process for extensions help,
74         //then -extension must be set.
75         boolean bExtension = false;
76         boolean bLang = false;
77         boolean bMod = false;
78         boolean bZipDir = false;
79         boolean bSrcDir = false;
80         boolean bOutput = false;
81         boolean bCfsName = false;
82         boolean bSegmentName = false;
83 
84         int nArgCount = args.length;
85         for( int i = 0 ; i < nArgCount ; i++ )
86         {
87             if( "-extension".equals(args[i]) )
88             {
89                 bExtension = true;
90             }
91             else if( "-lang".equals(args[i]) )
92             {
93                 if( i + 1 < nArgCount )
94                 {
95                     aLanguageStr = args[i + 1];
96                     bLang = true;
97                 }
98                 i++;
99             }
100             else if( "-mod".equals(args[i]) )
101             {
102                 if( i + 1 < nArgCount )
103                 {
104                     aModule = args[i + 1];
105                     bMod = true;
106                 }
107                 i++;
108             }
109             else if( "-zipdir".equals(args[i]) )
110             {
111                 if( i + 1 < nArgCount )
112                 {
113                     aDirToZipStr = args[i + 1];
114                     bZipDir = true;
115                 }
116                 i++;
117             }
118             else if( "-srcdir".equals(args[i]) )
119             {
120                 if( i + 1 < nArgCount )
121                 {
122                     aSrcDirStr = args[i + 1];
123                     bSrcDir = true;
124                 }
125                 i++;
126             }
127             else if( "-o".equals(args[i]) )
128             {
129                 if( i + 1 < nArgCount )
130                 {
131                     aTargetZipFileStr = args[i + 1];
132                     bOutput = true;
133                 }
134                 i++;
135             }
136             else if( "-checkcfsandsegname".equals(args[i]) )
137             {
138                 if( i + 1 < nArgCount )
139                 {
140                     aCfsName = args[i + 1] + ".cfs";
141                     bCfsName = true;
142                 }
143                 i++;
144                 if( i + 1 < nArgCount )
145                 {
146                     aSegmentName = "segments" + args[i + 1];
147                     bSegmentName = true;
148                 }
149                 i++;
150                 if (!(bCfsName && bSegmentName))
151                 {
152                     System.out.println("Usage: HelpIndexer -checkcfsandsegname _0 _3 (2 arguments needed)");
153                     System.exit( -1 );
154                 }
155             }
156         }
157 
158         if( !bLang || !bMod || !bZipDir || (!bOutput && !bExtensionMode && !bExtension) )
159         {
160             if( bExtensionMode )
161                 return;
162 
163             System.out.println("Usage: HelpIndexer -lang ISOLangCode -mod HelpModule -zipdir TempZipDir -o OutputZipFile");
164             System.out.println("Usage: HelpIndexer -extension -lang ISOLangCode -mod HelpModule -zipdir PathToLangDir");
165             System.exit( -1 );
166         }
167 
168         String aIndexDirName = aModule + ".idxl";
169         File aIndexDir = new File( aDirToZipStr + File.separator + aIndexDirName );
170         if( !bSrcDir )
171             aSrcDirStr = aDirToZipStr;
172         File aCaptionFilesDir = new File( aSrcDirStr + File.separator + "caption" );
173         File aContentFilesDir = new File( aSrcDirStr + File.separator + "content" );
174 
175         try
176         {
177             Date start = new Date();
178         Analyzer analyzer = aLanguageStr.equals("ja") ? (Analyzer)new CJKAnalyzer(Version.LUCENE_29) : (Analyzer)new StandardAnalyzer(Version.LUCENE_29);
179         IndexWriter writer = new IndexWriter( NIOFSDirectory.open(aIndexDir), analyzer, true, IndexWriter.MaxFieldLength.LIMITED );
180             if( !bExtensionMode )
181                 System.out.println( "Lucene: Indexing to directory '" + aIndexDir + "'..." );
182             int nRet = indexDocs( writer, aModule, bExtensionMode, aCaptionFilesDir, aContentFilesDir );
183             if( nRet != -1 )
184             {
185                 if( !bExtensionMode )
186                 {
187                     System.out.println();
188                     System.out.println( "Optimizing ..." );
189                 }
190                 writer.optimize();
191             }
192             writer.close();
193 
194             boolean bCfsFileOk = true;
195             boolean bSegmentFileOk = true;
196             if( bCfsName && bSegmentName && !bExtensionMode && nRet != -1 )
197             {
198                 String aCompleteCfsFileName = aDirToZipStr + File.separator + aIndexDirName + File.separator + aCfsName;
199                 String aCompleteSegmentFileName = aDirToZipStr + File.separator + aIndexDirName + File.separator + aSegmentName;
200                 File aCfsFile = new File( aCompleteCfsFileName );
201                 File aSegmentFile = new File( aCompleteSegmentFileName );
202                 bCfsFileOk = aCfsFile.exists();
203                 bSegmentFileOk = aSegmentFile.exists();
204                 System.out.println( "Checking cfs file " + aCfsName+ ": " + (bCfsFileOk ? "Found" : "Not found") );
205                 System.out.println( "Checking segment file " + aSegmentName+ ": " + (bSegmentFileOk ? "Found" : "Not found") );
206             }
207 
208             if( bExtensionMode || bExtension)
209             {
210                 if( !bSrcDir )
211                 {
212                     deleteRecursively( aCaptionFilesDir );
213                     deleteRecursively( aContentFilesDir );
214                 }
215             }
216             else
217             {
218                 if( nRet == -1 )
219                     deleteRecursively( aIndexDir );
220 
221                 if( bCfsFileOk && bSegmentFileOk )
222                     System.out.println( "Zipping ..." );
223                 File aDirToZipFile = new File( aDirToZipStr );
224                 createZipFile( aDirToZipFile, aTargetZipFileStr );
225                 deleteRecursively( aDirToZipFile );
226             }
227 
228             if( !bCfsFileOk )
229             {
230                 System.out.println( "cfs file check failed, terminating..." );
231                 System.exit( -1 );
232             }
233 
234             if( !bSegmentFileOk )
235             {
236                 System.out.println( "segment file check failed, terminating..." );
237                 System.exit( -1 );
238             }
239 
240             Date end = new Date();
241             if( !bExtensionMode )
242                 System.out.println(end.getTime() - start.getTime() + " total milliseconds");
243         }
244         catch (IOException e)
245         {
246             if( bExtensionMode )
247                 return;
248 
249             System.out.println(" caught a " + e.getClass() +
250                 "\n with message: " + e.getMessage());
251             System.exit( -1 );
252         }
253     }
254 
255     private static int indexDocs(IndexWriter writer, String aModule, boolean bExtensionMode,
256         File aCaptionFilesDir, File aContentFilesDir) throws IOException
257     {
258         if( !aCaptionFilesDir.canRead() || !aCaptionFilesDir.isDirectory() )
259         {
260             if( !bExtensionMode )
261                 System.out.println( "Not found: " + aCaptionFilesDir );
262             return -1;
263         }
264         if( !aContentFilesDir.canRead() || !aContentFilesDir.isDirectory() )
265         {
266             if( !bExtensionMode )
267                 System.out.println( "Not found: " + aContentFilesDir );
268             return -1;
269         }
270 
271         String[] aCaptionFiles = aCaptionFilesDir.list();
272         List aCaptionFilesList = Arrays.asList( aCaptionFiles );
273         HashSet aCaptionFilesHashSet = new HashSet( aCaptionFilesList );
274 
275         String[] aContentFiles = aContentFilesDir.list();
276         List aContentFilesList = Arrays.asList( aContentFiles );
277         HashSet aContentFilesHashSet = new HashSet( aContentFilesList );
278 
279         // Loop over caption files and find corresponding content file
280         if( !bExtensionMode )
281             System.out.println( "Indexing, adding files" );
282         int nCaptionFilesLen = aCaptionFiles.length;
283         for( int i = 0 ; i < nCaptionFilesLen ; i++ )
284         {
285             String aCaptionFileStr = aCaptionFiles[i];
286             File aCaptionFile = new File( aCaptionFilesDir, aCaptionFileStr );
287             File aContentFile = null;
288             if( aContentFilesHashSet.contains( aCaptionFileStr ) )
289                 aContentFile = new File( aContentFilesDir, aCaptionFileStr );
290 
291             if( !bExtensionMode )
292                 System.out.print( "." );
293             writer.addDocument( HelpFileDocument.Document( aModule, aCaptionFile, aContentFile ) );
294         }
295 
296         // Loop over content files to find remaining files not mapped to caption files
297         int nContentFilesLen = aContentFiles.length;
298         for( int i = 0 ; i < nContentFilesLen ; i++ )
299         {
300             String aContentFileStr = aContentFiles[i];
301             if( !aCaptionFilesHashSet.contains( aContentFileStr ) )
302             {
303                 // Not already handled in caption files loop
304                 File aCaptionFile = null;
305                 File aContentFile = new File( aContentFilesDir, aContentFileStr );
306                 if( !bExtensionMode )
307                     System.out.print( "." );
308                 writer.addDocument( HelpFileDocument.Document( aModule, aCaptionFile, aContentFile ) );
309             }
310         }
311         return 0;
312     }
313 
314     public static void createZipFile( File aDirToZip, String aTargetZipFileStr )
315             throws FileNotFoundException, IOException
316     {
317         FileOutputStream fos = new FileOutputStream( aTargetZipFileStr );
318         ZipOutputStream zos = new ZipOutputStream( fos );
319 
320         File[] aChildrenFiles = aDirToZip.listFiles();
321         int nFileCount = aChildrenFiles.length;
322         for( int i = 0 ; i < nFileCount ; i++ )
323             addToZipRecursively( zos, aChildrenFiles[i], null );
324 
325         zos.close();
326     }
327 
328     public static void addToZipRecursively( ZipOutputStream zos, File aFile, String aBasePath )
329             throws FileNotFoundException, IOException
330     {
331         if( aFile.isDirectory() )
332         {
333             String aDirName = aFile.getName();
334             if( aDirName.equalsIgnoreCase( "caption" ) || aDirName.equalsIgnoreCase( "content" ) )
335                 return;
336 
337             File[] aChildrenFiles = aFile.listFiles();
338             String aNewBasePath = "";
339             if( aBasePath != null )
340                 aNewBasePath += aBasePath + File.separator;
341             aNewBasePath += aDirName;
342 
343             int nFileCount = aChildrenFiles.length;
344             for( int i = 0 ; i < nFileCount ; i++ )
345                 addToZipRecursively( zos, aChildrenFiles[i], aNewBasePath );
346 
347             return;
348         }
349 
350         // No directory
351         // read contents of file we are going to put in the zip
352         int fileLength = (int) aFile.length();
353         FileInputStream fis = new FileInputStream( aFile );
354         byte[] wholeFile = new byte[fileLength];
355         int bytesRead = fis.read( wholeFile, 0, fileLength );
356         fis.close();
357 
358         String aFileName = aFile.getName();
359         String aEntryName = "";
360         if( aBasePath != null )
361             aEntryName += aBasePath + "/";
362         aEntryName += aFileName;
363         ZipEntry aZipEntry = new ZipEntry( aEntryName );
364         aZipEntry.setTime( aFile.lastModified() );
365         aZipEntry.setSize( fileLength );
366 
367         int nMethod = ( aFileName.toLowerCase().endsWith( ".jar" ) )
368                 ? ZipEntry.STORED : ZipEntry.DEFLATED;
369         aZipEntry.setMethod( nMethod );
370 
371         CRC32 tempCRC = new CRC32();
372         tempCRC.update( wholeFile, 0, wholeFile.length );
373         aZipEntry.setCrc( tempCRC.getValue() );
374 
375         // write the contents into the zip element
376         zos.putNextEntry( aZipEntry );
377         zos.write( wholeFile, 0, fileLength );
378         zos.closeEntry();
379     }
380 
381     static public boolean deleteRecursively( File aFile )
382     {
383         if( aFile.isDirectory() )
384         {
385             File[] aChildrenFiles = aFile.listFiles();
386             int nFileCount = aChildrenFiles.length;
387             for( int i = 0 ; i < nFileCount ; i++ )
388             {
389                 File aChildrenFile = aChildrenFiles[i];
390                 boolean bSuccess = deleteRecursively( aChildrenFile );
391                 if( !bSuccess )
392                     return false;
393             }
394         }
395 
396         return aFile.delete();
397     }
398 }
399 
400