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