org.zanata.adapter.xliff.XliffWriter Maven / Gradle / Ivy
package org.zanata.adapter.xliff;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import com.sun.xml.txw2.output.IndentingXMLStreamWriter;
import org.zanata.rest.dto.extensions.comment.SimpleComment;
import org.zanata.rest.dto.extensions.gettext.TextFlowExtension;
import org.zanata.rest.dto.resource.Resource;
import org.zanata.rest.dto.resource.TextFlow;
import org.zanata.rest.dto.resource.TextFlowTarget;
import org.zanata.rest.dto.resource.TranslationsResource;
import org.zanata.util.PathUtil;
public class XliffWriter extends XliffCommon {
/**
* Write document header with XML, xliff, file and body tag
*
* @param writer
* @param doc
* @param targetLocale
* (use hyphen, not underscore)
* @throws XMLStreamException
*/
private static void writeHeader(XMLStreamWriter writer,
Resource doc, String targetLocale) throws XMLStreamException {
// XML tag
writer.writeStartDocument("utf-8", "1.0");
writer.writeComment("XLIFF document generated by Zanata. Visit http://zanata.org for more infomation.");
writer.writeCharacters("\n");
// XLiff tag
writer.writeStartElement("xliff");
writer.writeNamespace("", "urn:oasis:names:tc:xliff:document:1.1");
writer.writeNamespace("xyz", "urn:appInfo:Items");
writer.writeNamespace("xsi",
"http://www.w3.org/2001/XMLSchema-instance");
writer.writeAttribute(
"xsi:schemaLocation",
"urn:oasis:names:tc:xliff:document:1.1 http://www.oasis-open.org/committees/xliff/documents/xliff-core-1.1.xsd");
writer.writeAttribute("version", "1.1");
// file tag
writer.writeStartElement(ELE_FILE);
writer.writeAttribute(ATTRI_SOURCE_LANGUAGE, doc.getLang().getId());
writer.writeAttribute(ATTRI_DATATYPE, "plaintext");
writer.writeAttribute(ATTRI_ORIGINAL, "");
if (targetLocale != null) {
writer.writeAttribute(ATTRI_TARGET_LANGUAGE, targetLocale);
}
// body tag
writer.writeStartElement(ELE_BODY);
}
private static void writeTransUnits(XMLStreamWriter writer,
Resource doc, TranslationsResource targetDoc,
boolean createSkeletons) throws XMLStreamException {
Map targets = Collections.emptyMap();
if (targetDoc != null) {
targets = new HashMap<>();
for (TextFlowTarget target : targetDoc.getTextFlowTargets()) {
targets.put(target.getResId(), target);
}
}
for (TextFlow textFlow : doc.getTextFlows()) {
TextFlowTarget target = targets.get(textFlow.getId());
if (target == null && !createSkeletons) {
continue;
}
writer.writeStartElement(ELE_TRANS_UNIT);
writer.writeAttribute(ATTRI_ID, textFlow.getId());
writeTransUnitSource(writer, textFlow);
if (target != null && target.getState().isTranslated()) {
writeTransUnitTarget(writer, target);
}
writeTransUnitContext(writer, textFlow);
// end trans-unit tag
writer.writeEndElement();
}
}
private static void writeTransUnitSource(XMLStreamWriter writer,
TextFlow textFlow) throws XMLStreamException {
writer.writeStartElement(ELE_SOURCE);
List contents = textFlow.getContents();
if (contents.size() != 1) {
throw new RuntimeException(
"file format does not support plural forms: resId="
+ textFlow.getId());
}
writer.writeCharacters(contents.get(0));
// end source tag
writer.writeEndElement();
}
private static void writeTransUnitTarget(XMLStreamWriter writer,
TextFlowTarget target) throws XMLStreamException {
writer.writeStartElement(ELE_TARGET);
List contents = target.getContents();
if (contents.size() != 1) {
throw new RuntimeException(
"file format does not support plural forms: resId="
+ target.getResId());
}
writer.writeCharacters(contents.get(0));
// end target tag
writer.writeEndElement();
}
private static void writeTransUnitContext(XMLStreamWriter writer,
TextFlow textFlow) throws XMLStreamException {
if (!textFlow.getExtensions(true).isEmpty()) {
Map> contextGroupMap =
new HashMap<>();
for (TextFlowExtension textFlowExtension : textFlow.getExtensions()) {
SimpleComment comment = (SimpleComment) textFlowExtension;
String[] contextValues = comment.getValue().split(DELIMITER, 3);
if (!contextGroupMap.containsKey(contextValues[0])) {
ArrayList list = new ArrayList();
list.add(new String[] { contextValues[1], contextValues[2] });
contextGroupMap.put(contextValues[0], list);
} else {
ArrayList list =
contextGroupMap.get(contextValues[0]);
list.add(new String[] { contextValues[1], contextValues[2] });
}
}
for (Map.Entry> entry : contextGroupMap
.entrySet()) {
String key = entry.getKey();
ArrayList values = entry.getValue();
writer.writeStartElement(ELE_CONTEXT_GROUP);
writer.writeAttribute(ATTRI_NAME, key);
for (String[] val : values) {
writer.writeStartElement(ELE_CONTEXT);
writer.writeAttribute(ATTRI_CONTEXT_TYPE, val[0]);
writer.writeCharacters(val[1]);
// end context
writer.writeEndElement();
}
// end context-group
writer.writeEndElement();
}
}
}
/**
* Used for writing target file
*
* @param baseDir
* @param doc
* @param locale
* (use hyphen, not underscore)
* @param targetDoc
* may be null
*/
public static void write(File baseDir, Resource doc, String locale,
TranslationsResource targetDoc, boolean createSkeletons) {
File outFile =
new File(baseDir, doc.getName() + "_"
+ locale.replace('-', '_') + ".xml");
writeFile(outFile, doc, locale, targetDoc, createSkeletons);
}
/**
* Used for writing translation file with given translations map
*
* @param doc
* @param targetDoc
* @param file
* @param locale (use hyphen, not underscore)
*/
public static void writeFile(File file, Resource doc, String locale,
TranslationsResource targetDoc, boolean createSkeletons) {
try {
PathUtil.makeParents(file);
} catch (IOException e) {
throw new RuntimeException("Error writing XLIFF file ", e);
}
try (FileOutputStream fileStream = new FileOutputStream(file)) {
XMLOutputFactory output = XMLOutputFactory.newInstance();
XMLStreamWriter writer =
new IndentingXMLStreamWriter(
output.createXMLStreamWriter(fileStream, "utf-8"));
try {
writeHeader(writer, doc, locale);
writeTransUnits(writer, doc, targetDoc, createSkeletons);
// end body tag
writer.writeEndElement();
// end file tag
writer.writeEndElement();
// end xliff tag
writer.writeEndDocument();
writer.flush();
} finally {
writer.close();
}
} catch (XMLStreamException | IOException e) {
throw new RuntimeException("Error writing XLIFF file", e);
}
}
/**
* Used for writing source file
*
* @param baseDir
* @param doc
* @param locale
* (use hyphen, not underscore)
*/
public static void write(File baseDir, Resource doc, String locale) {
write(baseDir, doc, locale, null, true);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy