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  * Converter.java
25  *
26  * create Source and Target
27  * for converting
28  * TODO maybe a factory would be good here
29  */
30 
31 package com.sun.star.tooling.converter;
32 
33 import java.io.BufferedOutputStream;
34 import java.io.File;
35 import java.io.FileNotFoundException;
36 import java.io.FileOutputStream;
37 import java.io.IOException;
38 import java.io.OutputStream;
39 
40 import javax.xml.parsers.ParserConfigurationException;
41 import javax.xml.parsers.SAXParser;
42 import javax.xml.parsers.SAXParserFactory;
43 
44 import org.xml.sax.EntityResolver;
45 import org.xml.sax.SAXException;
46 import org.xml.sax.SAXParseException;
47 import org.xml.sax.XMLReader;
48 import org.xml.sax.helpers.DefaultHandler;
49 
50 /**
51  *
52  * This class handles the creating of the source to read from,
53  * the target to write to and the appropriate DataHandler
54  *
55  * @author Christian Schmidt 2005
56  */
57 public final class Converter {
58 
59     /**
60      * the used charset f.e. UTF-8
61      */
62     private final static String         CHARSET        = new String("UTF-8");
63 
64     private static final String EMPTY          = new String("");
65 
66     /**
67      * The DataHandler use to connect reader and writer
68      */
69     private static DataHandler  handler;
70 
71     /**
72      * Counting the lines written by a writer
73      */
74     private static int          lineCounter;
75 
76     /**
77      * The target to write to
78      */
79     private static DataWriter   theTargetWriter;
80 
81 
82     /**
83      * Overwrite existing files
84      */
85     private boolean             overwrite      = false;
86     /**
87      * The source to read from
88      */
89     private Source              reader;
90     /**
91      * The name of the source file
92      */
93     private String              sourceString;
94     /**
95      * the Type of the Source file(SDF,GSI,XLIFF)
96      */
97     private String              sourceType;
98     /**
99      * The name of the target fille
100      */
101     private String              targetString;
102     /**
103      * the Type of the Target file(SDF,GSI,XLIFF)
104      */
105     private String              targetType;
106     /**
107      * The writer that handles the output
108      */
109     private Target              writer;
110 
111     /**
112      * The sourceLanguage
113      */
114     String                      sourceLanguage = "en-US";
115 
116     /**
117      * The targetLanguage
118      */
119     String                      targetLanguage = "";
120 
121     /**
122      * The name of the second source, needed for GSI to SDF merge
123      */
124     private String secondSourceString=EMPTY;
125 
126 
127     /**
128      * Get the line counter
129      * @return Returns the lineCounter.
130      */
getLineCounter()131     public static int getLineCounter() {
132         return lineCounter;
133     }
134 
135     /**
136      * increment the lineCounter
137      */
countLine()138     final static void countLine() {
139         lineCounter++;
140     }
141 
142     /**
143      * Creates a new instance of Converter
144      *
145      * @param sourceType        the type of the sourceFile
146      * @param sourceString      the name of the sourceFile
147      * @param SourceLanguage    the ISO Id of the sourceLanguage
148      * @param targetType        the type of the targetFile
149      * @param targetString      the name of the targetFile
150      * @param TargetLanguage    the ISO Id of the targetLanguage
151      * @param secondSourceString     the name of the second sourceFile (GSI merge only)
152      * @param overwrite         indicates whether overwrite existing files
153      * @throws IOException
154      * @throws Exception
155      */
Converter(String sourceType, String sourceString, String SourceLanguage, String targetType, String targetString, String TargetLanguage,String secondSourceString, boolean overwrite)156     public Converter(String sourceType, String sourceString,
157             String SourceLanguage, String targetType, String targetString,
158             String TargetLanguage,String secondSourceString, boolean overwrite) throws IOException,
159             Exception {
160 
161         this.sourceType = sourceType;
162         this.sourceString = sourceString;
163         this.sourceLanguage = SourceLanguage;
164         this.targetType = targetType;
165         this.targetString = targetString;
166         this.targetLanguage = TargetLanguage;
167         this.secondSourceString=secondSourceString;
168         this.overwrite = overwrite;
169 
170         handler = new DataHandler();
171 
172         if ("sdf".equalsIgnoreCase(sourceType)) {
173             reader = new SDFSource();
174         } else if ("xliff".equalsIgnoreCase(sourceType)||"dbxliff".equalsIgnoreCase(sourceType)) {
175             reader = new XLIFFSource();
176         } else if ("gsi".equalsIgnoreCase(sourceType)) {
177             reader = new GSISource();
178         } else {
179             throw new ConverterException("Unknown Source File Type: '"+sourceType+"'");
180         }
181 
182         if ("sdf".equalsIgnoreCase(targetType)) {
183             writer = new SDFTarget();
184         } else if ("xliff".equalsIgnoreCase(targetType)) {
185             writer = new XLIFFTarget();
186         } else if ("gsi".equalsIgnoreCase(targetType)) {
187             writer = new GSITarget();
188         } else {
189             throw new ConverterException("Unknown Target File Type: '"+targetType+"'");
190         }
191 
192     }
193 
194     /**
195      * Do the converting from the source file format to the target file format
196      *
197      * @throws IOException
198      */
convert()199     public final void convert() throws IOException {
200 
201         try {
202 
203             reader.convertTo(writer);
204 
205             //TODO this belongs in the Target Class
206             theTargetWriter.flush();
207             theTargetWriter.close();
208         } catch (Exception e) {
209             OutputHandler.out(e.getMessage());
210         }
211 
212     }
213 
214 
215     /**
216      *
217      * Encapsulate the reading from an GSI file
218      *
219      * @author Christian Schmidt 2005
220      *
221      */
222     private class GSISource implements Source {
223         DataReader theSourceReader;
224         /**
225          * Create a new Instance of GSISource
226          *
227          * @throws IOException
228          * @throws Exception
229          */
GSISource()230         public GSISource() throws IOException {
231 
232             theSourceReader = new GSIandSDFMerger(new File(sourceString),new File(secondSourceString), sourceLanguage,
233                     targetLanguage, CHARSET);
234         }
235 
convertTo(Target t)236         public void convertTo(Target t) {
237 
238             try {
239                 theTargetWriter = t.getWriter();
240                 while (handler.fillDataFrom(theSourceReader)) {
241 
242                     theTargetWriter.getDatafrom(handler);
243                     theTargetWriter.writeData();
244                 }
245             } catch (IOException e) {
246                 OutputHandler.out(e.getMessage());
247 
248             } catch (Exception e) {
249                 e.printStackTrace();
250             }
251 
252         }
253 
254     }
255     /**
256      *
257      * Encapsulate to write to a GSI file
258      *
259      * @author Christian Schmidt 2005
260      *
261      */
262     private class GSITarget implements Target {
263 
264         File target;
265 
266         /**
267          * Create a new Instance of GSITarget
268          *
269          * @throws FileNotFoundException
270          * @throws IOException
271          */
GSITarget()272         public GSITarget() throws FileNotFoundException, IOException {
273 
274             target = FileMaker.newFile(targetString, overwrite);
275             theTargetWriter = new GSIWriter(new BufferedOutputStream(
276                     new FileOutputStream(target)), CHARSET);
277         }
278 
getWriter()279         public DataWriter getWriter() {
280 
281             return theTargetWriter;
282         }
283 
284     }
285     /**
286      *
287      * Encapsulate the reading from an SDF file
288      *
289      * @author Christian Schmidt 2005
290      *
291      */
292     private final class SDFSource implements Source {
293 
294         DataReader Source;
295 
296         /**
297          * Create a new Instance of SDFSource
298          * @throws IOException
299          * @throws Exception
300          */
SDFSource()301         public SDFSource() throws IOException, Exception {
302 
303             Source = new SDFReader(new File(sourceString), sourceLanguage,
304                     targetLanguage, CHARSET);
305         }
306 
convertTo(Target t)307         public void convertTo(Target t) {
308             try {
309                 theTargetWriter = t.getWriter();
310                 while (handler.fillDataFrom(Source)) {
311 
312                     theTargetWriter.getDatafrom(handler);
313                     theTargetWriter.writeData();
314                 }
315 
316             } catch (IOException e) {
317                 OutputHandler.out(e.getMessage());
318 
319             } catch (Exception e) {
320                 e.printStackTrace();
321             }
322 
323         }
324 
325     }
326     /**
327      * Encapsulate writing to a SDF file
328      *
329      * @author Christian Schmidt 2005
330      *
331      */
332     private class SDFTarget implements Target {
333 
334         /**
335          * Create a new Instance of SDFTarget
336          *
337          * @throws IOException
338          */
SDFTarget()339         public SDFTarget() throws IOException {
340             File target = FileMaker.newFile(targetString, overwrite);
341             theTargetWriter = new SDFWriter(new BufferedOutputStream(
342                     new FileOutputStream(target)), CHARSET);
343         }
344 
345         /* (non-Javadoc)
346          * @see com.sun.star.tooling.converter.Converter.Target#getWriter()
347          */
getWriter()348         public DataWriter getWriter() {
349 
350             return theTargetWriter;
351         }
352 
353     }
354 
355     /**
356      * The interface for all convertable sources
357      *
358      * @author Christian Schmidt 2005
359      *
360      */
361     private interface Source {
362 
363         DataReader Source=null;
364         /**
365          * Convert this. to the designated target
366          * @param target the target of the converting
367          * @throws IOException
368          */
convertTo(Target target)369         abstract void convertTo(Target target) throws IOException;
370     }
371 
372     /**
373      * The interface for all creatable targets
374      *
375      * @author Christian Schmidt 2005
376      *
377      */
378     private interface Target {
379         /**
380          * The writer to use
381          */
382         public OutputStream writer = null;
383 
384         /**
385          * Get the writer
386          * this target uses to write the
387          * data in the correct format.
388          *
389          * @return the used DataWriter
390          */
getWriter()391         abstract DataWriter getWriter();
392 
393     }
394     /**
395      * Encapsulate the reading from an XLIFF file
396      *
397      * @author Christian Schmidt 2005
398      *
399      */
400     private class XLIFFSource implements Source {
401         File source;
402 
403         /**
404          * Create a new Instance of XLIFFSource
405          *
406          *
407          */
XLIFFSource()408         public XLIFFSource() {
409 
410             source = new File(sourceString);
411         }
412 
convertTo(Target t)413         public void convertTo(Target t) throws IOException {
414             try {
415                 System.setProperty("entityExpansionLimit", "1000000");
416                 boolean laden = source.canRead();
417                 if (laden) {
418                     DefaultHandler contentHandler=null;
419                     if("dbxliff".equalsIgnoreCase(sourceType)){
420                         contentHandler = new XLIFFReader(handler, t
421                                 .getWriter(),false);
422                     }else{
423                         contentHandler = new XLIFFReader(handler, t
424                             .getWriter());
425                     }
426                     SAXParserFactory factory = SAXParserFactory.newInstance();
427                     factory.setNamespaceAware( true );
428                     factory.setValidating( true );
429 
430                     SAXParser parser=factory.newSAXParser();
431                     XMLReader xliffreader=parser.getXMLReader();
432 
433 
434 
435 //                    XMLReader xliffreader = XMLReaderFactory
436 //                            .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
437                     xliffreader.setErrorHandler(contentHandler);
438                     xliffreader.setContentHandler(contentHandler);
439                     /* one possibility to resolve an extern entity (DTD) */
440                     EntityResolver res = new Resolver();
441                     xliffreader.setEntityResolver(res);
442                     /*
443                      * a second possibility to resolve an extern entity (DTD)
444                      *
445                      * xliffreader.setFeature("xml.org/sax/features/validation",true);
446                      * xliffreader.setEntityResolver(new EntityResolver() {
447                      * public InputSource resolveEntity(java.lang.String
448                      * publicId, java.lang.String systemId) throws SAXException,
449                      * java.io.IOException { if (publicId.equals("-//XLIFF//DTD
450                      * XLIFF//EN")) // this deactivates the open office DTD
451                      * return new InputSource(new ByteArrayInputStream( " <?xml
452                      * version='1.0' encoding='UTF-8'?>" .getBytes())); else
453                      * return null; } });
454                      *
455                      */
456 
457                     xliffreader.parse(sourceString);
458 
459                 } else {
460                     System.out.println("Datei existiert nicht");
461                 }
462 
463             } catch (SAXParseException e) {
464                 try {
465                     theTargetWriter.flush();
466                 } catch (IOException e1) {
467 
468                     e1.printStackTrace();
469                 }
470                 OutputHandler.out("PARSE ERROR Zeile " + e.getLineNumber()
471                         + ", " + e.getMessage());
472 
473             }catch (SAXException e){
474                 try {
475                     theTargetWriter.flush();
476                 } catch (IOException e1) {
477 
478                     e1.printStackTrace();
479                 }
480                 OutputHandler.out("PARSE EXCEPTION " +  e.getMessage());
481             } catch (ParserConfigurationException e) {
482                 OutputHandler.out("PARSER Configuration failed\n " +  e.getMessage());
483             }
484         }
485 
486     }
487     /**
488      * Encapsulate writing to a XLIFF file
489      *
490      * @author Christian Schmidt 2005
491      *
492      */
493     private class XLIFFTarget implements Target {
494         File target;
495 
496         /**
497          * Create a new Instance of XLIFFTarget
498          *
499          * @throws FileNotFoundException
500          * @throws IOException
501          */
XLIFFTarget()502         public XLIFFTarget() throws FileNotFoundException, IOException {
503             target = FileMaker.newFile(targetString, overwrite);
504             theTargetWriter = new XLIFFWriter(new BufferedOutputStream(
505                     new FileOutputStream(target)), CHARSET);
506 
507         }
508 
getWriter()509         public DataWriter getWriter() {
510 
511             return theTargetWriter;
512         }
513     }
514 
515 
516 }