Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
allow '# NON-TRANSLATABLE' comments in properties files
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmason committed Aug 26, 2011
1 parent f21d9d5 commit 6a616f3
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.IOException;
import java.io.InputStream;
import java.util.InvalidPropertiesFormatException;
import java.util.List;

import org.fedorahosted.openprops.Properties;
Expand All @@ -23,6 +24,7 @@ public class PropReader
{

public static final String PROP_CONTENT_TYPE = "text/plain";
private static final String NEWLINE_REGEX = "(\r\n|\r|\n)";

// pre: template already extracted
public void extractTarget(TranslationsResource doc, InputStream in, LocaleId localeId, ContentState contentState) throws IOException
Expand All @@ -46,26 +48,103 @@ public void extractTarget(TranslationsResource doc, InputStream in, LocaleId loc
}
}

/**
* Reads properties from a given {@link InputStream} and adds them to the
* given {@link Resource}.
*
* @param doc the resource to add properties textflows to
* @param in the input stream to read the properties from
* @throws IOException
*/
// TODO allowing Readers (via InputSource) might be a bad idea
// TODO add documentation on exceptions thrown
public void extractTemplate(Resource doc, InputStream in) throws IOException
{
List<TextFlow> resources = doc.getTextFlows();
Properties props = loadProps(in);
int nonTranslatableCount = 0;
for (String key : props.stringPropertyNames())
{
String val = props.getProperty(key);
String id = getID(key, val);
TextFlow textFlow = new TextFlow(id);
textFlow.setContent(val);
String comment = props.getComment(key);
if (comment != null && comment.length() != 0)
String comment = null;
String rawComment = props.getRawComment(key);
if (rawComment != null && rawComment.length() != 0)
{
SimpleComment simpleComment = textFlow.getExtensions(true).findOrAddByType(SimpleComment.class);
simpleComment.setValue(comment);
StringBuilder sb = new StringBuilder(rawComment.length());
nonTranslatableCount = processCommentForNonTranslatable(nonTranslatableCount, rawComment, sb);
comment = sb.toString();
}
if (nonTranslatableCount == 0)
{
String val = props.getProperty(key);
String id = getID(key, val);
TextFlow textFlow = new TextFlow(id);
textFlow.setContent(val);
if (comment != null && comment.length() != 0)
{
SimpleComment simpleComment = textFlow.getExtensions(true).findOrAddByType(SimpleComment.class);
simpleComment.setValue(comment);
}
// textFlow.setLang(LocaleId.EN);
resources.add(textFlow);
}
}
}

/**
* Processes a full comment for non-translatable sections, writing
* translatable sections to a given string buffer.
*
* @param comment comment to process, may have multiple lines
* @param sb string buffer to output comments in translatable blocks
* @return adjusted non-translateable count, a value > 0 indicates that the
* current section is non-translatable
* @throws Exception
*/
private int processCommentForNonTranslatable(int nonTranslatableCount, String comment, StringBuilder sb) throws InvalidPropertiesFormatException
{
int nonTranslatable = nonTranslatableCount;
String[] lines = comment.split(NEWLINE_REGEX);

int lineNonTranslatable;
for (String line : lines)
{
lineNonTranslatable = checkNonTranslatable(line);
nonTranslatable += lineNonTranslatable;
if (nonTranslatable < 0)
{
// TODO probably want a different exception here
throw new InvalidPropertiesFormatException("Found '# END NON-TRANSLATABLE' " + "without matching '# START NON-TRANSLATABLE'");
}
// textFlow.setLang(LocaleId.EN);
resources.add(textFlow);
if (nonTranslatable == 0 && lineNonTranslatable == 0)
{
sb.append(Properties.cookCommentLine(line));
// TODO if not last line
sb.append('\n');
}
}

return nonTranslatable;
}

