Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "sal/config.h"
30 : :
31 : : #include <fstream>
32 : : #include <functional>
33 : :
34 : : #include <osl/file.hxx>
35 : : #include <sal/log.hxx>
36 : :
37 : : #include <stdio.h>
38 : : #include <stdlib.h>
39 : : #include "helpmerge.hxx"
40 : : #include <algorithm>
41 : : #include <sys/types.h>
42 : : #include <sys/stat.h>
43 : : #include <iostream>
44 : : #include <fstream>
45 : : #include <vector>
46 : : #include <rtl/strbuf.hxx>
47 : : #ifdef WNT
48 : : #include <windows.h>
49 : : #undef CopyFile
50 : : #include <direct.h>
51 : : #endif
52 : :
53 : : #include "common.hxx"
54 : : #include "helper.hxx"
55 : :
56 : : #if OSL_DEBUG_LEVEL > 2
57 : : void HelpParser::Dump(XMLHashMap* rElem_in)
58 : : {
59 : : for(XMLHashMap::iterator pos = rElem_in->begin();pos != rElem_in->end(); ++pos)
60 : : {
61 : : Dump(pos->second,pos->first);
62 : : }
63 : : }
64 : :
65 : : void HelpParser::Dump(LangHashMap* rElem_in,const rtl::OString & sKey_in)
66 : : {
67 : : rtl::OString x;
68 : : OString y;
69 : : fprintf(stdout,"+------------%s-----------+\n",sKey_in.getStr() );
70 : : for(LangHashMap::iterator posn=rElem_in->begin();posn!=rElem_in->end();++posn)
71 : : {
72 : : x=posn->first;
73 : : y=posn->second->ToOString();
74 : : fprintf(stdout,"key=%s value=%s\n",x.getStr(),y.getStr());
75 : : }
76 : : fprintf(stdout,"+--------------------------+\n");
77 : : }
78 : : #endif
79 : :
80 : 0 : HelpParser::HelpParser( const rtl::OString &rHelpFile )
81 : 0 : : sHelpFile( rHelpFile )
82 : 0 : {};
83 : :
84 : : /*****************************************************************************/
85 : 0 : bool HelpParser::CreateSDF(
86 : : /*****************************************************************************/
87 : : const rtl::OString &rSDFFile_in, const rtl::OString &rPrj_in,const rtl::OString &rRoot_in,
88 : : const rtl::OString &sHelpFile, XMLFile *pXmlFile, const rtl::OString &rGsi1){
89 : 0 : SimpleXMLParser aParser;
90 : : rtl::OUString sXmlFile(
91 : 0 : rtl::OStringToOUString(sHelpFile, RTL_TEXTENCODING_ASCII_US));
92 : : //TODO: explicit BOM handling?
93 : :
94 : 0 : std::auto_ptr <XMLFile> file ( aParser.Execute( sXmlFile, pXmlFile ) );
95 : :
96 : 0 : if(file.get() == NULL)
97 : : {
98 : : printf(
99 : : "%s: %s\n",
100 : : sHelpFile.getStr(),
101 : : (rtl::OUStringToOString(
102 : 0 : aParser.GetError().sMessage, RTL_TEXTENCODING_ASCII_US).
103 : 0 : getStr()));
104 : 0 : exit(-1);
105 : : }
106 : 0 : file->Extract();
107 : 0 : if( !file->CheckExportStatus() ){
108 : 0 : return true;
109 : : }
110 : : std::ofstream aSDFStream(
111 : 0 : rSDFFile_in.getStr(), std::ios_base::out | std::ios_base::trunc);
112 : :
113 : 0 : if (!aSDFStream.is_open()) {
114 : 0 : fprintf(stdout,"Can't open file %s\n",rSDFFile_in.getStr());
115 : 0 : return false;
116 : : }
117 : :
118 : : rtl::OString sActFileName(
119 : 0 : common::pathnameToken(sHelpFile.getStr(), rRoot_in.getStr()));
120 : :
121 : 0 : XMLHashMap* aXMLStrHM = file->GetStrings();
122 : : LangHashMap* pElem;
123 : 0 : XMLElement* pXMLElement = NULL;
124 : :
125 : 0 : OUStringBuffer sBuffer;
126 : 0 : const OUString sOUPrj( rPrj_in.getStr() , rPrj_in.getLength() , RTL_TEXTENCODING_ASCII_US );
127 : 0 : const OUString sOUActFileName(sActFileName.getStr() , sActFileName.getLength() , RTL_TEXTENCODING_ASCII_US );
128 : 0 : const OUString sOUGsi1( rGsi1.getStr() , rGsi1.getLength() , RTL_TEXTENCODING_ASCII_US );
129 : :
130 : 0 : Export::InitLanguages( false );
131 : 0 : std::vector<rtl::OString> aLanguages = Export::GetLanguages();
132 : :
133 : 0 : std::vector<rtl::OString> order = file->getOrder();
134 : 0 : std::vector<rtl::OString>::iterator pos;
135 : 0 : XMLHashMap::iterator posm;
136 : :
137 : 0 : for( pos = order.begin(); pos != order.end() ; ++pos )
138 : : {
139 : 0 : posm = aXMLStrHM->find( *pos );
140 : 0 : pElem = posm->second;
141 : 0 : rtl::OString sCur;
142 : :
143 : 0 : for( unsigned int n = 0; n < aLanguages.size(); n++ )
144 : : {
145 : 0 : sCur = aLanguages[ n ];
146 : 0 : pXMLElement = (*pElem)[ sCur ];
147 : :
148 : 0 : if( pXMLElement != NULL )
149 : : {
150 : : OUString data(
151 : : pXMLElement->ToOUString().
152 : : replaceAll(
153 : : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\n")),
154 : : rtl::OUString()).
155 : : replaceAll(
156 : : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\t")),
157 : 0 : rtl::OUString()));
158 : 0 : sBuffer.append( sOUPrj );
159 : 0 : sBuffer.append('\t');
160 : 0 : if ( !rRoot_in.isEmpty())
161 : 0 : sBuffer.append( sOUActFileName );
162 : 0 : sBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("\t0\t"));
163 : 0 : sBuffer.append( sOUGsi1 ); //"help";
164 : 0 : sBuffer.append('\t');
165 : 0 : rtl::OString sID = posm->first; // ID
166 : 0 : sBuffer.append( rtl::OStringToOUString( sID, RTL_TEXTENCODING_UTF8 ) );
167 : 0 : sBuffer.append('\t');
168 : 0 : rtl::OString sOldRef = pXMLElement->GetOldref(); // oldref
169 : 0 : sBuffer.append( rtl::OStringToOUString(sOldRef, RTL_TEXTENCODING_UTF8 ) );
170 : 0 : sBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("\t\t\t0\t"));
171 : 0 : sBuffer.append( rtl::OStringToOUString( sCur, RTL_TEXTENCODING_UTF8 ) );
172 : 0 : sBuffer.append('\t');
173 : 0 : sBuffer.append( data );
174 : 0 : sBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("\t\t\t\t"));
175 : 0 : rtl::OString sOut(rtl::OUStringToOString(sBuffer.makeStringAndClear().getStr() , RTL_TEXTENCODING_UTF8));
176 : 0 : if( !data.isEmpty() )
177 : 0 : aSDFStream << sOut.getStr() << '\n';
178 : 0 : pXMLElement=NULL;
179 : : }
180 : : else
181 : : {
182 : 0 : fprintf(stdout,"\nDBG: NullPointer in HelpParser::CreateSDF, Language %s, File %s\n", sCur.getStr(), sHelpFile.getStr());
183 : : }
184 : : }
185 : 0 : }
186 : 0 : aSDFStream.close();
187 : :
188 : 0 : return sal_True;
189 : : }
190 : :
191 : 0 : bool HelpParser::Merge( const rtl::OString &rSDFFile, const rtl::OString &rDestinationFile ,
192 : : const rtl::OString& rLanguage , MergeDataFile& aMergeDataFile )
193 : : {
194 : :
195 : : (void) rSDFFile;
196 : 0 : bool hasNoError = true;
197 : :
198 : 0 : SimpleXMLParser aParser;
199 : :
200 : : rtl::OUString sXmlFile(
201 : 0 : rtl::OStringToOUString(sHelpFile, RTL_TEXTENCODING_ASCII_US));
202 : : //TODO: explicit BOM handling?
203 : :
204 : 0 : XMLFile* xmlfile = ( aParser.Execute( sXmlFile, new XMLFile( rtl::OUString('0') ) ) );
205 : 0 : hasNoError = MergeSingleFile( xmlfile , aMergeDataFile , rLanguage , rDestinationFile );
206 : 0 : delete xmlfile;
207 : 0 : return hasNoError;
208 : : }
209 : :
210 : 0 : void HelpParser::parse_languages( std::vector<rtl::OString>& aLanguages , MergeDataFile& aMergeDataFile ){
211 : 0 : std::vector<rtl::OString> aTmp;
212 : :
213 : 0 : Export::InitLanguages( false );
214 : :
215 : 0 : if (Export::sLanguages.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("ALL")))
216 : : {
217 : 0 : aLanguages = aMergeDataFile.GetLanguages();
218 : 0 : aLanguages.push_back(rtl::OString(RTL_CONSTASCII_STRINGPARAM("en-US")));
219 : :
220 : 0 : if( !Export::sForcedLanguages.isEmpty() )
221 : : {
222 : 0 : std::vector<rtl::OString> aFL = Export::GetForcedLanguages();
223 : : std::copy( aFL.begin() ,
224 : : aFL.end() ,
225 : : back_inserter( aLanguages )
226 : 0 : );
227 : 0 : std::sort( aLanguages.begin() , aLanguages.end() , std::less< rtl::OString >() );
228 : 0 : std::vector<rtl::OString>::iterator unique_iter = std::unique( aLanguages.begin() , aLanguages.end() , std::equal_to< rtl::OString >() );
229 : 0 : std::copy( aLanguages.begin() , unique_iter , back_inserter( aTmp ) );
230 : 0 : aLanguages = aTmp;
231 : : }
232 : : }
233 : : else{
234 : 0 : aLanguages = Export::GetLanguages();
235 : 0 : }
236 : :
237 : 0 : }
238 : :
239 : 0 : bool HelpParser::Merge(
240 : : const rtl::OString &rSDFFile, const rtl::OString &rPathX , const rtl::OString &rPathY , bool bISO ,
241 : : const std::vector<rtl::OString>& aLanguages , MergeDataFile& aMergeDataFile , bool bCreateDir )
242 : : {
243 : :
244 : :
245 : : (void) rSDFFile ;
246 : 0 : bool hasNoError = true;
247 : 0 : SimpleXMLParser aParser;
248 : : rtl::OUString sXmlFile(
249 : 0 : rtl::OStringToOUString(sHelpFile, RTL_TEXTENCODING_ASCII_US));
250 : : //TODO: explicit BOM handling?
251 : :
252 : 0 : XMLFile* xmlfile = aParser.Execute( sXmlFile, new XMLFile( rtl::OUString('0') ) );
253 : :
254 : 0 : if( xmlfile == NULL)
255 : : {
256 : 0 : printf("%s\n", rtl::OUStringToOString(aParser.GetError().sMessage, RTL_TEXTENCODING_UTF8).getStr());
257 : 0 : exit(-1);
258 : : }
259 : :
260 : 0 : xmlfile->Extract();
261 : :
262 : 0 : rtl::OString sCur;
263 : 0 : for( unsigned int n = 0; n < aLanguages.size(); n++ ){
264 : 0 : sCur = aLanguages[ n ];
265 : :
266 : 0 : rtl::OString sFilepath;
267 : 0 : if( bISO ) sFilepath = GetOutpath( rPathX , sCur , rPathY );
268 : 0 : else sFilepath = rPathX;
269 : 0 : if( bCreateDir )
270 : 0 : MakeDir(sFilepath);
271 : :
272 : 0 : XMLFile* file = new XMLFile( *xmlfile );
273 : 0 : sFilepath += sHelpFile;
274 : 0 : hasNoError = MergeSingleFile( file , aMergeDataFile , sCur , sFilepath );
275 : 0 : delete file;
276 : :
277 : 0 : if( !hasNoError ) return false; // Stop on error
278 : 0 : }
279 : :
280 : 0 : delete xmlfile;
281 : 0 : return hasNoError;
282 : : }
283 : :
284 : 0 : bool HelpParser::MergeSingleFile( XMLFile* file , MergeDataFile& aMergeDataFile , const rtl::OString& sLanguage ,
285 : : rtl::OString const & sPath )
286 : : {
287 : 0 : file->Extract();
288 : :
289 : 0 : XMLHashMap* aXMLStrHM = file->GetStrings();
290 : : LangHashMap* aLangHM;
291 : 0 : static ResData pResData( "","","");
292 : 0 : pResData.sResTyp = "help";
293 : :
294 : 0 : for(XMLHashMap::iterator pos=aXMLStrHM->begin();pos!=aXMLStrHM->end();++pos) // Merge every l10n related string
295 : : {
296 : :
297 : 0 : aLangHM = pos->second;
298 : : #if OSL_DEBUG_LEVEL > 2
299 : : printf("*********************DUMPING HASHMAP***************************************");
300 : : Dump(aXMLStrHM);
301 : : printf("DBG: sHelpFile = %s\n",sHelpFile.getStr() );
302 : : #endif
303 : :
304 : 0 : pResData.sGId = pos->first;
305 : 0 : pResData.sFilename = sHelpFile;
306 : :
307 : 0 : ProcessHelp( aLangHM , sLanguage, &pResData , aMergeDataFile );
308 : : }
309 : :
310 : 0 : file->Write(sPath);
311 : 0 : return true;
312 : : }
313 : :
314 : 0 : rtl::OString HelpParser::GetOutpath( const rtl::OString& rPathX , const rtl::OString& sCur , const rtl::OString& rPathY )
315 : : {
316 : 0 : rtl::OString testpath = rPathX;
317 : 0 : if (!testpath.endsWithL(RTL_CONSTASCII_STRINGPARAM("/"))) {
318 : 0 : testpath += "/";
319 : : }
320 : 0 : testpath += sCur;
321 : 0 : testpath += "/";
322 : 0 : rtl::OString sRelativePath( rPathY );
323 : 0 : if (sRelativePath.matchL(RTL_CONSTASCII_STRINGPARAM("/"))) {
324 : 0 : sRelativePath = sRelativePath.copy(1);
325 : : }
326 : 0 : testpath += sRelativePath;
327 : 0 : testpath += "/";
328 : 0 : return testpath;
329 : : }
330 : :
331 : 0 : void HelpParser::MakeDir(const rtl::OString& rPath)
332 : : {
333 : 0 : rtl::OString sTPath(rPath.replaceAll("\\", "/"));
334 : 0 : sal_Int32 cnt = helper::countOccurrences(sTPath, '/');
335 : 0 : rtl::OStringBuffer sCreateDir;
336 : 0 : for (sal_uInt16 i = 0; i <= cnt; ++i)
337 : : {
338 : 0 : sCreateDir.append(sTPath.getToken(i , '/'));
339 : 0 : sCreateDir.append('/');
340 : : #ifdef WNT
341 : : _mkdir( sCreateDir.getStr() );
342 : : #else
343 : 0 : mkdir( sCreateDir.getStr() , S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH );
344 : : #endif
345 : 0 : }
346 : 0 : }
347 : :
348 : :
349 : : /* ProcessHelp Methode: search for en-US entry and replace it with the current language*/
350 : 0 : void HelpParser::ProcessHelp( LangHashMap* aLangHM , const rtl::OString& sCur , ResData *pResData , MergeDataFile& aMergeDataFile ){
351 : :
352 : 0 : XMLElement* pXMLElement = NULL;
353 : 0 : PFormEntrys *pEntrys = NULL;
354 : 0 : XMLData *data = NULL;
355 : :
356 : 0 : rtl::OString sLId;
357 : 0 : rtl::OString sGId;
358 : :
359 : 0 : pEntrys = NULL;
360 : :
361 : 0 : if( !sCur.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("en-US")) ){
362 : 0 : pXMLElement = (*aLangHM)[ "en-US" ];
363 : 0 : if( pXMLElement == NULL )
364 : : {
365 : 0 : printf("Error: Can't find en-US entry\n");
366 : : }
367 : 0 : if( pXMLElement != NULL )
368 : : {
369 : 0 : sLId = pXMLElement->GetOldref();
370 : 0 : pResData->sId = sLId;
371 : :
372 : 0 : pEntrys = aMergeDataFile.GetPFormEntrys( pResData );
373 : 0 : if( pEntrys != NULL)
374 : : {
375 : 0 : rtl::OString sNewText;
376 : 0 : pEntrys->GetText( sNewText, STRING_TYP_TEXT, sCur , true );
377 : : rtl::OUString sNewdata(
378 : 0 : rtl::OStringToOUString(sNewText, RTL_TEXTENCODING_UTF8));
379 : 0 : if (!sNewdata.isEmpty())
380 : : {
381 : 0 : if( pXMLElement != NULL )
382 : : {
383 : 0 : data = new XMLData( sNewdata , NULL , true ); // Add new one
384 : 0 : pXMLElement->RemoveAndDeleteAllChildren();
385 : 0 : pXMLElement->AddChild( data );
386 : 0 : aLangHM->erase( sCur );
387 : : }
388 : 0 : }
389 : : }
390 : 0 : else if( pResData == NULL )
391 : : {
392 : : fprintf(stdout,"Can't find GID=%s LID=%s TYP=%s\n",
393 : : pResData->sGId.getStr(), pResData->sId.getStr(),
394 : 0 : pResData->sResTyp.getStr());
395 : : }
396 : : pXMLElement->ChangeLanguageTag(
397 : 0 : rtl::OStringToOUString(sCur, RTL_TEXTENCODING_ASCII_US));
398 : : }
399 : :
400 : 0 : }
401 : 0 : }
402 : :
403 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|