Merge remote-tracking branch 'origin/master' into docker

pull/55/head
luccioman 9 years ago
commit 73d8b7931e

@ -88,7 +88,7 @@
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/> <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="lib" path="lib/icu4j-57_1.jar"/> <classpathentry kind="lib" path="lib/icu4j-57_1.jar"/>
<classpathentry kind="lib" path="lib/htmllexer.jar"/> <classpathentry kind="lib" path="lib/htmllexer.jar"/>
<classpathentry kind="lib" path="lib/jsoup-1.9.1.jar"/> <classpathentry kind="lib" path="lib/jsoup-1.9.2.jar"/>
<classpathentry kind="lib" path="lib/javax.servlet-api-3.1.0.jar"/> <classpathentry kind="lib" path="lib/javax.servlet-api-3.1.0.jar"/>
<classpathentry kind="lib" path="lib/weupnp-0.1.4.jar"/> <classpathentry kind="lib" path="lib/weupnp-0.1.4.jar"/>
<classpathentry kind="lib" path="lib/common-image-3.2.1.jar"/> <classpathentry kind="lib" path="lib/common-image-3.2.1.jar"/>

@ -206,7 +206,7 @@
<pathelement location="${lib}/jetty-xml-9.2.17.v20160517.jar" /> <pathelement location="${lib}/jetty-xml-9.2.17.v20160517.jar" />
<pathelement location="${lib}/jsch-0.1.53.jar" /> <pathelement location="${lib}/jsch-0.1.53.jar" />
<pathelement location="${lib}/json-simple-1.1.1.jar" /> <pathelement location="${lib}/json-simple-1.1.1.jar" />
<pathelement location="${lib}/jsoup-1.9.1.jar" /> <pathelement location="${lib}/jsoup-1.9.2.jar" />
<pathelement location="${lib}/log4j-over-slf4j-1.7.18.jar" /> <pathelement location="${lib}/log4j-over-slf4j-1.7.18.jar" />
<pathelement location="${lib}/lucene-analyzers-common-5.5.1.jar" /> <pathelement location="${lib}/lucene-analyzers-common-5.5.1.jar" />
<pathelement location="${lib}/lucene-analyzers-phonetic-5.5.1.jar" /> <pathelement location="${lib}/lucene-analyzers-phonetic-5.5.1.jar" />

3
debian/control vendored

@ -7,7 +7,8 @@ Standards-Version: 3.7.2
Package: yacy Package: yacy
Architecture: all Architecture: all
Depends: openjdk-7-jre-headless, sudo, debconf Depends: java7-runtime-headless | java8-runtime-headless, sudo, debconf
Suggests: curl | wget
Description: Peer-to-Peer Web Search Engine Description: Peer-to-Peer Web Search Engine
YaCy is a Java-based peer-to-peer search engine. YaCy is a Java-based peer-to-peer search engine.
It provides a personal web search engine, which is It provides a personal web search engine, which is