/**
* Checks a comment for START and END of NON-TRANSLATABLE sections within a
* single line of a comment.
*
* @param line a single line of a comment
* @return 0 if no NON-TRANSLATABLE comment is found, +1 for start, -1 for
* end
*/
private int checkNonTranslatable(String line)
{
if (line.startsWith("# START NON-TRANSLATABLE"))
{
return 1;
}
if (line.startsWith("# END NON-TRANSLATABLE"))
{
return -1;
}
return 0;
}

private String getID(String key, String val)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,42 @@
package org.zanata.adapter.properties;

import org.testng.annotations.Test;
import org.testng.annotations.BeforeMethod;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.InvalidPropertiesFormatException;
import java.util.List;

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

import org.junit.Test;
import org.apache.commons.lang.NotImplementedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.testng.Assert.*;
import org.zanata.common.ContentState;
import org.zanata.common.LocaleId;
import org.zanata.rest.dto.resource.Resource;
import org.zanata.rest.dto.resource.TextFlow;
import org.zanata.rest.dto.resource.TranslationsResource;

public class PropReaderTests
{
private static final Logger log = LoggerFactory.getLogger(PropReaderTests.class);

@SuppressWarnings("deprecation")
PropReader propReader = new PropReader();
PropReader propReader;

@BeforeMethod
public void resetReader()
{
propReader = new PropReader();
}

@Test
public void roundtripSrcPropsToDocXmlToProps() throws Exception
Expand Down Expand Up @@ -77,4 +90,42 @@ private InputStream getResourceAsStream(String relativeResourceName) throws File
throw new FileNotFoundException(relativeResourceName);
return stream;
}

@Test
public void extractTemplateRemovesNonTranslateableRegions() throws IOException
{
Resource srcDoc = new Resource("test");
InputStream testStream = getResourceAsStream("test_non_trans.properties");
propReader.extractTemplate(srcDoc, testStream);

List<TextFlow> textFlows = srcDoc.getTextFlows();

assertEquals(textFlows.size(), 2, "Unexpected number of textflows");
assertEquals(textFlows.get(0).getId(), "HELLO", "Unexpected textflow id");
assertEquals(textFlows.get(1).getId(), "GOODBYE", "Unexpected textflow id");
// TODO also check comments?
}

@Test
public void extractTemplateNestedNonTranslatableRegions() throws Exception
{
Resource srcDoc = new Resource("test");
InputStream testStream = getResourceAsStream("test_non_trans_nested.properties");
propReader.extractTemplate(srcDoc, testStream);

List<TextFlow> textFlows = srcDoc.getTextFlows();

assertEquals(textFlows.size(), 2, "Unexpected number of textflows");
assertEquals(textFlows.get(0).getId(), "HELLO", "Unexpected textflow id");
assertEquals(textFlows.get(1).getId(), "GOODBYE", "Unexpected textflow id");
// TODO also check comments?
}

@Test(expectedExceptions = InvalidPropertiesFormatException.class)
public void extractTemplateNonTranslatableMismatchException() throws IOException, InvalidPropertiesFormatException
{
Resource srcDoc = new Resource("test");
InputStream testStream = getResourceAsStream("test_non_trans_mismatch.properties");
propReader.extractTemplate(srcDoc, testStream);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# a source comment
HELLO=Hello World

# START NON-TRANSLATABLE
# non-translatable source comment
NONT=Hello Config

# other non-translatable source comment
NONT3=Goodbye Config
# END NON-TRANSLATABLE

# different source comment
GOODBYE=Goodbye World
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# a source comment
HELLO=Hello World

# END NON-TRANSLATABLE

GOODBYE=Goodbye World
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# a source comment
HELLO=Hello World

# START NON-TRANSLATABLE
# non-trans source comment
NONT=Hello Config

# START NON-TRANSLATABLE
# non-trans source comment 2
NONT2=Also this Config
# END NON-TRANSLATABLE

# this was non-translatable before
NONT3=Goodbye Config
# END NON-TRANSLATABLE

# different source comment
GOODBYE=Goodbye World

0 comments on commit 6a616f3

Please sign in to comment.