Skip to content

Commit

Permalink
refactor: Use Jackson XML dataformat for JAXB data parser
Browse files Browse the repository at this point in the history
- Update TMXWriterTest to check with system line separator
  It is because XML parser can automatically change /r/n into
  XML entity 
/n when System.lineSeparator() is /n
- Update TMXReader2 to detect both "lang" and "xml:lang"
  some implementation return "lang" from "xml:lang" but
  other can return "xml:lang" as is.
- as a workaround for  FasterXML/jackson-modules-base#127
  Add  @JacksonXmlElementWrapper(useWrapping=false) for mask
  element for the parser of omegat.project file.

Signed-off-by: Hiroshi Miura <miurahr@linux.com>
  • Loading branch information
miurahr committed Apr 15, 2023
1 parent 5e55910 commit e7f6ac0
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 195 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ dependencies {
// JSON parser
implementation "com.fasterxml.jackson.core:jackson-core:2.13.4"
implementation "com.fasterxml.jackson.core:jackson-databind:2.13.4.2"
implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.13.4"
implementation 'com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.14.0'


implementation("com.github.ben-manes.caffeine:caffeine:2.9.3") {
attributes {
Expand Down
22 changes: 9 additions & 13 deletions src/org/omegat/convert/v20to21/Convert20to21.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
import java.io.Serializable;
import java.nio.charset.StandardCharsets;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;

import gen.core.filters.Files;
import gen.core.filters.Filter;
Expand All @@ -60,19 +60,16 @@ private Convert20to21() {
* old config file
* @param toFile
* new config file
* @throws Exception
*/
public static void convertFiltersConfig(final File fromFile, final File toFile) throws Exception {
if (!fromFile.exists()) {
return;
}
String c = read(fromFile);
org.omegat.convert.v20to21.data.Filters filters;
XMLDecoder xmldec = new XMLDecoder(new ByteArrayInputStream(c.getBytes("UTF-8")));
try {
try (XMLDecoder xmldec = new XMLDecoder(
new ByteArrayInputStream(c.getBytes(StandardCharsets.UTF_8)))) {
filters = (org.omegat.convert.v20to21.data.Filters) xmldec.readObject();
} finally {
xmldec.close();
}

Filters res = new Filters();
Expand Down Expand Up @@ -108,10 +105,9 @@ public static void convertFiltersConfig(final File fromFile, final File toFile)
convertTextFilter(res);
convertHTMLFilter2(res);

JAXBContext ctx = JAXBContext.newInstance(Filters.class);
Marshaller m = ctx.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.marshal(res, toFile);
XmlMapper mapper = new XmlMapper();
mapper.registerModule(new JaxbAnnotationModule());
mapper.writeValue(toFile, res);
}

/**
Expand All @@ -133,8 +129,8 @@ private static String read(File f) throws IOException {
}
String res = r.toString();
res = res.replace("org.omegat.filters2.master.Filters", "org.omegat.convert.v20to21.data.Filters");
res = res
.replace("org.omegat.filters2.master.OneFilter", "org.omegat.convert.v20to21.data.OneFilter");
res = res.replace("org.omegat.filters2.master.OneFilter",
"org.omegat.convert.v20to21.data.OneFilter");
res = res.replace("org.omegat.filters2.Instance", "org.omegat.convert.v20to21.data.Instance");
res = res.replace("org.omegat.filters2.html2.HTMLOptions",
"org.omegat.convert.v20to21.data.HTMLOptions");
Expand Down
105 changes: 54 additions & 51 deletions src/org/omegat/core/statistics/StatsResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,17 @@
import java.util.Set;
import java.util.TimeZone;

import javax.xml.bind.JAXB;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SequenceWriter;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
import org.omegat.util.OStrings;
import org.omegat.util.StaticUtils;
import org.omegat.util.gui.TextUtil;
Expand All @@ -55,46 +58,36 @@
*/
@XmlRootElement(name = "omegat-stats")
public class StatsResult {
public static final String[] HT_HEADERS = {
"",
OStrings.getString("CT_STATS_Segments"),
OStrings.getString("CT_STATS_Words"),
OStrings.getString("CT_STATS_Characters_NOSP"),
OStrings.getString("CT_STATS_Characters"),
OStrings.getString("CT_STATS_Files"),
};

private static final String[] HT_ROWS = {
OStrings.getString("CT_STATS_Total"),
OStrings.getString("CT_STATS_Remaining"),
OStrings.getString("CT_STATS_Unique"),
OStrings.getString("CT_STATS_Unique_Remaining"),
};
public static final String[] HT_HEADERS = { "", OStrings.getString("CT_STATS_Segments"),
OStrings.getString("CT_STATS_Words"), OStrings.getString("CT_STATS_Characters_NOSP"),
OStrings.getString("CT_STATS_Characters"), OStrings.getString("CT_STATS_Files"), };

private static final String[] HT_ROWS = { OStrings.getString("CT_STATS_Total"),
OStrings.getString("CT_STATS_Remaining"), OStrings.getString("CT_STATS_Unique"),
OStrings.getString("CT_STATS_Unique_Remaining"), };

private static final boolean[] HT_ALIGN = new boolean[] { false, true, true, true, true, true };

public static final String[] FT_HEADERS = {
OStrings.getString("CT_STATS_FILE_Name"),
OStrings.getString("CT_STATS_FILE_Total_Segments"),
OStrings.getString("CT_STATS_FILE_Remaining_Segments"),
OStrings.getString("CT_STATS_FILE_Unique_Segments"),
OStrings.getString("CT_STATS_FILE_Unique_Remaining_Segments"),
OStrings.getString("CT_STATS_FILE_Total_Words"),
OStrings.getString("CT_STATS_FILE_Remaining_Words"),
OStrings.getString("CT_STATS_FILE_Unique_Words"),
OStrings.getString("CT_STATS_FILE_Unique_Remaining_Words"),
OStrings.getString("CT_STATS_FILE_Total_Characters_NOSP"),
OStrings.getString("CT_STATS_FILE_Remaining_Characters_NOSP"),
OStrings.getString("CT_STATS_FILE_Unique_Characters_NOSP"),
OStrings.getString("CT_STATS_FILE_Unique_Remaining_Characters_NOSP"),
OStrings.getString("CT_STATS_FILE_Total_Characters"),
OStrings.getString("CT_STATS_FILE_Remaining_Characters"),
OStrings.getString("CT_STATS_FILE_Unique_Characters"),
OStrings.getString("CT_STATS_FILE_Unique_Remaining_Characters"),
};

private static final boolean[] FT_ALIGN = { false, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, };
public static final String[] FT_HEADERS = { OStrings.getString("CT_STATS_FILE_Name"),
OStrings.getString("CT_STATS_FILE_Total_Segments"),
OStrings.getString("CT_STATS_FILE_Remaining_Segments"),
OStrings.getString("CT_STATS_FILE_Unique_Segments"),
OStrings.getString("CT_STATS_FILE_Unique_Remaining_Segments"),
OStrings.getString("CT_STATS_FILE_Total_Words"),
OStrings.getString("CT_STATS_FILE_Remaining_Words"),
OStrings.getString("CT_STATS_FILE_Unique_Words"),
OStrings.getString("CT_STATS_FILE_Unique_Remaining_Words"),
OStrings.getString("CT_STATS_FILE_Total_Characters_NOSP"),
OStrings.getString("CT_STATS_FILE_Remaining_Characters_NOSP"),
OStrings.getString("CT_STATS_FILE_Unique_Characters_NOSP"),
OStrings.getString("CT_STATS_FILE_Unique_Remaining_Characters_NOSP"),
OStrings.getString("CT_STATS_FILE_Total_Characters"),
OStrings.getString("CT_STATS_FILE_Remaining_Characters"),
OStrings.getString("CT_STATS_FILE_Unique_Characters"),
OStrings.getString("CT_STATS_FILE_Unique_Remaining_Characters"), };

private static final boolean[] FT_ALIGN = { false, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, };

@JsonProperty("project")
private StatProjectProperties props;
Expand Down Expand Up @@ -122,6 +115,7 @@ public StatsResult() {

/**
* Constructor.
*
* @param total
* @param remaining
* @param unique
Expand All @@ -143,7 +137,9 @@ public StatsResult(StatCount total, StatCount remaining, StatCount unique, StatC

/**
* Update given hosStat with current stats data.
* @param hotStat StatisticsInfo data object.
*
* @param hotStat
* StatisticsInfo data object.
*/
public void updateStatisticsInfo(StatisticsInfo hotStat) {
hotStat.numberOfSegmentsTotal = total.segments;
Expand All @@ -167,6 +163,7 @@ public StatProjectProperties getProps() {

/**
* Return total number of segments.
*
* @return
*/
@XmlElement(name = "total")
Expand All @@ -176,6 +173,7 @@ public StatCount getTotal() {

/**
* Return remaining number of segments that needs translation.
*
* @return
*/
@XmlElement(name = "remaining")
Expand All @@ -185,6 +183,7 @@ public StatCount getRemaining() {

/**
* Return a number of unique segments.
*
* @return
*/
@XmlElement(name = "unique")
Expand All @@ -194,6 +193,7 @@ public StatCount getUnique() {

/**
* Return a number of remaining unique segments.
*
* @return
*/
@XmlElement(name = "unique-remaining")
Expand All @@ -203,6 +203,7 @@ public StatCount getRemainingUnique() {

/**
* return a statistics of each source/target files.
*
* @return
*/
@XmlElement(name = "files")
Expand All @@ -212,25 +213,25 @@ public List<FileData> getCounts() {

/**
* Return pretty printed statistics data.
*
* @return pretty-printed string.
*/
@JsonIgnore
public String getTextData() {
return OStrings.getString("CT_STATS_Project_Statistics") +
"\n\n" +
TextUtil.showTextTable(HT_HEADERS, getHeaderTable(), HT_ALIGN) +
"\n\n" +
return OStrings.getString("CT_STATS_Project_Statistics") + "\n\n"
+ TextUtil.showTextTable(HT_HEADERS, getHeaderTable(), HT_ALIGN) + "\n\n" +

// STATISTICS BY FILE
OStrings.getString("CT_STATS_FILE_Statistics") +
"\n\n" +
TextUtil.showTextTable(FT_HEADERS, getFilesTable(), FT_ALIGN);
OStrings.getString("CT_STATS_FILE_Statistics") + "\n\n"
+ TextUtil.showTextTable(FT_HEADERS, getFilesTable(), FT_ALIGN);
}

/**
* Return JSON expression of stats data.
*
* @return JSON string data.
* @throws IOException when export failed.
* @throws IOException
* when export failed.
*/
@JsonIgnore
public String getJsonData() throws IOException {
Expand All @@ -245,14 +246,16 @@ public String getJsonData() throws IOException {

/**
* Return XML expression of Stats data.
*
* @return XML expression of stats data as String.
*/
@JsonIgnore
public String getXmlData() {
public String getXmlData() throws JsonProcessingException {
setDate();
StringWriter result = new StringWriter();
JAXB.marshal(this, result);
return result.toString();
XmlMapper mapper = XmlMapper.xmlBuilder().enable(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME)
.build();
mapper.registerModule(new JaxbAnnotationModule());
return mapper.writeValueAsString(this);
}

private void setDate() {
Expand Down
38 changes: 13 additions & 25 deletions src/org/omegat/filters2/master/FilterMaster.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,8 @@
import java.util.TreeMap;
import java.util.regex.Pattern;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
import org.apache.commons.io.FileUtils;
import org.omegat.filters2.AbstractFilter;
import org.omegat.filters2.FilterContext;
Expand Down Expand Up @@ -88,8 +86,6 @@ public class FilterMaster {
/** name of the filter configuration file */
public static final String FILE_FILTERS = "filters.xml";

private static final JAXBContext CONFIG_CTX;

/**
* There was no version of file filters support (1.4.5 Beta 1 -- 1.6.0
* RC12).
Expand All @@ -109,14 +105,6 @@ public class FilterMaster {
/** Classes of all filters. */
static List<Class<?>> filtersClasses = Collections.emptyList();

static {
try {
CONFIG_CTX = JAXBContext.newInstance(Filters.class);
} catch (Exception ex) {
throw new ExceptionInInitializerError(ex);
}
}

public static void setFilterClasses(List<Class<?>> classes) {
filtersClasses = new ArrayList<>(classes);
}
Expand Down Expand Up @@ -446,8 +434,8 @@ public static Filters loadConfig(File configFile) throws IOException {
}
Filters result;
try {
Unmarshaller unm = CONFIG_CTX.createUnmarshaller();
result = (Filters) unm.unmarshal(configFile);
XmlMapper mapper = new XmlMapper();
result = mapper.readValue(configFile, Filters.class);
} catch (Exception e) {
Log.logErrorRB("FILTERMASTER_ERROR_LOADING_FILTERS_CONFIG");
Log.log(e);
Expand All @@ -468,13 +456,13 @@ public static Filters loadConfig(File configFile) throws IOException {
*/
public static void saveConfig(Filters config, File configFile) throws IOException {
if (config == null) {
configFile.delete();
boolean ignored = configFile.delete();
return;
}
try {
Marshaller m = CONFIG_CTX.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.marshal(config, configFile);
XmlMapper mapper = new XmlMapper();
mapper.registerModule(new JaxbAnnotationModule());
mapper.writerWithDefaultPrettyPrinter().writeValue(configFile, config);
} catch (Exception e) {
Log.logErrorRB("FILTERMASTER_ERROR_SAVING_FILTERS_CONFIG");
Log.log(e);
Expand Down Expand Up @@ -517,7 +505,7 @@ public static String now(String dateFormat) {

/**
* Calculate the target path corresponding to the given source file.
*
*
* @param sourceDir
* Path to the project's <code>source</code> dir
* @param srcRelPath
Expand Down Expand Up @@ -736,7 +724,7 @@ public static Filters cloneConfig(Filters orig) {
/**
* Clone one filter's config for editing.
*
* @param f
* @param filter
* one filter's config
* @return new config instance
*/
Expand All @@ -759,8 +747,8 @@ public static Filter cloneFilter(Filter filter) {
/**
* Clone one filter's instance config for editing.
*
* @param f
* new filter's instance config
* @param files
* new filter's instance config file
* @return new config instance
*/
private static Files cloneFiles(Files files) {
Expand All @@ -786,7 +774,7 @@ public static Filter getDefaultSettingsFromFilter(final String filterClassname)
}
Filter fc = new Filter();
fc.setClassName(f.getClass().getName());
fc.setEnabled(f.isEnabledInDefault());
fc.setEnabled(true);
for (Instance ins : f.getDefaultInstances()) {
Files ff = new Files();
ff.setSourceEncoding(ins.getSourceEncoding());
Expand Down

0 comments on commit e7f6ac0

Please sign in to comment.