@ -11,14 +11,13 @@
#%env/templates/submenuDesign.template%# #%env/templates/submenuDesign.template%#
<h2>Translation Editor</h2> <h2>Translation Editor</h2>
<p>Translate untranslated text of the user interface (current language). The modified translation file is stored in DATA/LOCALE directory</p> <p>Translate untranslated text of the user interface (current language). The modified translation file is stored in DATA/LOCALE directory.</p>
<form id="Translation" method="post" action="Translator_p.html" enctype="multipart/form-data" accept-charset="UTF-8">
<fieldset> <fieldset>
<legend> <legend>
<label>UI Translation</label> <label>UI Translation</label>
</legend> </legend>
<p>Target Language: <b>#[targetlang]#</b></p><p class="error">#[errmsg]#</p> <p>Target Language: <b>#[targetlang]#</b></p><p class="error">#[errmsg]#</p>
<form id="Translation" method="post" action="Translator_p.html" enctype="multipart/form-data" accept-charset="UTF-8">
<label for="sourcefile">Source File</label> <label for="sourcefile">Source File</label>
<select name="sourcefile" onchange="submit();"> <select name="sourcefile" onchange="submit();">
#{filelist}# #{filelist}#
@ -37,7 +36,7 @@
<label for="targettxt#[tokenid]#" >#[sourcetxt]#</label> <label for="targettxt#[tokenid]#" >#[sourcetxt]#</label>
</td> </td>
<td style="border-bottom: solid gray; border-bottom-width: 1px;" valign="top" nowrap> <td style="border-bottom: solid gray; border-bottom-width: 1px;" valign="top" nowrap>
<input type="text" name="targettxt#[tokenid]#" id="targettxt#[tokenid]#" size="80" value="#[targettxt]#"/>#(filteruntranslated)#::<button name="approve" type="submit" value="#[tokenid]#" class="btn btn-sm"><span class="glyphicon glyphicon-ok-sign" style="color: green"/></button>#(/filteruntranslated)# <input type="text" name="targettxt#[tokenid]#" id="targettxt#[tokenid]#" size="80" value="#[targettxt]#" #(filteruntranslated)#disabled::#(/filteruntranslated)#/>#(filteruntranslated)#::<button name="approve" type="submit" value="#[tokenid]#" class="btn btn-sm"><span class="glyphicon glyphicon-ok-sign" style="color: green"/></button>#(/filteruntranslated)#
</td> </td>
</tr> </tr>
#{/textlist}# #{/textlist}#
@ -45,8 +44,8 @@
<input type="submit" name="savetranslationlist" value="Save translation" class="btn btn-primary"/> <input type="submit" name="savetranslationlist" value="Save translation" class="btn btn-primary"/>
</form> </fieldset>
</fieldset> </form>
#%env/templates/footer.template%# #%env/templates/footer.template%#
</body> </body>

