/**************************************************************************
OmegaT - Computer Assisted Translation (CAT) tool
with fuzzy matching, translation memory, keyword search,
glossaries, and translation leveraging into updated projects.
Copyright (C) 2016 Alex Buloichik
Home page: http://www.omegat.org/
Support center: http://groups.yahoo.com/group/OmegaT/
This file is part of OmegaT.
OmegaT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OmegaT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/
package org.omegat.gui.main;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.omegat.core.data.ProjectProperties;
import org.omegat.util.FileUtil;
import org.omegat.util.OConsts;
/**
* Class for support some MED-specific operations.
*
* @author Alex Buloichik (alex73mail@gmail.com)
*/
public class ProjectMedProcessing {
/**
* It creates project internals from MED zip file.
*/
public static void extractFromMed(File medZip, ProjectProperties props) throws Exception {
String medName = medZip.getName().replaceAll("\\.zip$", "");
// extract source and target languages
Properties p = new Properties();
try (ZipFile zip = new ZipFile(medZip)) {
ZipEntry e = zip.getEntry(medName + "/dossier/workflow/translation");
if (e == null) {
throw new Exception("Wrong MED zip structure");
}
try (InputStream in = zip.getInputStream(e)) {
p.load(in);
}
}
// get source language
String slang = p.getProperty("slang");
if (slang == null) {
throw new Exception("Bad MED format: slang not defined");
}
// get target language
String tlang = p.getProperty("tlang");
if (tlang == null) {
throw new Exception("Bad MED format: tlang not defined");
}
props.setSourceLanguage(slang);
props.setTargetLanguage(tlang);
// copy source files
try (ZipFile zip = new ZipFile(medZip)) {
extractFiles(zip, medName + "/doc/main/" + props.getSourceLanguage().getLanguage() + "/", null,
props.getSourceDir().getAsFile());
extractFiles(zip, medName + "/doc/support/" + props.getSourceLanguage().getLanguage() + "/",
".tmx", new File(props.getTMAutoRoot()));
extractFiles(zip, medName + "/doc/support/" + props.getSourceLanguage().getLanguage() + "/term/",
null, props.getGlossaryDir().getAsFile());
}
// copy original zip
File outZip = new File(props.getProjectInternalDir(), "med/" + medZip.getName());
outZip.getParentFile().mkdirs();
FileUtils.copyFile(medZip, outZip);
}
private static void extractFiles(ZipFile zip, String zipPrefix, String zipSuffix, File projectDir)
throws Exception {
for (Enumeration<? extends ZipEntry> en = zip.entries(); en.hasMoreElements();) {
ZipEntry e = en.nextElement();
if (e.isDirectory()) {
continue;
}
if (!e.getName().startsWith(zipPrefix)) {
continue;
}
if (zipSuffix != null && !e.getName().endsWith(zipSuffix)) {
continue;
}
File outFile = new File(projectDir, e.getName().substring(zipPrefix.length()));
outFile.getParentFile().mkdirs();
try (InputStream in = zip.getInputStream(e)) {
FileUtils.copyInputStreamToFile(in, outFile);
}
}
}
/**
* Finds one .zip file inside omegat/med/ dir.
*/
public static File getOriginMedFile(ProjectProperties props) throws Exception {
File[] files = new File(props.getProjectInternalDir(), "med/").listFiles(new FileFilter() {
@Override
public boolean accept(File f) {
return f.isFile() && f.getName().endsWith(".zip");
}
});
if (files != null && files.length > 1) {
throw new Exception("Too many source med files in the <project>/omegat/med directory");
}
File originMedFile = files != null && files.length > 0 ? files[0] : null;
return originMedFile;
}
public static void createMed(File medZip, ProjectProperties props) throws Exception {
if (medZip.getAbsolutePath().startsWith(props.getProjectRoot())) {
throw new Exception("Med can't be inside project");
}
File sourceMedFile = getOriginMedFile(props);
Properties translationContent = new Properties();
String slang = props.getSourceLanguage().getLanguage();
String tlang = props.getTargetLanguage().getLanguage();
String medName = medZip.getName().replaceAll("\\.zip$", "");
try (ZipOutputStream outZip = new ZipOutputStream(new FileOutputStream(medZip))) {
if (sourceMedFile != null) {
String oldMedName = sourceMedFile.getName().replaceAll("\\.zip$", "");
String[] skipPrefixes = new String[] { oldMedName + "/doc/main/" + slang + "/",
oldMedName + "/doc/main/" + tlang + "/" };
String[] skipFiles = new String[] { oldMedName + "/dossier/workflow/translation",
oldMedName + "/doc/support/" + slang + "/tm/" + props.getProjectName()
+ OConsts.LEVEL2_TMX + OConsts.TMX_EXTENSION,
oldMedName + "/doc/support/" + slang + "/term/glossary.txt" };
try (ZipFile zip = new ZipFile(sourceMedFile)) {
// extract old file
ZipEntry tre = zip.getEntry(oldMedName + "/dossier/workflow/translation");
if (tre == null) {
throw new Exception("Wrong MED zip structure");
}
try (InputStream in = zip.getInputStream(tre)) {
translationContent.load(in);
}
for (Enumeration<? extends ZipEntry> en = zip.entries(); en.hasMoreElements();) {
ZipEntry e = en.nextElement();
if (e.isDirectory()) {
continue;
}
boolean add = true;
for (String skip : skipFiles) {
if (e.getName().equals(skip)) {
add = false;
break;
}
}
if (add) {
for (String skip : skipPrefixes) {
if (e.getName().startsWith(skip)) {
add = false;
break;
}
}
}
if (!add) {
continue;
}
String newName = medName + e.getName().substring(oldMedName.length());
outZip.putNextEntry(new ZipEntry(newName));
try (InputStream in = zip.getInputStream(e)) {
IOUtils.copy(in, outZip);
}
}
}
}
translationContent.put("slang", slang);
translationContent.put("tlang", tlang);
outZip.putNextEntry(new ZipEntry(medName + "/dossier/workflow/translation"));
translationContent.store(outZip, null);
// source files
packDir(props.getSourceDir().getAsFile(), medName + "/doc/main/" + slang + "/", outZip);
// translations
packDir(props.getTargetDir().getAsFile(), medName + "/doc/main/" + tlang + "/", outZip);
// level2.tmx
outZip.putNextEntry(new ZipEntry(medName + "/doc/support/" + slang + "/tm/"
+ props.getProjectName() + OConsts.LEVEL2_TMX + OConsts.TMX_EXTENSION));
FileUtils.copyFile(new File(props.getProjectRootDir(),
props.getProjectName() + OConsts.LEVEL2_TMX + OConsts.TMX_EXTENSION), outZip);
// statistics
outZip.putNextEntry(new ZipEntry(medName + "/dossier/post/" + OConsts.STATS_FILENAME));
FileUtils.copyFile(new File(props.getProjectInternalDir(), OConsts.STATS_FILENAME), outZip);
// writable glossary
if (props.getWritableGlossaryFile().getAsFile().exists()) {
outZip.putNextEntry(new ZipEntry(medName + "/doc/support/" + slang + "/term/glossary.txt"));
FileUtils.copyFile(props.getWritableGlossaryFile().getAsFile(), outZip);
}
}
}
private static void packDir(File dir, String namePrefix, ZipOutputStream zip) throws Exception {
List<String> srcPathList = FileUtil.buildRelativeFilesList(dir, null, null);
for (String f : srcPathList) {
if (f.startsWith("/")) {
f = f.substring(1);
}
zip.putNextEntry(new ZipEntry(namePrefix + f));
FileUtils.copyFile(new File(dir, f), zip);
}
}
}