001    package org.maltparser.core.config;
002    
003    import java.io.BufferedInputStream;
004    import java.io.BufferedOutputStream;
005    import java.io.BufferedReader;
006    import java.io.BufferedWriter;
007    import java.io.File;
008    import java.io.FileInputStream;
009    import java.io.FileNotFoundException;
010    import java.io.FileOutputStream;
011    import java.io.FileReader;
012    import java.io.FileWriter;
013    import java.io.IOException;
014    import java.io.InputStreamReader;
015    import java.io.OutputStreamWriter;
016    import java.io.UnsupportedEncodingException;
017    import java.net.URL;
018    import java.util.Date;
019    import java.util.HashSet;
020    import java.util.SortedSet;
021    import java.util.TreeSet;
022    import java.util.jar.JarEntry;
023    import java.util.jar.JarInputStream;
024    import java.util.jar.JarOutputStream;
025    
026    import org.maltparser.core.exception.MaltChainedException;
027    import org.maltparser.core.helper.SystemInfo;
028    import org.maltparser.core.helper.SystemLogger;
029    import org.maltparser.core.helper.Util;
030    import org.maltparser.core.options.OptionManager;
031    
032    /**
033    * This class contains methods for handle the configuration directory.
034    *
035    * @author Johan Hall
036    */
037    public class ConfigurationDir  {
038            protected static final int BUFFER = 4096;
039            protected File configDirectory;
040            protected String name;
041            protected String type;
042            protected File workingDirectory;
043            protected URL url = null;
044            protected int containerIndex;
045            protected BufferedWriter infoFile = null;
046            protected String createdByMaltParserVersion;
047    
048            
049            /**
050             * Creates a configuration directory from a mco-file specified by an URL.
051             * 
052             * @param url   an URL to a mco-file
053             * @throws MaltChainedException
054             */
055            public ConfigurationDir(URL url) throws MaltChainedException {
056                    initWorkingDirectory();
057                    setUrl(url);
058                    initNameNTypeFromInfoFile(url);
059            }
060            
061            /**
062             * Creates a new configuration directory or a configuration directory from a mco-file
063             * 
064             * @param name  the name of the configuration
065             * @param type  the type of configuration
066             * @param containerIndex        the container index
067             * @throws MaltChainedException
068             */
069            public ConfigurationDir(String name, String type, int containerIndex) throws MaltChainedException {
070                    setContainerIndex(containerIndex);
071                    initWorkingDirectory();
072                    if (name != null && name.length() > 0 && type != null && type.length() > 0) {
073                            setName(name);
074                            setType(type);
075                    } else {
076                            throw new ConfigurationException("The configuration name is not specified. ");
077                    }
078                    setConfigDirectory(new File(workingDirectory.getPath()+File.separator+getName()));
079            }
080            
081            /**
082             * Creates an output stream writer, where the corresponding file will be included in the configuration directory
083             * 
084             * @param fileName      a file name
085             * @param charSet       a char set
086             * @return      an output stream writer for writing to a file within the configuration directory
087             * @throws MaltChainedException
088             */
089            public OutputStreamWriter getOutputStreamWriter(String fileName, String charSet) throws MaltChainedException {
090                    try {
091                            return new OutputStreamWriter(new FileOutputStream(configDirectory.getPath()+File.separator+fileName), charSet);
092                    } catch (FileNotFoundException e) {
093                            throw new ConfigurationException("The file '"+fileName+"' cannot be created. ", e);
094                    } catch (UnsupportedEncodingException e) {
095                            throw new ConfigurationException("The char set '"+charSet+"' is not supported. ", e);
096                    }
097            }
098            
099            /**
100             * Creates an output stream writer, where the corresponding file will be included in the 
101             * configuration directory. Uses UTF-8 for character encoding.
102             * 
103             * @param fileName      a file name
104             * @return an output stream writer for writing to a file within the configuration directory
105             * @throws MaltChainedException
106             */
107            public OutputStreamWriter getOutputStreamWriter(String fileName) throws MaltChainedException {
108                    try {
109                            return new OutputStreamWriter(new FileOutputStream(configDirectory.getPath()+File.separator+fileName), "UTF-8");
110                    } catch (FileNotFoundException e) {
111                            throw new ConfigurationException("The file '"+fileName+"' cannot be created. ", e);
112                    } catch (UnsupportedEncodingException e) {
113                            throw new ConfigurationException("The char set 'UTF-8' is not supported. ", e);
114                    }
115            }
116            
117            /**
118             * Creates an input stream reader for reading a file within the configuration directory
119             * 
120             * @param fileName      a file name
121             * @param charSet       a char set
122             * @return an input stream reader for reading a file within the configuration directory
123             * @throws MaltChainedException
124             */
125            public InputStreamReader getInputStreamReader(String fileName, String charSet) throws MaltChainedException {
126                    try {
127                            return new InputStreamReader(new FileInputStream(configDirectory.getPath()+File.separator+fileName), charSet);
128                    } catch (FileNotFoundException e) {
129                            throw new ConfigurationException("The file '"+fileName+"' cannot be found. ", e);
130                    } catch (UnsupportedEncodingException e) {
131                            throw new ConfigurationException("The char set '"+charSet+"' is not supported. ", e);
132                    }
133            }
134            
135            /**
136             * Creates an input stream reader for reading a file within the configuration directory.
137             * Uses UTF-8 for character encoding.
138             * 
139             * @param fileName      a file name
140             * @return      an input stream reader for reading a file within the configuration directory
141             * @throws MaltChainedException
142             */
143            public InputStreamReader getInputStreamReader(String fileName) throws MaltChainedException {
144                    try {
145                            return new InputStreamReader(new FileInputStream(configDirectory.getPath()+File.separator+fileName), "UTF-8");
146                    } catch (FileNotFoundException e) {
147                            throw new ConfigurationException("The file '"+fileName+"' cannot be found. ", e);
148                    } catch (UnsupportedEncodingException e) {
149                            throw new ConfigurationException("The char set 'UTF-8' is not supported. ", e);
150                    }
151            }
152            
153            /**
154             * Returns a file handler object of a file within the configuration directory
155             * 
156             * @param fileName      a file name
157             * @return      a file handler object of a file within the configuration directory
158             * @throws MaltChainedException
159             */
160            public File getFile(String fileName) throws MaltChainedException {
161                    return new File(configDirectory.getPath()+File.separator+fileName);
162            }
163            
164        /**
165         * Copies a file into the configuration directory.
166         * 
167         * @param source    a path to file 
168         * @throws MaltChainedException
169         */
170        public void copyToConfig(File source) throws MaltChainedException {
171            byte[] readBuffer = new byte[BUFFER];
172            String destination = configDirectory.getPath()+File.separator+source.getName();
173            try {
174                    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(source));
175                    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destination), BUFFER);
176                
177                    int n = 0;
178                        while ((n = bis.read(readBuffer, 0, BUFFER)) != -1) {
179                            bos.write(readBuffer, 0, n);
180                        }
181                    bos.flush();
182                    bos.close();
183                    bis.close();
184                    } catch (FileNotFoundException e) {
185                            throw new ConfigurationException("The source file '"+source+"' cannot be found or the destination file '"+destination+"' cannot be created when coping the file. ", e);
186                    } catch (IOException e) {
187                            throw new ConfigurationException("The source file '"+source+"' cannot be copied to destination '"+destination+"'. ", e);
188                    }
189        }
190        
191        /**
192         * Copies a file into the configuration directory.
193         * 
194         * @param fileUrl   an URL to the file
195         * @throws MaltChainedException
196         */
197        public void copyToConfig(String fileUrl) throws MaltChainedException {
198            URL url = Util.findURL(fileUrl);
199            if (url == null) {
200                    throw new ConfigurationException("The file or URL '"+fileUrl+"' could not be found. ");
201            }
202            byte[] readBuffer = new byte[BUFFER];
203            String destFileName = url.getFile();
204            int indexSlash = destFileName.lastIndexOf('/');
205            int indexQuery = destFileName.lastIndexOf('?');
206            
207            if (indexSlash != -1 || indexQuery != -1) {
208                    if (indexSlash == -1) {
209                            indexSlash = 0;
210                    }
211                    if (indexQuery == -1) {
212                            indexQuery = destFileName.length();
213                    }
214                    destFileName = destFileName.substring(indexSlash, indexQuery);
215            }
216            
217            String destination = configDirectory.getPath()+File.separator+destFileName;
218            try {
219                    BufferedInputStream bis = new BufferedInputStream(url.openStream());
220                    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destination), BUFFER);
221                
222                    int n = 0;
223                        while ((n = bis.read(readBuffer, 0, BUFFER)) != -1) {
224                            bos.write(readBuffer, 0, n);
225                        }
226                    bos.flush();
227                    bos.close();
228                    bis.close();
229                    } catch (FileNotFoundException e) {
230                            throw new ConfigurationException("The destination file '"+destination+"' cannot be created when coping the file. ", e);
231                    } catch (IOException e) {
232                            throw new ConfigurationException("The URL '"+url+"' cannot be copied to destination '"+destination+"'. ", e);
233                    }
234        }
235        
236            /**
237             * Removes the configuration directory, if it exists and it contains a .info file. 
238             * 
239             * @throws MaltChainedException
240             */
241            public void deleteConfigDirectory() throws MaltChainedException {
242                    if (!configDirectory.exists()) {
243                            return;
244                    }
245                    File infoFile = new File(configDirectory.getPath()+File.separator+getName()+"_"+getType()+".info");
246                    if (infoFile.exists()) {
247                            deleteConfigDirectory(configDirectory);
248                    } else {
249                            throw new ConfigurationException("There exists a directory that is not a MaltParser configuration directory. ");
250                    }
251            }
252            
253            private void deleteConfigDirectory(File directory) throws MaltChainedException {
254                    if (directory.exists()) {
255                            File[] files = directory.listFiles();
256                            for (int i = 0; i < files.length; i++) {
257                                    if (files[i].isDirectory()) {
258                                            deleteConfigDirectory(files[i]);
259                                    } else {
260                                            files[i].delete();
261                                    }
262                            }
263                    } else {
264                            throw new ConfigurationException("The directory '"+directory.getPath()+ "' cannot be found. ");
265                    }
266                    directory.delete();
267            }
268            
269            /**
270             * Returns a file handler object for the configuration directory
271             * 
272             * @return a file handler object for the configuration directory
273             */
274            public File getConfigDirectory() {
275                    return configDirectory;
276            }
277    
278            protected void setConfigDirectory(File dir) {
279                    this.configDirectory = dir;
280            }
281    
282            /**
283             * Creates the configuration directory
284             * 
285             * @throws MaltChainedException
286             */
287            public void createConfigDirectory() throws MaltChainedException {
288                    checkConfigDirectory();
289                    configDirectory.mkdir();
290                    createInfoFile();
291            }
292            
293            protected void checkConfigDirectory()  throws MaltChainedException {
294                    if (configDirectory.exists() && !configDirectory.isDirectory()) {
295                            throw new ConfigurationException("The configuration directory name already exists and is not a directory. ");
296                    }
297                    
298                    if (configDirectory.exists()) {
299                            deleteConfigDirectory();
300                    } 
301            }
302            
303            protected void createInfoFile() throws MaltChainedException {
304                    infoFile = new BufferedWriter(getOutputStreamWriter(getName()+"_"+getType()+".info"));
305                    try {
306                            infoFile.write("CONFIGURATION\n");
307                            infoFile.write("Configuration name:   "+getName()+"\n");
308                            infoFile.write("Configuration type:   "+getType()+"\n");
309                            infoFile.write("Created:              "+new Date(System.currentTimeMillis())+"\n");
310                            
311                            infoFile.write("\nSYSTEM\n");
312                            infoFile.write("Operating system architecture: "+System.getProperty("os.arch")+"\n");
313                            infoFile.write("Operating system name:         "+System.getProperty("os.name")+"\n");
314                            infoFile.write("JRE vendor name:               "+System.getProperty("java.vendor")+"\n");
315                            infoFile.write("JRE version number:            "+System.getProperty("java.version")+"\n");
316                            
317                            infoFile.write("\nMALTPARSER\n");
318                            infoFile.write("Version:                       "+SystemInfo.getVersion()+"\n");
319                            infoFile.write("Build date:                    "+SystemInfo.getBuildDate()+"\n");
320                            HashSet<String> excludeGroups = new HashSet<String>();
321                            excludeGroups.add("system");
322                            infoFile.write("\nSETTINGS\n");
323                            infoFile.write(OptionManager.instance().toStringPrettyValues(containerIndex, excludeGroups));
324                            infoFile.flush();
325                    } catch (IOException e) {
326                            throw new ConfigurationException("Could not create the maltparser info file. ");
327                    }
328            }
329            
330            /**
331             * Returns a writer to the configuration information file
332             * 
333             * @return      a writer to the configuration information file
334             * @throws MaltChainedException
335             */
336            public BufferedWriter getInfoFileWriter() throws MaltChainedException {
337                    return infoFile;
338            }
339            
340            /**
341             * Creates the malt configuration file (.mco). This file is compressed.   
342             * 
343             * @throws MaltChainedException
344             */
345            public void createConfigFile() throws MaltChainedException {
346                    try {
347                            JarOutputStream jos = new JarOutputStream(new FileOutputStream(workingDirectory.getPath()+File.separator+getName()+".mco"));
348    //                      configLogger.info("Creates configuration file '"+workingDirectory.getPath()+File.separator+getName()+".mco' ...\n");
349                            createConfigFile(configDirectory.getPath(), jos);
350                            jos.close();
351                    } catch (FileNotFoundException e) {
352                            throw new ConfigurationException("The maltparser configurtation file '"+workingDirectory.getPath()+File.separator+getName()+".mco"+"' cannot be found. ", e);
353                    } catch (IOException e) {
354                            throw new ConfigurationException("The maltparser configurtation file '"+workingDirectory.getPath()+File.separator+getName()+".mco"+"' cannot be created. ", e);
355                    } 
356            }
357            
358            private void createConfigFile(String directory, JarOutputStream jos) throws MaltChainedException {
359            byte[] readBuffer = new byte[BUFFER];
360                    try {
361                            File zipDir = new File(directory);
362                            String[] dirList = zipDir.list();
363                            
364                            int bytesIn = 0;
365            
366                            for (int i = 0; i < dirList.length; i++) {
367                                    File f = new File(zipDir, dirList[i]);
368                                    if (f.isDirectory()) {
369                                            String filePath = f.getPath();
370                                            createConfigFile(filePath, jos);
371                                            continue;
372                                    }
373            
374                                    FileInputStream fis = new FileInputStream(f);
375                                    
376                                    
377                                    JarEntry entry = new JarEntry(f.getPath().substring(workingDirectory.getPath().length()+1));
378                                    jos.putNextEntry(entry);
379            
380                                    while ((bytesIn = fis.read(readBuffer)) != -1) {
381                                            jos.write(readBuffer, 0, bytesIn);
382                                    }
383            
384                                    fis.close();
385                            }
386                    } catch (FileNotFoundException e) {
387                            throw new ConfigurationException("The directory '"+directory+"' cannot be found. ", e);
388                    } catch (IOException e) {
389                            throw new ConfigurationException("The directory '"+directory+"' cannot be compressed into a mco file. ", e);
390                    } 
391            }
392        
393        protected void initNameNTypeFromInfoFile(URL url) throws MaltChainedException {
394                    if (url == null) {
395                            throw new ConfigurationException("The URL cannot be found. ");
396                    }       
397                    try {
398                            JarEntry je;
399                            JarInputStream jis = new JarInputStream(url.openConnection().getInputStream());
400                            while ((je = jis.getNextJarEntry()) != null) {
401                                    String entryName = je.getName();
402                                    if (entryName.endsWith(".info")) {
403                                            int indexUnderScore = entryName.lastIndexOf('_');
404                                            int indexSeparator = entryName.lastIndexOf(File.separator);
405                                            if (indexSeparator == -1) {
406                                                    indexSeparator = entryName.lastIndexOf('/');
407                                            }
408                                            if (indexSeparator == -1) {
409                                                    indexSeparator = entryName.lastIndexOf('\\');
410                                            }
411                                            int indexDot = entryName.lastIndexOf('.');
412                                            if (indexUnderScore == -1 || indexDot == -1) {
413                                                    throw new ConfigurationException("Could not find the configuration name and type from the URL '"+url.toString()+"'. ");
414                                            }
415                                            setName(entryName.substring(indexSeparator+1, indexUnderScore));
416                                            setType(entryName.substring(indexUnderScore+1, indexDot));
417                                            setConfigDirectory(new File(workingDirectory.getPath()+File.separator+getName()));
418                                            jis.close();
419                                            return;
420                                    }
421                            }
422                            
423                    } catch (IOException e) {
424                            throw new ConfigurationException("Could not find the configuration name and type from the URL '"+url.toString()+"'. ", e);
425                    }
426        }
427        
428        /**
429         * Prints the content of the configuration information file to the system logger
430         * 
431         * @throws MaltChainedException
432         */
433        public void echoInfoFile() throws MaltChainedException {
434            checkConfigDirectory();
435            JarInputStream jis;
436            try {
437                    if (url == null) {
438                            jis = new JarInputStream(new FileInputStream(workingDirectory.getPath()+File.separator+getName()+".mco"));
439                    } else {
440                            jis = new JarInputStream(url.openConnection().getInputStream());
441                    }
442                            JarEntry je;
443    
444                            while ((je = jis.getNextJarEntry()) != null) {
445                            String entryName = je.getName();
446    
447                            if (entryName.endsWith(getName()+"_"+getType()+".info")) {
448                                    int c;
449                                        while ((c = jis.read()) != -1) {
450                                            SystemLogger.logger().info((char)c);
451                                        }   
452                            }
453                            }
454                    jis.close();
455            } catch (FileNotFoundException e) {
456                    throw new ConfigurationException("Could not print configuration information file. The configuration file '"+workingDirectory.getPath()+File.separator+getName()+".mco"+"' cannot be found. ", e);
457            } catch (IOException e) {
458                            throw new ConfigurationException("Could not print configuration information file. ", e);
459                    }
460    
461        }
462        
463        /**
464         * Unpacks the malt configuration file (.mco).
465         * 
466         * @throws MaltChainedException
467         */
468        public void unpackConfigFile() throws MaltChainedException {
469            checkConfigDirectory();
470            JarInputStream jis;
471            try {
472                    if (url == null) {
473                            jis = new JarInputStream(new FileInputStream(workingDirectory.getPath()+File.separator+getName()+".mco"));
474                    } else {
475                            jis = new JarInputStream(url.openConnection().getInputStream());
476                    }
477                    unpackConfigFile(jis);
478                    jis.close();
479            } catch (FileNotFoundException e) {
480                    throw new ConfigurationException("Could not unpack configuration. The configuration file '"+workingDirectory.getPath()+File.separator+getName()+".mco"+"' cannot be found. ", e);
481            } catch (IOException e) {
482                    if (configDirectory.exists()) {
483                            deleteConfigDirectory();
484                    }
485                            throw new ConfigurationException("Could not unpack configuration. ", e);
486                    }
487            initCreatedByMaltParserVersionFromInfoFile();
488        }
489    
490        protected void unpackConfigFile(JarInputStream jis) throws MaltChainedException {
491                    try {
492                            JarEntry je;
493                            byte[] readBuffer = new byte[BUFFER];
494                    SortedSet<String> directoryCache  = new TreeSet<String>();
495                            while ((je = jis.getNextJarEntry()) != null) {
496                            String entryName = je.getName();
497    
498                            if (entryName.startsWith("/")) {
499                                    entryName = entryName.substring(1);
500                            }
501                            if (entryName.endsWith(File.separator)) {
502                                return;
503                            }
504                            int index = -1;
505                            if (File.separator.equals("\\")) {
506                                    entryName = entryName.replace('/', '\\');
507                                    index = entryName.lastIndexOf("\\");
508                            } else if (File.separator.equals("/")) {
509                                    entryName = entryName.replace('\\', '/');
510                                    index = entryName.lastIndexOf("/");
511                            }
512                            if (index > 0) {
513                                String dirName = entryName.substring(0, index);
514                                if (!directoryCache.contains(dirName)) {
515                                    File directory = new File(workingDirectory.getPath()+File.separator+dirName);
516                                    if (!(directory.exists() && directory.isDirectory())) {
517                                        if (!directory.mkdirs()) {
518                                            throw new ConfigurationException("Unable to make directory '" + dirName +"'. ");
519                                        }
520                                        directoryCache.add(dirName);
521                                    }
522                                }
523                            }
524                           
525                            if (new File(workingDirectory.getPath()+File.separator+entryName).isDirectory() && new File(workingDirectory.getPath()+File.separator+entryName).exists()) {
526                                    continue;
527                            }
528                            BufferedOutputStream bos;
529                            try {
530                                    bos = new BufferedOutputStream(new FileOutputStream(workingDirectory.getPath()+File.separator+entryName), BUFFER);
531                            } catch (FileNotFoundException e) {
532                                            throw new ConfigurationException("Could not unpack configuration. The file '"+workingDirectory.getPath()+File.separator+entryName+"' cannot be unpacked. ", e);
533                            }
534                                    int n = 0;
535                                while ((n = jis.read(readBuffer, 0, BUFFER)) != -1) {
536                                    bos.write(readBuffer, 0, n);
537                                }
538                                bos.flush();
539                                bos.close();
540                            }
541                    } catch (IOException e) {
542                            throw new ConfigurationException("Could not unpack configuration. ", e);
543                    }
544        }
545                
546            /**
547             * Returns the name of the configuration directory
548             * 
549             * @return the name of the configuration directory
550             */
551            public String getName() {
552                    return name;
553            }
554    
555            protected void setName(String name) {
556                    this.name = name;
557            }
558    
559            /**
560             * Returns the type of the configuration directory
561             * 
562             * @return the type of the configuration directory
563             */
564            public String getType() {
565                    return type;
566            }
567    
568            protected void setType(String type) {
569                    this.type = type;
570            }
571            
572            /**
573             * Returns a file handler object for the working directory
574             * 
575             * @return a file handler object for the working directory
576             */
577            public File getWorkingDirectory() {
578                    return workingDirectory;
579            }
580    
581            /**
582             * Initialize the working directory
583             * 
584             * @throws MaltChainedException
585             */
586            public void initWorkingDirectory() throws MaltChainedException {
587                    try {
588                            initWorkingDirectory(OptionManager.instance().getOptionValue(0, "config", "workingdir").toString());
589                    } catch (NullPointerException e) {
590                            throw new ConfigurationException("The configuration cannot be found.", e);
591                    }
592            }
593    
594            /**
595             * Initialize the working directory according to the path. If the path is equals to "user.dir" or current directory, then the current directory
596             *  will be the working directory.
597             * 
598             * @param pathPrefixString      the path to the working directory
599             * @throws MaltChainedException
600             */
601            public void initWorkingDirectory(String pathPrefixString) throws MaltChainedException {
602                    if (pathPrefixString == null || pathPrefixString.equalsIgnoreCase("user.dir") || pathPrefixString.equalsIgnoreCase(".")) {
603                            workingDirectory = new File(System.getProperty("user.dir"));
604                    } else {
605                            workingDirectory = new File(pathPrefixString);
606                    }
607    
608                    if (workingDirectory == null || !workingDirectory.isDirectory()) {
609                            new ConfigurationException("The specified working directory '"+pathPrefixString+"' is not a directory. ");
610                    }
611            }
612            
613            /**
614             * Returns the URL to the malt configuration file (.mco) 
615             * 
616             * @return the URL to the malt configuration file (.mco)
617             */
618            public URL getUrl() {
619                    return url;
620            }
621    
622            protected void setUrl(URL url) {
623                    this.url = url;
624            }
625    
626            /**
627             * Returns a reference to the configuration 
628             * 
629             * @return a reference to the configuration 
630             */
631    //      public Configuration getConfiguration() {
632    //              return configuration;
633    //      }
634    
635            /**
636             * Sets the reference to the configuration
637             * 
638             * @param configuration a reference to a configuration
639             */
640    //      public void setConfiguration(Configuration configuration) {
641    //              this.configuration = configuration;
642    //      }
643            
644            /**
645             * Returns the option container index
646             * 
647             * @return the option container index
648             */
649            public int getContainerIndex() {
650                    return containerIndex;
651            }
652    
653            /**
654             * Sets the option container index
655             * 
656             * @param containerIndex a option container index
657             */
658            public void setContainerIndex(int containerIndex) {
659                    this.containerIndex = containerIndex;
660            }
661    
662            /**
663             * Returns the version number of MaltParser which created the malt configuration file (.mco)
664             * 
665             * @return the version number of MaltParser which created the malt configuration file (.mco)
666             */
667            public String getCreatedByMaltParserVersion() {
668                    return createdByMaltParserVersion;
669            }
670    
671            /**
672             * Sets the version number of MaltParser which created the malt configuration file (.mco)
673             * 
674             * @param createdByMaltParserVersion a version number of MaltParser
675             */
676            public void setCreatedByMaltParserVersion(String createdByMaltParserVersion) {
677                    this.createdByMaltParserVersion = createdByMaltParserVersion;
678            }
679    
680            protected void initCreatedByMaltParserVersionFromInfoFile() throws MaltChainedException {
681                    File info = new File(configDirectory.getPath()+File.separator+getName()+"_"+getType()+".info");
682                    if (!info.exists()) {
683                            throw new ConfigurationException("Could not retrieve the version number of the MaltParser configuration.");
684                    }
685                    try {
686                            BufferedReader br = new BufferedReader(new FileReader(info));
687                            String line = null;
688                            while ((line = br.readLine()) != null) {
689                                    if (line.startsWith("Version:                       ")) {
690                                            setCreatedByMaltParserVersion(line.substring(31));
691                                            break;
692                                    }
693                            }
694                            br.close();
695                    } catch (FileNotFoundException e) {
696                            throw new ConfigurationException("Could not retrieve the version number of the MaltParser configuration.", e);
697                    } catch (IOException e) {
698                            throw new ConfigurationException("Could not retrieve the version number of the MaltParser configuration.", e);
699                    }
700                    checkNConvertConfigVersion();
701            }
702            
703            protected void checkNConvertConfigVersion() throws MaltChainedException {
704                    if (createdByMaltParserVersion.startsWith("1.0")) {
705                            SystemLogger.logger().info("  Converts the MaltParser configuration ");
706                            SystemLogger.logger().info("1.0");
707                            SystemLogger.logger().info(" to ");
708                            SystemLogger.logger().info(SystemInfo.getVersion());
709                            SystemLogger.logger().info("\n");
710                            File[] configFiles = configDirectory.listFiles();
711                            for (int i = 0, n = configFiles.length; i < n; i++) {
712                                    if (configFiles[i].getName().endsWith(".mod")) {
713                                            configFiles[i].renameTo(new File(configDirectory.getPath()+File.separator+"odm0."+configFiles[i].getName()));
714                                    }
715                                    if (configFiles[i].getName().endsWith(getName()+".dsm")) {
716                                            configFiles[i].renameTo(new File(configDirectory.getPath()+File.separator+"odm0.dsm"));
717                                    }
718                                    if (configFiles[i].getName().equals("savedoptions.sop")) {
719                                            configFiles[i].renameTo(new File(configDirectory.getPath()+File.separator+"savedoptions.sop.old"));
720                                    }
721                                    if (configFiles[i].getName().equals("symboltables.sym")) {
722                                            configFiles[i].renameTo(new File(configDirectory.getPath()+File.separator+"symboltables.sym.old"));
723                                    }
724                            }
725                            try {
726                                    BufferedReader br = new BufferedReader(new FileReader(configDirectory.getPath()+File.separator+"savedoptions.sop.old"));
727                                    BufferedWriter bw = new BufferedWriter(new FileWriter(configDirectory.getPath()+File.separator+"savedoptions.sop"));
728                                    String line;
729                                    while ((line = br.readLine()) != null) {
730                                            if (line.startsWith("0\tguide\tprediction_strategy")) {
731                                                    bw.write("0\tguide\tdecision_settings\tT.TRANS+A.DEPREL\n");
732                                            } else {
733                                                    bw.write(line);
734                                                    bw.write('\n');
735                                            }
736                                    }
737                                    br.close();
738                                    bw.flush();
739                                    bw.close();
740                                    new File(configDirectory.getPath()+File.separator+"savedoptions.sop.old").delete();
741                            } catch (FileNotFoundException e) {
742                                    throw new ConfigurationException("Could convert savedoptions.sop version 1.0.4 to version 1.1. ", e);
743                            }  catch (IOException e) {
744                                    throw new ConfigurationException("Could convert savedoptions.sop version 1.0.4 to version 1.1. ", e);
745                            }               
746                            try {
747                                    BufferedReader br = new BufferedReader(new FileReader(configDirectory.getPath()+File.separator+"symboltables.sym.old"));
748                                    BufferedWriter bw = new BufferedWriter(new FileWriter(configDirectory.getPath()+File.separator+"symboltables.sym"));
749                                    String line;
750                                    while ((line = br.readLine()) != null) {
751                                            if (line.startsWith("AllCombinedClassTable")) {
752                                                    bw.write("T.TRANS+A.DEPREL\n");
753                                            } else {
754                                                    bw.write(line);
755                                                    bw.write('\n');
756                                            }
757                                    }
758                                    br.close();
759                                    bw.flush();
760                                    bw.close();
761                                    new File(configDirectory.getPath()+File.separator+"symboltables.sym.old").delete();
762                            } catch (FileNotFoundException e) {
763                                    throw new ConfigurationException("Could convert symboltables.sym version 1.0.4 to version 1.1. ", e);
764                            }  catch (IOException e) {
765                                    throw new ConfigurationException("Could convert symboltables.sym version 1.0.4 to version 1.1. ", e);
766                            }
767                    }
768                    if (!createdByMaltParserVersion.startsWith("1.3")) {
769                            SystemLogger.logger().info("  Converts the MaltParser configuration ");
770                            SystemLogger.logger().info(createdByMaltParserVersion);
771                            SystemLogger.logger().info(" to ");
772                            SystemLogger.logger().info(SystemInfo.getVersion());
773                            SystemLogger.logger().info("\n");
774                            
775    
776                            new File(configDirectory.getPath()+File.separator+"savedoptions.sop").renameTo(new File(configDirectory.getPath()+File.separator+"savedoptions.sop.old"));
777                            try {
778                                    BufferedReader br = new BufferedReader(new FileReader(configDirectory.getPath()+File.separator+"savedoptions.sop.old"));
779                                    BufferedWriter bw = new BufferedWriter(new FileWriter(configDirectory.getPath()+File.separator+"savedoptions.sop"));
780                                    String line;
781                                    while ((line = br.readLine()) != null) {
782                                            int index = line.indexOf('\t');
783                                            int container = 0;
784                                            if (index > -1) {
785                                                    container = Integer.parseInt(line.substring(0,index));
786                                            }
787                                            
788                                            if (line.startsWith(container+"\tnivre\tpost_processing")) {
789                                            } else if (line.startsWith(container+"\tmalt0.4\tbehavior")) {
790                                                    if (line.endsWith("true")) {
791                                                            SystemLogger.logger().info("MaltParser 1.3 doesn't support MaltParser 0.4 emulation.");
792                                                            br.close();
793                                                            bw.flush();
794                                                            bw.close();
795                                                            deleteConfigDirectory();
796                                                            System.exit(0);
797                                                    }
798                                            } else if (line.startsWith(container+"\tsinglemalt\tparsing_algorithm")) {
799                                                    bw.write(container);
800                                                    bw.write("\tsinglemalt\tparsing_algorithm\t");
801                                                    if (line.endsWith("NivreStandard")) {
802                                                            bw.write("class org.maltparser.parser.algorithm.nivre.NivreArcStandardFactory");        
803                                                    } else if (line.endsWith("NivreEager")) {
804                                                            bw.write("class org.maltparser.parser.algorithm.nivre.NivreArcEagerFactory");
805                                                    } else if (line.endsWith("CovingtonNonProjective")) {
806                                                            bw.write("class org.maltparser.parser.algorithm.covington.CovingtonNonProjFactory");
807                                                    } else if (line.endsWith("CovingtonProjective")) {
808                                                            bw.write("class org.maltparser.parser.algorithm.covington.CovingtonProjFactory");
809                                                    }
810                                                    bw.write('\n');
811                                            } else {
812                                                    bw.write(line);
813                                                    bw.write('\n');
814                                            }
815                                    }
816                                    br.close();
817                                    bw.flush();
818                                    bw.close();
819                                    new File(configDirectory.getPath()+File.separator+"savedoptions.sop.old").delete();
820                            } catch (FileNotFoundException e) {
821                                    throw new ConfigurationException("Could convert savedoptions.sop version 1.0.4 to version 1.1. ", e);
822                            }  catch (IOException e) {
823                                    throw new ConfigurationException("Could convert savedoptions.sop version 1.0.4 to version 1.1. ", e);
824                            }
825                    }
826            }
827            
828            /**
829             * Terminates the configuration directory
830             * 
831             * @throws MaltChainedException
832             */
833            public void terminate() throws MaltChainedException {
834                    if (infoFile != null) {
835                            try {
836                                    infoFile.flush();
837                                    infoFile.close();
838                            } catch (IOException e) {
839                                    throw new ConfigurationException("Could not close configuration information file. ", e);
840                            }
841                    }
842    //              configuration = null;
843            }
844            
845            /* (non-Javadoc)
846             * @see java.lang.Object#finalize()
847             */
848            protected void finalize() throws Throwable {
849                    try {
850                            if (infoFile != null) {
851                                    infoFile.flush();
852                                    infoFile.close();
853                            }
854                    } finally {
855                            super.finalize();
856                    }
857            }
858    }