@ -52,6 +52,8 @@ public class Translator_p {
File masterxlf = new File("locales", "master.lng.xlf"); File masterxlf = new File("locales", "master.lng.xlf");
if (!masterxlf.exists()) ctm.createMasterTranslationLists(masterxlf); if (!masterxlf.exists()) ctm.createMasterTranslationLists(masterxlf);
Map<String, Map<String, String>> origTrans = ctm.joinMasterTranslationLists(masterxlf, lngfile); Map<String, Map<String, String>> origTrans = ctm.joinMasterTranslationLists(masterxlf, lngfile);
final File locallngfile = ctm.getScratchFile(lngfile);
Map<String, Map<String, String>> localTrans = ctm.loadTranslationsLists(locallngfile); // TODO: this will read file twice
int i = 0; int i = 0;
if (origTrans.size() > 0) { if (origTrans.size() > 0) {
String filename = origTrans.keySet().iterator().next(); String filename = origTrans.keySet().iterator().next();
@ -87,7 +89,8 @@ public class Translator_p {
boolean changed = false; boolean changed = false;
for (String sourcetext : origTextList.keySet()) { for (String sourcetext : origTextList.keySet()) {
String targettxt = origTextList.get(sourcetext); String targettxt = origTextList.get(sourcetext);
if (targettxt == null || targettxt.isEmpty()) { boolean existinlocalTrans = localTrans.containsKey(filename) && localTrans.get(filename).containsKey(sourcetext);
if (targettxt == null || targettxt.isEmpty() || existinlocalTrans) {
prop.put("textlist_" + i + "_filteruntranslated", true); prop.put("textlist_" + i + "_filteruntranslated", true);
} else if (filteruntranslated) { } else if (filteruntranslated) {
continue; continue;
@ -100,21 +103,21 @@ public class Translator_p {
if (sourcetext.endsWith("<") && !t.endsWith("<")) t=t+"<"; if (sourcetext.endsWith("<") && !t.endsWith("<")) t=t+"<";
} }
targettxt = t; targettxt = t;
origTextList.replace(sourcetext, targettxt); // add changes to original (for display) and local (for save)
changed = true; origTextList.put(sourcetext, targettxt);
changed = ctm.addTranslation (localTrans, filename, sourcetext, targettxt);
} }
prop.putHTML("textlist_" + i + "_sourcetxt", sourcetext); prop.putHTML("textlist_" + i + "_sourcetxt", sourcetext);
prop.putHTML("textlist_" + i + "_targettxt", targettxt); prop.putHTML("textlist_" + i + "_targettxt", targettxt);
prop.put("textlist_" + i + "_tokenid", Integer.toString(i)); prop.put("textlist_" + i + "_tokenid", Integer.toString(i));
prop.put("textlist_" + i + "_filteruntranslated_tokenid", Integer.toString(i)); prop.put("textlist_" + i + "_filteruntranslated_tokenid", Integer.toString(i));
//prop.put("textlist_" + i +"_filteruntranslated", filteruntranslated);
i++; i++;
} }
if (post != null && post.containsKey("savetranslationlist")) { if (post != null && post.containsKey("savetranslationlist")) {
changed = true; changed = true;
} }
if (changed) { if (changed) {
ctm.saveAsLngFile(langcfg, ctm.getScratchFile(lngfile), origTrans); ctm.saveAsLngFile(langcfg, locallngfile, localTrans);
} }
} }
prop.put("textlist", i); prop.put("textlist", i);

@ -2779,7 +2779,7 @@ If the remote crawl option is switched on, then this peer will load URLs from th
#>Name<==>Name< #>Name<==>Name<
#>Remote<br/>Crawl<==>Remote<br/>Crawl< #>Remote<br/>Crawl<==>Remote<br/>Crawl<
#>Release/<br/>SVN<==>Version/<br/>SVN< #>Release/<br/>SVN<==>Version/<br/>SVN<
>PPM<==>==>Seiten pro Minute (PPM)< >PPM<==>Seiten pro Minute (PPM)<
>QPH<==>Anfragen pro Stunde (QPH)< >QPH<==>Anfragen pro Stunde (QPH)<
>Last<br/>Seen<==>Zuletzt<br/>Gesehen< >Last<br/>Seen<==>Zuletzt<br/>Gesehen<
>UTC</strong><br/>Offset<==>UTC</strong><br/>Abweichung< >UTC</strong><br/>Offset<==>UTC</strong><br/>Abweichung<
@ -3106,7 +3106,7 @@ value="add"==value="hinzufügen"
Console Status==Konsolen Status Console Status==Konsolen Status
Log-in as administrator to see full status==Als Administrator einloggen, für kompletten Status Log-in as administrator to see full status==Als Administrator einloggen, für kompletten Status
Welcome to YaCy!==Willkommen bei YaCy! Welcome to YaCy!==Willkommen bei YaCy!
Your settings are _not_ protected!</strong>==Ihre Einstellungen sind _nicht_ mit einem Kennwort geschützt!</strong> Your settings are _not_ protected!==Ihre Einstellungen sind _nicht_ mit einem Kennwort geschützt!
Please open the <a href="ConfigAccounts_p.html">accounts configuration</a> page <strong>immediately</strong>==Bitte öffnen Sie die <a href="ConfigAccounts_p.html">Benutzerverwaltung</a> <strong>sofort</strong> Please open the <a href="ConfigAccounts_p.html">accounts configuration</a> page <strong>immediately</strong>==Bitte öffnen Sie die <a href="ConfigAccounts_p.html">Benutzerverwaltung</a> <strong>sofort</strong>
and set an administration password.==und geben Sie ein Administrator Passwort ein. and set an administration password.==und geben Sie ein Administrator Passwort ein.
You have not published your peer seed yet. This happens automatically, just wait.==Ihr Peer ist dem Netzwerk noch nicht bekannt. Warten Sie noch ein wenig, dies geschieht automatisch. You have not published your peer seed yet. This happens automatically, just wait.==Ihr Peer ist dem Netzwerk noch nicht bekannt. Warten Sie noch ein wenig, dies geschieht automatisch.
@ -3449,6 +3449,21 @@ Threaddump<==Thread Dump<
#"create Threaddump"=="Threaddump erstellen" #"create Threaddump"=="Threaddump erstellen"
#----------------------------- #-----------------------------
#File: Translator_p.html
#---------------------------
Translation Editor==Übersetzungseditor
Translate untranslated text of the user interface (current language).==Ergänze fehlende Übersetzungen der Benutzeroberfläche (aktuell aktive Sprache).
The modified translation file is stored in DATA/LOCALE directory.==Geänderte Übersetzungen werden im Verzeichnis DATA/LOCALE gespeichert.
UI Translation==Übersetzung Benutzeroberfläche
Target Language:==Zielsprache
Source File==Quelldatei
view it==Datei anzeigen
filter untranslated==filter unübersetztes
Source Text==Quelltext
Translated Text==Übersetzung
Save translation==Änderungen speichern
#-----------------------------
#File: User.html #File: User.html
#--------------------------- #---------------------------
User Page==Benutzer Seite User Page==Benutzer Seite
@ -3582,13 +3597,13 @@ delete vocabulary<==Lösche Vokabelliste<
#File: WatchWebStructure_p.html #File: WatchWebStructure_p.html
#--------------------------- #---------------------------
Web Structure<==Webstruktur< Web Structure==Webstruktur
The data that is visualized here can also be retrieved in a XML file, which lists the reference relation between the domains.==Die Daten die hier visualisiert werden können auch in einer XML geladen werden, die die verweisenden Relationen zwischen den Domains auflistet. The data that is visualized here can also be retrieved in a XML file, which lists the reference relation between the domains.==Die Daten die hier visualisiert werden können auch in einer XML geladen werden, die die verweisenden Relationen zwischen den Domains auflistet.
With a GET-property 'about' you get only reference relations about the host that you give in the argument field for 'about'.==Mit der GET Eigenschaft 'about' können Sie nur die verweisenden Relationen über den im 'about' Argument Feld angegebenen Host abrufen. With a GET-property 'about' you get only reference relations about the host that you give in the argument field for 'about'.==Mit der GET Eigenschaft 'about' können Sie nur die verweisenden Relationen über den im 'about' Argument Feld angegebenen Host abrufen.
With a GET-property 'latest' you get a list of references that had been computed during the current run-time of YaCy, and with each next call only an update to the next list of references.==Mit der GET Eigenschaft 'latest' können Sie eine Liste der Referenzen abrufen, die während der aktuellen Laufzeit von YaCy berechnet wurden. Und mit jedem Aufruf nur ein Update der jeweils bis dahin neuen Referenzen. With a GET-property 'latest' you get a list of references that had been computed during the current run-time of YaCy, and with each next call only an update to the next list of references.==Mit der GET Eigenschaft 'latest' können Sie eine Liste der Referenzen abrufen, die während der aktuellen Laufzeit von YaCy berechnet wurden. Und mit jedem Aufruf nur ein Update der jeweils bis dahin neuen Referenzen.
Click the API icon to see the XML file.==Klicken Sie auf die API Sprechblase, um die XML Datei anzusehen. Click the API icon to see the XML file.==Klicken Sie auf die API Sprechblase, um die XML Datei anzusehen.
To see a list of all APIs, please visit the==Um eine Liste aller APIs zu sehen, besuchen Sie die To see a list of all APIs, please visit the==Um eine Liste aller APIs zu sehen, besuchen Sie die
API wiki page==API Seite im WikiWeb Structure==Netz Struktur API wiki page==API Seite im Wiki
>Host List<==>Host Liste< >Host List<==>Host Liste<
>#[count]# outlinks==>#[count]# ausgehende Links >#[count]# outlinks==>#[count]# ausgehende Links
host<==Host< host<==Host<

@ -2508,7 +2508,7 @@ If the remote crawl option is switched on, then this peer will load URLs from th
>Name<==>Ім’я< >Name<==>Ім’я<
>Remote<br/>Crawl<==>Remote<br/>Crawl< >Remote<br/>Crawl<==>Remote<br/>Crawl<
>Release/<br/>SVN<==>Випуск/SVN< >Release/<br/>SVN<==>Випуск/SVN<
>PPM<==>==>Сторінок За Хвилину (PPM)< >PPM<==>Сторінок За Хвилину (PPM)<
>QPH<==>Запитів За Годину (QPH)< >QPH<==>Запитів За Годину (QPH)<
>Last<br/>Seen<==>Востаннє<br/>бачено< >Last<br/>Seen<==>Востаннє<br/>бачено<
<strong>UTC</strong><br/>Offset==Зсув<br/><strong>UTC</strong> <strong>UTC</strong><br/>Offset==Зсув<br/><strong>UTC</strong>
@ -2830,7 +2830,7 @@ value="add"==value="додати"
Console Status==Консоль стану Console Status==Консоль стану
Log-in as administrator to see full status==Увійдіть як адміністратор для перегляду повного стану Log-in as administrator to see full status==Увійдіть як адміністратор для перегляду повного стану
Welcome to YaCy!==Вітаємо в YaCy! Welcome to YaCy!==Вітаємо в YaCy!
Your settings are _not_ protected!</strong>==Ваші налаштування _не_ захищені паролем!</strong> Your settings are _not_ protected!==Ваші налаштування _не_ захищені паролем!
Please open the <a href="ConfigAccounts_p.html">accounts configuration</a> page <strong>immediately</strong>==Будь-ласка, <strong>негайно</strong> відкрийте <a href="ConfigAccounts_p.html">настройки облікових записів</a> Please open the <a href="ConfigAccounts_p.html">accounts configuration</a> page <strong>immediately</strong>==Будь-ласка, <strong>негайно</strong> відкрийте <a href="ConfigAccounts_p.html">настройки облікових записів</a>
and set an administration password.==і виставте пароль адміністратора. and set an administration password.==і виставте пароль адміністратора.
You have not published your peer seed yet. This happens automatically, just wait.==Ваш вузол не відомий мережі. Зачекайте, це робиться автоматично. You have not published your peer seed yet. This happens automatically, just wait.==Ваш вузол не відомий мережі. Зачекайте, це робиться автоматично.

@ -423,7 +423,7 @@
<dependency> <dependency>
<groupId>org.jsoup</groupId> <groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId> <artifactId>jsoup</artifactId>
<version>1.9.1</version> <version>1.9.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.youcruit.com.cybozu.labs</groupId> <groupId>com.youcruit.com.cybozu.labs</groupId>

@ -106,11 +106,11 @@ public class MessageBoard {
if (key.length() > categoryLength) key = key.substring(0, categoryLength); if (key.length() > categoryLength) key = key.substring(0, categoryLength);
while (key.length() < categoryLength) key += "_"; while (key.length() < categoryLength) key += "_";
key += dateString() + snString(); key += dateString() + snString();
record.put("author", ((authorName == null) || (authorName.isEmpty())) ? authorName : "anonymous"); record.put("author", ((authorName != null) && (!authorName.isEmpty())) ? authorName : "anonymous");
record.put("recipient", ((recName == null) || (recName.isEmpty())) ? recName : "anonymous"); record.put("recipient", ((recName != null) && (!recName.isEmpty())) ? recName : "anonymous");
record.put("ahash", (authorHash == null) ? authorHash : ""); record.put("ahash", (authorHash != null) ? authorHash : "");
record.put("rhash", (recHash == null) ? recHash : ""); record.put("rhash", (recHash != null) ? recHash : "");
record.put("subject", (subject == null) ? subject : ""); record.put("subject", (subject != null) ? subject : "");
record.put("message", (message == null) ? "" : Base64Order.enhancedCoder.encode(message)); record.put("message", (message == null) ? "" : Base64Order.enhancedCoder.encode(message));
record.put("read", "false"); record.put("read", "false");
} }

@ -67,11 +67,11 @@ public class Translator {
/** /**
* Translate source using entries in translationTable * Translate source using entries in translationTable
* @param source text to translate. Mus be non null. * @param source text to translate. Must be non null.
* @param translationTable translation entries : text to translate -> translation * @param translationTable translation entries : text to translate -> translation
* @return source translated * @return source translated
*/ */
public static String translate(final String source, public String translate(final StringBuilder source,
final Map<String, String> translationTable) { final Map<String, String> translationTable) {
final Set<Map.Entry<String, String>> entries = translationTable.entrySet(); final Set<Map.Entry<String, String>> entries = translationTable.entrySet();
StringBuilder builder = new StringBuilder(source); StringBuilder builder = new StringBuilder(source);
@ -146,7 +146,7 @@ public class Translator {
* @param translationList map of translations * @param translationList map of translations
* @return true when destFile was sucessfully written, false otherwise * @return true when destFile was sucessfully written, false otherwise
*/ */
public static boolean translateFile(final File sourceFile, final File destFile, final Map<String, String> translationList){ public boolean translateFile(final File sourceFile, final File destFile, final Map<String, String> translationList){
StringBuilder content = new StringBuilder(); StringBuilder content = new StringBuilder();
BufferedReader br = null; BufferedReader br = null;
@ -167,7 +167,7 @@ public class Translator {
} }
} }
String processedContent = translate(content.toString(), translationList); String processedContent = translate(content, translationList);
BufferedWriter bw = null; BufferedWriter bw = null;
try{ try{
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destFile), StandardCharsets.UTF_8)); bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destFile), StandardCharsets.UTF_8));
@ -186,11 +186,17 @@ public class Translator {
return true; return true;
} }
public boolean translateFiles(final File sourceDir, final File destDir, final File baseDir, final File translationFile, final String extensions){ /**
return translateFiles(sourceDir, destDir, baseDir, loadTranslationsLists(translationFile), extensions); * Translate files in sourceDir (relative path of baseDir) write result to destDir
} *
* @param sourceDir relative path
public static boolean translateFiles(final File sourceDir, final File destDir, final File baseDir, final Map<String, Map<String, String>> translationLists, final String extensions){ * @param destDir destination
* @param baseDir base dir of source
* @param translationLists translation to use
* @param extensions file extension to include in translation
* @return
*/
public boolean translateFiles(final File sourceDir, final File destDir, final File baseDir, final Map<String, Map<String, String>> translationLists, final String extensions){
destDir.mkdirs(); destDir.mkdirs();
final List<String> exts = ListManager.string2vector(extensions); final List<String> exts = ListManager.string2vector(extensions);
final File[] sourceFiles = sourceDir.listFiles(new ExtensionsFileFilter(exts)); final File[] sourceFiles = sourceDir.listFiles(new ExtensionsFileFilter(exts));
@ -200,7 +206,7 @@ public class Translator {
relativePath=sourceFile.getAbsolutePath().substring(baseDir.getAbsolutePath().length()+1); //+1 to get the "/" relativePath=sourceFile.getAbsolutePath().substring(baseDir.getAbsolutePath().length()+1); //+1 to get the "/"
relativePath = relativePath.replace(File.separatorChar, '/'); relativePath = relativePath.replace(File.separatorChar, '/');
} catch (final IndexOutOfBoundsException e) { } catch (final IndexOutOfBoundsException e) {
ConcurrentLog.severe("TRANSLATOR", "Error creating relative Path for "+sourceFile.getAbsolutePath()); ConcurrentLog.severe("TRANSLATOR", "Error creating relative Path for "+sourceFile.getAbsolutePath());
relativePath = "wrong path"; //not in translationLists relativePath = "wrong path"; //not in translationLists
} }
if (translationLists.containsKey(relativePath)) { if (translationLists.containsKey(relativePath)) {
@ -219,17 +225,29 @@ public class Translator {
return true; return true;
} }
public boolean translateFilesRecursive(final File sourceDir, final File destDir, final File translationFile, final String extensions, final String notdir){ /**
final List<File> dirList=FileUtils.getDirsRecursive(sourceDir, notdir); * Translate files starting with sourceDir and all subdirectories.
*
* @param sourceDir
* @param destDir
* @param translationFile translation language file
* @param extensions extension of files to include in translation
* @param notdir directory to exclude
* @return true if all files translated (or none)
*/
public boolean translateFilesRecursive(final File sourceDir, final File destDir, final File translationFile, final String extensions, final String notdir) {
final List<File> dirList = FileUtils.getDirsRecursive(sourceDir, notdir);
dirList.add(sourceDir); dirList.add(sourceDir);
final Map<String, Map<String, String>> translationLists = loadTranslationsLists(translationFile);
boolean erg = true;
for (final File file : dirList) { for (final File file : dirList) {
if(file.isDirectory() && !file.getName().equals(notdir)) { if (file.isDirectory() && !file.getName().equals(notdir)) {
//cuts the sourcePath and prepends the destPath //cuts the sourcePath and prepends the destPath
File file2 = new File(destDir, file.getPath().substring(sourceDir.getPath().length())); File file2 = new File(destDir, file.getPath().substring(sourceDir.getPath().length()));
translateFiles(file, file2, sourceDir, translationFile, extensions); erg &= translateFiles(file, file2, sourceDir, translationLists, extensions);
} }
} }
return true; return erg;
} }
public static Map<String, String> langMap(@SuppressWarnings("unused") final serverSwitch env) { public static Map<String, String> langMap(@SuppressWarnings("unused") final serverSwitch env) {

@ -58,7 +58,7 @@ public class CreateTranslationMasters extends TranslatorXliff {
* @param targetLngTxt the translated text * @param targetLngTxt the translated text
* @return true = if map was modified, otherwise false * @return true = if map was modified, otherwise false
*/ */
protected boolean addTranslation(Map<String, Map<String, String>> translation, final String relFileName, final String sourceLngTxt, final String targetLngTxt) { public boolean addTranslation(Map<String, Map<String, String>> translation, final String relFileName, final String sourceLngTxt, final String targetLngTxt) {
boolean modified = false; boolean modified = false;
Map<String, String> transFile; Map<String, String> transFile;
@ -156,7 +156,7 @@ public class CreateTranslationMasters extends TranslatorXliff {
final String filename = lngfile.getName(); final String filename = lngfile.getName();
Map<String, Map<String, String>> xliffTrans = loadTranslationsListsFromXliff(xlifmaster); Map<String, Map<String, String>> xliffTrans = loadTranslationsListsFromXliff(xlifmaster);
// load translation list // load translation list
System.out.println("join into master translation file " + filename); ConcurrentLog.info("TRANSLATOR", "join into master translation file " + filename);
Map<String, Map<String, String>> origTrans = loadTranslationsLists(lngfile); Map<String, Map<String, String>> origTrans = loadTranslationsLists(lngfile);
for (String transfilename : origTrans.keySet()) { // get translation filename for (String transfilename : origTrans.keySet()) { // get translation filename

@ -55,8 +55,11 @@ import org.oasis.xliff.core_12.Xliff;
* Wordlist based translator * Wordlist based translator
* *
* Translator which can read and write translation lists from a * Translator which can read and write translation lists from a
* <a href="http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html">XLIFF * <a href="http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html">XLIFF 1.2</a>
* 1.2</a> file with phrases or single words to translate a string or a file * file with phrases or single words to translate a string or a file.
*
* On loading of translation files loaded data is merged with local (modified or downloaded)
* translation data in DATA/LOCALE/
*/ */
public class TranslatorXliff extends Translator { public class TranslatorXliff extends Translator {
@ -140,21 +143,56 @@ public class TranslatorXliff extends Translator {
/** /**
* Maps (overrides) Translator.loadTranslationsLists to read from xliff file * Maps (overrides) Translator.loadTranslationsLists to read from xliff file
* if file extension is .xlf or .xliff (otherwise load xx.lng file) * if file extension is .xlf or .xliff (otherwise load xx.lng file).
* Additionally if localy modified translation exists in DATA/LOCALE content
* is merged into given translation.
* *
* @param xliffFile * @param xliffFile
* @return translatio map * @return translation map
*/ */
@Override @Override
public Map<String, Map<String, String>> loadTranslationsLists(final File xliffFile) { public Map<String, Map<String, String>> loadTranslationsLists(final File xliffFile) {
File locallng = getScratchFile(xliffFile); File locallng = getScratchFile(xliffFile);
if (xliffFile.getName().toLowerCase().endsWith(".xlf") || xliffFile.getName().toLowerCase().endsWith(".xliff")) { if (xliffFile.getName().toLowerCase().endsWith(".xlf") || xliffFile.getName().toLowerCase().endsWith(".xliff")) {
return locallng.exists() ? loadTranslationsListsFromXliff(locallng) : loadTranslationsListsFromXliff(xliffFile); if (locallng.exists()) {
Map<String, Map<String, String>> mergedList = loadTranslationsListsFromXliff(xliffFile);
Map<String, Map<String, String>> tmplist = loadTranslationsListsFromXliff(locallng);
return mergeTranslationLists(mergedList, tmplist);
} else {
return loadTranslationsListsFromXliff(xliffFile);
}
} else if (locallng.exists()) {
Map<String, Map<String, String>> mergedList = super.loadTranslationsLists(xliffFile);
Map<String, Map<String, String>> tmplist = super.loadTranslationsLists(locallng);
return mergeTranslationLists(mergedList, tmplist);
} else { } else {
return locallng.exists() ? super.loadTranslationsLists(locallng) : super.loadTranslationsLists(xliffFile); return super.loadTranslationsLists(xliffFile);
} }
} }
/**
* Merges translations, values from localTrans overwrite entries in masterTrans.
*
* @param masterTrans master translation
* @param localTrans translation to be merged to master
* @return resulting map with all entries from master and localTrans
*/
protected Map<String, Map<String, String>> mergeTranslationLists(Map<String, Map<String, String>> masterTrans, Map<String, Map<String, String>> localTrans) {
if (localTrans != null && !localTrans.isEmpty()) {
for (String transfilename : localTrans.keySet()) { // get translation filename
Map<String, String> origList = localTrans.get(transfilename);
if (masterTrans.containsKey(transfilename)) {
Map<String, String> xliffList = masterTrans.get(transfilename);
xliffList.putAll(origList);
} else {
masterTrans.put(transfilename, origList);
}
}
}
return masterTrans;
}
/** /**
* Saves the internal translation map as XLIFF 1.2 file * Saves the internal translation map as XLIFF 1.2 file
* *
@ -221,23 +259,24 @@ public class TranslatorXliff extends Translator {
* @throws IOException * @throws IOException
*/ */
private void writeFileSection(final String filename, final Map<String, String> textlist, OutputStreamWriter output) throws IOException { private void writeFileSection(final String filename, final Map<String, String> textlist, OutputStreamWriter output) throws IOException {
output.write("#File: " + filename + "\n" if (!filename.isEmpty()) {
+ "#---------------------------\n"); // required in 1.2 output.write("#File: " + filename + "\n"
+ "#---------------------------\n");
for (String source : textlist.keySet()) { for (String source : textlist.keySet()) {
String target = textlist.get(source); String target = textlist.get(source);
// we use hashCode of source string to get same id in different xliff files for same translation text if (target != null && !target.isEmpty()) { // omitt target text if not available
if (target != null && !target.isEmpty()) { // omitt target text if not available if (source.equals(target)) {
if (source.equals(target)) { output.write("#" + source + "==" + target + "\n"); // no translation needed (mark #)
output.write("#" + source + "==" + target + "\n"); // no translation needed (mark #) } else {
output.write(source + "==" + target + "\n");
}
} else { } else {
output.write(source + "==" + target + "\n"); output.write("#" + source + "==" + source + "\n"); // no translation available (mark #)
} }
} else {
output.write("#"+source + "==" + source + "\n"); // no translation available (mark #)
} }
output.write("#-----------------------------\n\n");
} }
output.write("#-----------------------------\n\n");
} }
/** /**
@ -267,7 +306,7 @@ public class TranslatorXliff extends Translator {
// special handling of "ConfigLanguage_p.html" to list on top of all other // special handling of "ConfigLanguage_p.html" to list on top of all other
// because of some important identifier // because of some important identifier
Map<String, String> txtmap = lng.get("ConfigLanguage_p.html"); Map<String, String> txtmap = lng.get("ConfigLanguage_p.html");
writeFileSection("ConfigLanguage_p.html", txtmap, output); if (txtmap != null) writeFileSection("ConfigLanguage_p.html", txtmap, output);
for (String afilemap : lng.keySet()) { for (String afilemap : lng.keySet()) {
txtmap = lng.get(afilemap); txtmap = lng.get(afilemap);

Loading…
Cancel
Save