From 77756088ea48393c89c05d4acd14efdd18b61dd9 Mon Sep 17 00:00:00 2001 From: "c.gromer" Date: Tue, 23 Apr 2019 15:53:25 +0200 Subject: [PATCH 01/15] Initial Resx-Plugin commit --- csharp/.classpath | 27 ++ csharp/.gitignore | 3 + csharp/.project | 23 + csharp/META-INF/.gitignore | 1 + csharp/pom.xml | 116 +++++ .../org/jabylon/csharp/CSharpConverter.java | 419 ++++++++++++++++++ .../org/jabylon/csharp/CSharpScanner.java | 298 +++++++++++++ .../test/java/org/jabylon/csharp/AppTest.java | 38 ++ 8 files changed, 925 insertions(+) create mode 100644 csharp/.classpath create mode 100644 csharp/.gitignore create mode 100644 csharp/.project create mode 100644 csharp/META-INF/.gitignore create mode 100644 csharp/pom.xml create mode 100644 csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java create mode 100644 csharp/src/main/java/org/jabylon/csharp/CSharpScanner.java create mode 100644 csharp/src/test/java/org/jabylon/csharp/AppTest.java diff --git a/csharp/.classpath b/csharp/.classpath new file mode 100644 index 0000000..351f14c --- /dev/null +++ b/csharp/.classpath @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/csharp/.gitignore b/csharp/.gitignore new file mode 100644 index 0000000..174222f --- /dev/null +++ b/csharp/.gitignore @@ -0,0 +1,3 @@ +/OSGI-INF +/lib +/.settings diff --git a/csharp/.project b/csharp/.project new file mode 100644 index 0000000..47dea4c --- /dev/null +++ b/csharp/.project @@ -0,0 +1,23 @@ + + + csharp + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/csharp/META-INF/.gitignore b/csharp/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/csharp/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/csharp/pom.xml b/csharp/pom.xml new file mode 100644 index 0000000..9058c98 --- /dev/null +++ b/csharp/pom.xml @@ -0,0 +1,116 @@ + + 4.0.0 + csharp + bundle + + + org.jabylon + 1.3.0 + jabylon-parent + + + 1.3.0-SNAPSHOT + + Adds support for C# strings XML + + + https://github.com/jutzig/jabylon-plugins + scm:git:https://github.com/jutzig/jabylon-plugins.git + scm:git:https://github.com/jutzig/jabylon-plugins.git + HEAD + + + + + jabylon + http://www.jabylon.org/maven + + true + + + false + + + + + + + + src/main/java + + **/*.html + **/*.properties + + + + ./ + + plugin.xml + + + + + + + + ${project.groupId} + properties + ${project.parent.version} + provided + + + ${project.groupId} + common + ${project.parent.version} + provided + + + ${project.groupId} + rest.ui + ${project.parent.version} + provided + + + + org.eclipse.emf + cdo + + + org.apache.wicket + wicket-core + + + org.slf4j + slf4j-api + + + org.eclipse.emf + ecore + + + org.eclipse.emf + common + + + org.eclipse.osgi + services + + + org.eclipse.equinox + common + + + org.eclipse.equinox + preferences + + + org.apache.felix + org.apache.felix.scr.annotations + + + + junit + junit + + + diff --git a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java new file mode 100644 index 0000000..5bc4caa --- /dev/null +++ b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java @@ -0,0 +1,419 @@ +package org.jabylon.csharp; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.URI; +import org.jabylon.properties.PropertiesFactory; +import org.jabylon.properties.PropertiesPackage; +import org.jabylon.properties.Property; +import org.jabylon.properties.PropertyAnnotation; +import org.jabylon.properties.PropertyFile; +import org.jabylon.properties.types.PropertyAnnotations; +import org.jabylon.properties.types.PropertyConverter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Comment; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +public class CSharpConverter implements PropertyConverter{ + + private static final String NAME_ATTRIBUTE = "name"; + private static final String ROOT_NODE = "root"; + private static final String DATA = "data"; + + private static final String NO_TRANS = "No_Translation"; // denotes a property a non-candidate for translation (most of the properties are non-candidates) + + private static final Logger LOG = LoggerFactory.getLogger(CSharpConverter.class); + + /** + * allows to disable pretty print for unit tests + */ + private boolean prettyPrint = true; + + private URI uri; + + private String comment; + + // If LOG... is running stable we can remove the System.out.println statemenets entirely + + + public CSharpConverter(URI resourceLocation, boolean prettyPrint) { + this.uri = resourceLocation; + this.prettyPrint = prettyPrint; + //System.out.println("CSharpConverter1"); + LOG.info("C#:CSharpConverter1"); + + } + + + @Override + public PropertyFile load(InputStream in, String encoding) throws IOException { + // TODO Auto-generated method stub + + LOG.info("C#:load1, in: " + in.toString()); + + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setIgnoringComments(false); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document result = builder.parse(in); + PropertyFile file = PropertiesFactory.eINSTANCE.createPropertyFile(); + + Node firstNode = result.getChildNodes().item(0); + if(firstNode.getNodeType()==Node.COMMENT_NODE) { + String nodeValue = firstNode.getNodeValue(); + //System.out.println("load1, value first node: " + nodeValue); + LOG.info("C#:load2, value first node: " + nodeValue); + file.setLicenseHeader(nodeValue); + } + + Node resources = result.getDocumentElement(); + + //System.out.println("load2, resources, TextContent: " + resources.getTextContent()); + LOG.info("C#:load3, resources, TextContent: " + resources.getTextContent()); + + // blueprint from Android: + /*if(!ROOT_NODE.equals(resources.getNodeName())) { + LOG.error("C#:XML does not start with "+ROOT_NODE+" but "+resources.getLocalName()+". Location: "+uri); + return file; + }*/ + + NodeList nodes = resources.getChildNodes(); + + for (int i = 0; i < nodes.getLength(); i++) { + Node node = nodes.item(i); + //System.out.println("load3, child node_" + i + " Name: " + node.getNodeName() + " Value: " + node.getNodeValue()); + LOG.info("C#:load4, child node_" + i + " Name: " + node.getNodeName() + " Value: " + node.getNodeValue()); + loadNode(node,file); + } + return file; + + } catch (SAXException e) { + throw new IOException(e); + } catch (ParserConfigurationException e) { + throw new IOException(e); + } finally { + in.close(); + } + } + + + private void loadNode(Node node, PropertyFile file) { + //Android as a blueprint: + /*if(node.getNodeType()==Node.TEXT_NODE) + return; + if(node.getNodeType()==Node.COMMENT_NODE) { + comment = node.getNodeValue(); + return; + }*/ + + Property property = PropertiesFactory.eINSTANCE.createProperty(); + String name = node.getNodeName(); + + //System.out.println("loadNode1, Name: " + name); + LOG.info("C#:loadNode1, Name: " + name); + + if(name.equals(DATA)){ + loadString(node, property); + } + else { + //System.out.println("loadNode2, error, Invalid tag "+name+" found in " + uri + " Skipping"); + LOG.error("C#:loadNode2, Invalid tag "+name+" found in " + uri + " Skipping"); + return; + } + + property.setComment(comment); + comment = null; + file.getProperties().add(property); + //System.out.println("loadNode3, end"); + LOG.info("C#:loadNode3, end"); + } + + + private void loadString(Node node, Property property) { + + Node name = node.getAttributes().getNamedItem(NAME_ATTRIBUTE); + + if (null == name) { + //System.out.println("loadString1, NAME_ATTRIBUTE not found TextContent: " + node.getTextContent()); + LOG.info("C#:loadString1, NAME_ATTRIBUTE not found TextContent: " + node.getTextContent()); + return; + } + + String textContentName = name.getTextContent(); + + //System.out.println("loadString2, textContentName: " + textContentName); + LOG.info("C#:loadString2, textContentName: " + textContentName); + + String key = name.getNodeValue(); + property.setKey(key); + + // most of the xml-elements in CSharp are not for translation + if (false == isCandidateForTranslation(key)) { + PropertyAnnotation annotation = PropertiesFactory.eINSTANCE.createPropertyAnnotation(); + + annotation.setName(PropertyAnnotations.NON_TRANSLATABLE); + property.getAnnotations().add(annotation); + String textContentNode = node.getTextContent(); + //System.out.println("loadString3, textContentNode: " + textContentNode); + LOG.info("C#:loadString3, textContentNode: " + textContentNode); + property.setValue(decode(textContentNode)); + } + else { // provided for translation + //System.out.println("loadString4, provided for translation "); + LOG.info("C#:loadString4, provided for translation "); + property.setValue(decode(textContentName)); + } + } + + + private Boolean isCandidateForTranslation(String key) { + Boolean bReturn = false; + + //System.out.println("isCandidateForTranslation1, key: " + key); + LOG.info("C#:isCandidateForTranslation1, key: " + key); + + if (key.contains(".Text\"")) { + bReturn = true; + } + + //System.out.println("isCandidateForTranslation2, bReturn: " + bReturn); + LOG.info("C#:isCandidateForTranslation2, bReturn: " + bReturn); + return bReturn; + } + + + /** + * decodes a string + * @param textContent + * @return the decoded string + */ + private String decode(String textContent) { + if(textContent==null) { + //System.out.println("decode1, textContent is null" ); + LOG.info("C#:decode1, textContent is null" ); + return null; + } + + // Android code as a blueprint + /*if(textContent.startsWith("\"") && textContent.endsWith("\"")) + return textContent.substring(1, textContent.length()-1); + return textContent.replace("\\'", "'");*/ + //System.out.println("decode1, textContent: " + textContent); + LOG.info("C#:decode1, textContent: " + textContent); + return textContent; + } + + + @Override + public int write(OutputStream out, PropertyFile file, String encoding) throws IOException { + try { + //System.out.println("write1, file:" + file.toString() + " encoding: " + encoding); + LOG.info("C#:write1, file:" + file.toString() + " encoding: " + encoding); + + int counter = 0; + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + Document document = factory.newDocumentBuilder().newDocument(); + + //System.out.println("write2"); + LOG.info("C#:write2"); + + if(isFilled(file.getLicenseHeader())) + { + //System.out.println("write3"); + LOG.info("C#:write3"); + document.appendChild(document.createComment(file.getLicenseHeader())); + } + + //System.out.println("write4"); + LOG.info("C#:write4"); + + Element root = document.createElement(ROOT_NODE); + document.appendChild(root); + EList properties = file.getProperties(); + for (Property property : properties) { + //System.out.println("write5, property: " + property.toString()); + LOG.info("C#:write5, property: " + property.toString()); + if(writeProperty(root, document, property)) { + counter++; + //System.out.println("write6, counter: " + counter); + LOG.info("C#:write6, counter: " + counter); + } + } + + //System.out.println("write7"); + LOG.info("C#:write7"); + + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + if(prettyPrint){ + //System.out.println("write8"); + LOG.info("C#:write8"); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); + } + DOMSource source = new DOMSource(document); + StreamResult result = new StreamResult(out); + + //System.out.println("write9"); + LOG.info("C#:write9"); + + transformer.transform(source, result); + + //System.out.println("write10"); + LOG.info("C#:write10"); + + return counter; + } catch (ParserConfigurationException e) { + throw new IOException(e); + } catch (TransformerConfigurationException e) { + throw new IOException(e); + } catch (TransformerException e) { + throw new IOException(e); + } finally{ + out.close(); + } + } + + + private boolean writeProperty(Element root, Document document, Property property) throws IOException { + + //System.out.println("writeProperty1"); + LOG.info("C#:writeProperty1"); + + String value = property.getValue(); + + //System.out.println("writeProperty2, value of property: " + value); + LOG.info("C#:writeProperty2, value of property: " + value); + + if(!isFilled(value)) { + //System.out.println("writeProperty3, value not filled"); + LOG.info("C#:writeProperty3, value not filled"); + return false; + } + + if (false == writeCommentAndAnnotations(root, document, property)) { + //System.out.println("writeProperty4 call to writeString"); + LOG.info("C#:writeProperty4 call to writeString"); + writeString(root,document,property); // property was created by a translatable xml-element. So write back the translation + } + return true; + } + + + private void writeString(Element root, Document document, Property property) { + //System.out.println("writeString1"); + LOG.info("C#:writeString1"); + Element data = document.createElement(DATA); + //System.out.println("writeString2"); + LOG.info("C#:writeString2"); + root.appendChild(data); + + String key = property.getKey(); + //System.out.println("writeString3, key: " + key); + LOG.info("C#:writeString3, key: " + key); + data.setAttribute(NAME_ATTRIBUTE, key); + + String value = property.getValue(); + //System.out.println("writeString4, value: " + value); + LOG.info("C#:writeString4, value: " + value); + data.setTextContent(encode(value)); + } + + + private String encode(String textContent) { + if(textContent==null) { + //System.out.println("encode1, textContent is null"); + LOG.info("C#:encode1, textContent is null"); + return null; + } + + textContent = textContent.replace("'", "\\'").replace("\"", "\\\""); + //System.out.println("encode2, textContent: " + textContent); + LOG.info("C#:encode2, textContent: " + textContent); + + return textContent; + } + + + /** + * + * @param root + * @param document + * @param property + * @return = true: non translatable property + * = false: translatable property, the caller has to care for the property + * @throws IOException + */ + private boolean writeCommentAndAnnotations(Element root, Document document, Property property) throws IOException { + + boolean bReturn = false; + + //System.out.println("writeCommentAndAnnotations1, property: " + property.toString()); + LOG.info("C#:writeCommentAndAnnotations1, property: " + property.toString()); + + if(property.eIsSet(PropertiesPackage.Literals.PROPERTY__COMMENT) || property.getAnnotations().size()>0) + { + //System.out.println("writeCommentAndAnnotations2"); + LOG.info("C#:writeCommentAndAnnotations2"); + + String comment = property.getCommentWithoutAnnotations(); + + //System.out.println("writeCommentAndAnnotations3, comment: " + comment); + LOG.info("C#:writeCommentAndAnnotations3, comment: " + comment); + + StringBuilder builder = new StringBuilder(); + + PropertyAnnotation nonTranslatable = property.findAnnotation(PropertyAnnotations.NON_TRANSLATABLE); + if (null != nonTranslatable) { + bReturn = true; // this property is non-translatable + } + + if(builder.length()>0 && comment!=null && comment.length()>0 ) + { + builder.append("\n"); + } + builder.append(comment); + + String stringFromComment = builder.toString(); + + //System.out.println("writeCommentAndAnnotations3, stringFromComment: " + stringFromComment); + LOG.info("C#:writeCommentAndAnnotations3, stringFromComment: " + stringFromComment); + + Comment node = document.createComment(stringFromComment); + + //System.out.println("writeCommentAndAnnotations4, node: " + node.toString()); + LOG.info("C#:writeCommentAndAnnotations4, node: " + node.toString()); + + root.appendChild(node); + } + return bReturn; + } + + + private boolean isFilled(String s){ + //System.out.println("isFilled1, s: " + s); + LOG.info("C#:isFilled1, s: " + s); + return s!=null && !s.isEmpty(); + } +} diff --git a/csharp/src/main/java/org/jabylon/csharp/CSharpScanner.java b/csharp/src/main/java/org/jabylon/csharp/CSharpScanner.java new file mode 100644 index 0000000..06e04a1 --- /dev/null +++ b/csharp/src/main/java/org/jabylon/csharp/CSharpScanner.java @@ -0,0 +1,298 @@ +/** + * + */ +package org.jabylon.csharp; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Service; +import org.apache.wicket.util.crypt.StringUtils; +import org.eclipse.emf.common.util.URI; +import org.jabylon.properties.PropertiesFactory; +import org.jabylon.properties.PropertiesPackage; +import org.jabylon.properties.ScanConfiguration; +import org.jabylon.properties.types.PropertyConverter; +import org.jabylon.properties.types.PropertyScanner; +import org.jabylon.properties.types.impl.AbstractPropertyScanner; +//import org.jabylon.security.CommonPermissions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * adds support for the C# xml format. + * + * @author c.gromer@seeburger.de + * + */ +@Component(enabled=true,immediate=true) +@Service +public class CSharpScanner implements PropertyScanner { + + @Property(name=PropertyScanner.TYPE, value="CSHARP") + public static final String TYPE = "CSHARP"; + + private static final String[] DEFAULT_EXCLUDES = {}; + private static final String[] DEFAULT_INCLUDES = {"**/*.resx"}; + + private static final Logger LOG = LoggerFactory.getLogger(CSharpScanner.class); + + public CSharpScanner() { + LOG.info("C#:CSharpScanner1"); + } + + + @Override + public String[] getDefaultIncludes() { + + LOG.info("C#:getDefaultIncludes1"); + + return DEFAULT_INCLUDES; + } + + /* (non-Javadoc) + * @see org.jabylon.properties.types.PropertyScanner#getDefaultExcludes() + */ + @Override + public String[] getDefaultExcludes() { + + LOG.info("C#:getDefaultExcludes1"); + + return DEFAULT_EXCLUDES; + } + + + @Override + public boolean isTemplate(File propertyFile, String masterLocale) { + + LOG.info("C#:isTemplate1"); + LOG.info("C#:isTemplate2 propertyFile: " + propertyFile.getName() + " masterLocale: " + masterLocale); + + if(isResourceFile(propertyFile) && countingPeriodsFullfillsTemplateFileCondition(propertyFile)) { + return true; + } + return false; + } + + + @Override + public boolean isTranslation(File propertyFile, ScanConfiguration config) { + + LOG.info("C#:isTranslation1"); + + String fileName = propertyFile.getName(); + + LOG.info("C#:isTranslation2 fileName: " + fileName); + + if (isResourceFile(propertyFile) && (countingPeriodsFullfillsTranslationFileCondition(propertyFile))) { + return true; + } + return false; + } + + + private boolean countingPeriodsFullfillsTranslationFileCondition(File propertyFile) { + //E.g.: Resources.nl.resx is a translation file, Resources.resx is a template file + LOG.info("C#:countingPeriodsFullfillsTranslationFileCondition1: propertyFile: " + propertyFile.getName()); + + if (2 == propertyFile.getName().length() - propertyFile.getName().replace(".","").length()) { + LOG.info("C#:countingPeriodsFullfillsTranslationFileCondition2: translation file" ); + return true; + } + + LOG.info("C#:countingPeriodsFullfillsTranslationFileCondition3: no translation file" ); + return false; + } + + + private boolean countingPeriodsFullfillsTemplateFileCondition(File propertyFile) { + //E.g.: Resources.nl.resx is a translation file, Resources.resx is a template file + + LOG.info("C#:countingPeriodsFullfillsTemplateFileCondition1: propertyFile: " + propertyFile.getName()); + + if (1 == propertyFile.getName().length() - propertyFile.getName().replace(".","").length()) { + LOG.info("C#:countingPeriodsFullfillsTemplateFileCondition2: template" ); + return true; + } + + LOG.info("C#:countingPeriodsFullfillsTemplateFileCondition3: no template" ); + return false; + + // did not work: + /*if (2 == propertyFile.getName().split(".", -1).length) { + LOG.info("C#:countingPeriodsFullfillsTemplateFileCondition3: template" ); + return true; + } + LOG.info("C#:countingPeriodsFullfillsTemplateFileCondition4: no template" ); + return false;*/ + } + + + private boolean isResourceFile(File propertyFile) { + + LOG.info("C#:isResourceFile1" ); + LOG.info("C#:isResourceFile2, propertyFile: " + propertyFile.getName()); + + if(propertyFile.getName().endsWith(".resx")) { + LOG.info("C#:isResourceFile3: resource file" ); + return true; + } + LOG.info("C#:isResourceFile4: no resource file" ); + return false; + } + + + @Override + public File findTemplate(File propertyFile, ScanConfiguration config) { + + LOG.info("C#:findTemplate1"); + + if (isTranslation(propertyFile, config)) { + String fileName = propertyFile.getName(); + LOG.info("C#:findTemplate2: fileName: " + fileName ); + // e.g.: Resources.nl.resx + String[] strings = fileName.split(".", -1); + if (3 == strings.length) { + String templateFile = strings[0] + "." + strings[2]; // e.g.: Resources.resx + LOG.info("C#:findTemplate3: templateFile: " + templateFile); + return new File(templateFile); + } + } + LOG.info("C#:findTemplate4"); + return null; + } + + + @Override + public Map findTranslations(File template, ScanConfiguration config) { + + LOG.info("C#:findTranslations1"); + + if (isTemplate(template, "")) { + String folder = template.getParent(); + LOG.info("C#:findTranslations2: folder: " + folder); + File[] files = new File(folder).listFiles(); + Map translations = new HashMap(); + for (File file : files) { + LOG.info("C#:findTranslations3: file: " + file.getName()); + if (isTranslation(file, config)) { + LOG.info("C#:findTranslations4: is translation"); + translations.put(getLocale(file), file); + } + } + if (!translations.isEmpty()) { + return translations; + } + } + return null; + } + + + @Override + public File computeTranslationPath(File template, Locale templateLocale, Locale translationLocale) { + LOG.info("C#:computeTranslationPath1, template:" + template.getName() + " template.getPath: " + template.getPath()); + File folder = template.getParentFile(); // template and translation files reside in the same folder + LOG.info("C#:computeTranslationPath2, folder: " + folder.getName()); + + LOG.info("C#:computeTranslationPath2.1, folder.getPath: " + folder.getPath()); + LOG.info("C#:computeTranslationPath2.2, folder.getParent: " + folder.getParent()); + + return folder; + } + + + @Override + public Locale getLocale(File propertyFile) { + + LOG.info("C#:getLocale1, propertyFile: " + propertyFile); + + String propFileName = propertyFile.getName(); // e.g.: dialog.resx (template file), dialog.nl.resx (translation file) + + LOG.info("C#:getLocale2, propFileName: " + propFileName); + + String[] splittedPropFileName = propFileName.split("\\."); + + String language = ""; // "en" in "en_US" + String culture = ""; // "US" in "en_US" + boolean isTemplate = false; + + if (1 == splittedPropFileName.length) { + LOG.info("C#:getLocale3, obviously no property file: " + propFileName); + } + else if (1 < splittedPropFileName.length) { + LOG.info("C#:getLocale4, splittedPropFileName.length: " + splittedPropFileName.length); + String extension = splittedPropFileName[splittedPropFileName.length-1]; + + if (2 == splittedPropFileName.length) { + //e.g.: dialog.resx (template file) + } + else { + if (5 == splittedPropFileName[splittedPropFileName.length-2].length()) { + if ("_" == splittedPropFileName[splittedPropFileName.length-2].substring(2,3)) { + LOG.info("C#:getLocale5, language + culture "); + language = splittedPropFileName[splittedPropFileName.length-2].substring(0,2); + culture = splittedPropFileName[splittedPropFileName.length-2].substring(3,5); + } + else { + LOG.info("C#:getLocale6, template "); + isTemplate = true; + } + } else if (2 == splittedPropFileName[splittedPropFileName.length-2].length()) { + LOG.info("C#:getLocale7, only language "); + language = splittedPropFileName[splittedPropFileName.length-2]; + } + else { + LOG.info("C#:getLocale8, template "); + isTemplate = true; + } + } + } + + Locale loc = null; + + if (true == isTemplate) { + LOG.info("C#:getLocale9, isTemplate"); + loc = new Locale("en", "US"); // In C# we actually translate from American English + } + else if (0 < language.length()){ + LOG.info("C#:getLocale10, isTranslation File, language: " + language + " culture: " + culture); + loc = new Locale(language, culture); + } + return loc; + } + + + @Override + public boolean isBilingual() { + + LOG.info("C#:isBilingual1"); + + return false; + } + + + @Override + public PropertyConverter createConverter(URI resource) { + + LOG.info("C#:createConverter1, resource: " + resource.path()); + + return new CSharpConverter(resource, true); + } + + + @Override + public String getEncoding() { + + LOG.info("C#:getEncoding1"); + + return "UTF-8"; + } +} diff --git a/csharp/src/test/java/org/jabylon/csharp/AppTest.java b/csharp/src/test/java/org/jabylon/csharp/AppTest.java new file mode 100644 index 0000000..8a9ea3c --- /dev/null +++ b/csharp/src/test/java/org/jabylon/csharp/AppTest.java @@ -0,0 +1,38 @@ +package org.jabylon.csharp; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} From bc72c9c49f662c5e3c3eee4849cc2af9478e0c01 Mon Sep 17 00:00:00 2001 From: "c.gromer" Date: Tue, 7 May 2019 09:52:05 +0200 Subject: [PATCH 02/15] updated --- .../org/jabylon/csharp/CSharpConverter.java | 161 +++++++++--------- .../org/jabylon/csharp/CSharpScanner.java | 112 ++++++------ 2 files changed, 132 insertions(+), 141 deletions(-) diff --git a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java index 5bc4caa..2518c4d 100644 --- a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java +++ b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java @@ -1,6 +1,5 @@ package org.jabylon.csharp; -import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -31,6 +30,7 @@ import org.w3c.dom.Comment; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; @@ -60,12 +60,11 @@ public class CSharpConverter implements PropertyConverter{ public CSharpConverter(URI resourceLocation, boolean prettyPrint) { this.uri = resourceLocation; this.prettyPrint = prettyPrint; - //System.out.println("CSharpConverter1"); LOG.info("C#:CSharpConverter1"); - } + @Override public PropertyFile load(InputStream in, String encoding) throws IOException { // TODO Auto-generated method stub @@ -82,28 +81,20 @@ public PropertyFile load(InputStream in, String encoding) throws IOException { Node firstNode = result.getChildNodes().item(0); if(firstNode.getNodeType()==Node.COMMENT_NODE) { String nodeValue = firstNode.getNodeValue(); - //System.out.println("load1, value first node: " + nodeValue); LOG.info("C#:load2, value first node: " + nodeValue); file.setLicenseHeader(nodeValue); } Node resources = result.getDocumentElement(); - //System.out.println("load2, resources, TextContent: " + resources.getTextContent()); LOG.info("C#:load3, resources, TextContent: " + resources.getTextContent()); - // blueprint from Android: - /*if(!ROOT_NODE.equals(resources.getNodeName())) { - LOG.error("C#:XML does not start with "+ROOT_NODE+" but "+resources.getLocalName()+". Location: "+uri); - return file; - }*/ - NodeList nodes = resources.getChildNodes(); for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); - //System.out.println("load3, child node_" + i + " Name: " + node.getNodeName() + " Value: " + node.getNodeValue()); - LOG.info("C#:load4, child node_" + i + " Name: " + node.getNodeName() + " Value: " + node.getNodeValue()); + LOG.info("C#:load4, child node_" + i + " Name: " + node.getNodeName() + " Value: " + node.getNodeValue() + " Content:" + node.getTextContent() + " Type: " + node.getNodeType()); + loadNode(node,file); } return file; @@ -130,75 +121,114 @@ private void loadNode(Node node, PropertyFile file) { Property property = PropertiesFactory.eINSTANCE.createProperty(); String name = node.getNodeName(); - //System.out.println("loadNode1, Name: " + name); LOG.info("C#:loadNode1, Name: " + name); - if(name.equals(DATA)){ - loadString(node, property); - } - else { - //System.out.println("loadNode2, error, Invalid tag "+name+" found in " + uri + " Skipping"); - LOG.error("C#:loadNode2, Invalid tag "+name+" found in " + uri + " Skipping"); + if (false == loadString(node, property)) { + LOG.info("C#:loadNode2, node not appropiate"); return; } + + // for analysis purpose + EList eListPropAnn = property.getAnnotations(); + int nCount = eListPropAnn.size(); + LOG.info("C#:loadNode3, was saved? nCount: " + nCount); + property.setComment(comment); + + LOG.info("C#:loadNode4, comment: " + comment); comment = null; file.getProperties().add(property); - //System.out.println("loadNode3, end"); - LOG.info("C#:loadNode3, end"); + LOG.info("C#:loadNode5, comment: " + comment); } - private void loadString(Node node, Property property) { + private boolean hasTypeAttribute(Node node) { + boolean hasTypeAttribute = false; + + NamedNodeMap namedNodeMap = node.getAttributes(); + if (null != namedNodeMap) { + LOG.info("C#:hasTypeAttribute1, namedNodeMap.toString: " + namedNodeMap.toString()); + for (int j=0; j eListPropAnn = property.getAnnotations(); + int nCount = eListPropAnn.size(); + LOG.info("C#:loadString7, nCount annotations before adding: " + nCount); + eListPropAnn.add(annotation); + + nCount = eListPropAnn.size(); + LOG.info("C#:loadString8, nCount annotations after adding: " + nCount + " not provided for translation"); } else { // provided for translation - //System.out.println("loadString4, provided for translation "); - LOG.info("C#:loadString4, provided for translation "); - property.setValue(decode(textContentName)); + LOG.info("C#:loadString10, provided for translation "); } + property.setValue(decode(textContentNode)); + return true; } - private Boolean isCandidateForTranslation(String key) { + private Boolean isCandidateForTranslation(String key, String nodeName) { Boolean bReturn = false; - //System.out.println("isCandidateForTranslation1, key: " + key); - LOG.info("C#:isCandidateForTranslation1, key: " + key); + LOG.info("C#:isCandidateForTranslation1, key: " + key + " nodeName: " + nodeName); - if (key.contains(".Text\"")) { - bReturn = true; + if (key.endsWith(".Text")) { + LOG.info("C#:isCandidateForTranslation2, key ends with .Text"); + if(nodeName.equals(DATA)){ + LOG.info("C#:isCandidateForTranslation3, nodeName equals DATA"); + bReturn = true; + } } - - //System.out.println("isCandidateForTranslation2, bReturn: " + bReturn); - LOG.info("C#:isCandidateForTranslation2, bReturn: " + bReturn); + LOG.info("C#:isCandidateForTranslation4, bReturn: " + bReturn); return bReturn; } @@ -210,7 +240,6 @@ private Boolean isCandidateForTranslation(String key) { */ private String decode(String textContent) { if(textContent==null) { - //System.out.println("decode1, textContent is null" ); LOG.info("C#:decode1, textContent is null" ); return null; } @@ -219,7 +248,7 @@ private String decode(String textContent) { /*if(textContent.startsWith("\"") && textContent.endsWith("\"")) return textContent.substring(1, textContent.length()-1); return textContent.replace("\\'", "'");*/ - //System.out.println("decode1, textContent: " + textContent); + LOG.info("C#:decode1, textContent: " + textContent); return textContent; } @@ -228,46 +257,38 @@ private String decode(String textContent) { @Override public int write(OutputStream out, PropertyFile file, String encoding) throws IOException { try { - //System.out.println("write1, file:" + file.toString() + " encoding: " + encoding); LOG.info("C#:write1, file:" + file.toString() + " encoding: " + encoding); int counter = 0; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); Document document = factory.newDocumentBuilder().newDocument(); - //System.out.println("write2"); LOG.info("C#:write2"); if(isFilled(file.getLicenseHeader())) { - //System.out.println("write3"); LOG.info("C#:write3"); document.appendChild(document.createComment(file.getLicenseHeader())); } - //System.out.println("write4"); LOG.info("C#:write4"); Element root = document.createElement(ROOT_NODE); document.appendChild(root); EList properties = file.getProperties(); for (Property property : properties) { - //System.out.println("write5, property: " + property.toString()); LOG.info("C#:write5, property: " + property.toString()); if(writeProperty(root, document, property)) { counter++; - //System.out.println("write6, counter: " + counter); LOG.info("C#:write6, counter: " + counter); } } - //System.out.println("write7"); LOG.info("C#:write7"); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); if(prettyPrint){ - //System.out.println("write8"); LOG.info("C#:write8"); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); @@ -275,12 +296,10 @@ public int write(OutputStream out, PropertyFile file, String encoding) throws IO DOMSource source = new DOMSource(document); StreamResult result = new StreamResult(out); - //System.out.println("write9"); LOG.info("C#:write9"); transformer.transform(source, result); - //System.out.println("write10"); LOG.info("C#:write10"); return counter; @@ -298,22 +317,18 @@ public int write(OutputStream out, PropertyFile file, String encoding) throws IO private boolean writeProperty(Element root, Document document, Property property) throws IOException { - //System.out.println("writeProperty1"); LOG.info("C#:writeProperty1"); String value = property.getValue(); - //System.out.println("writeProperty2, value of property: " + value); LOG.info("C#:writeProperty2, value of property: " + value); if(!isFilled(value)) { - //System.out.println("writeProperty3, value not filled"); LOG.info("C#:writeProperty3, value not filled"); return false; } if (false == writeCommentAndAnnotations(root, document, property)) { - //System.out.println("writeProperty4 call to writeString"); LOG.info("C#:writeProperty4 call to writeString"); writeString(root,document,property); // property was created by a translatable xml-element. So write back the translation } @@ -322,20 +337,16 @@ private boolean writeProperty(Element root, Document document, Property property private void writeString(Element root, Document document, Property property) { - //System.out.println("writeString1"); LOG.info("C#:writeString1"); Element data = document.createElement(DATA); - //System.out.println("writeString2"); LOG.info("C#:writeString2"); root.appendChild(data); String key = property.getKey(); - //System.out.println("writeString3, key: " + key); LOG.info("C#:writeString3, key: " + key); data.setAttribute(NAME_ATTRIBUTE, key); String value = property.getValue(); - //System.out.println("writeString4, value: " + value); LOG.info("C#:writeString4, value: " + value); data.setTextContent(encode(value)); } @@ -343,13 +354,11 @@ private void writeString(Element root, Document document, Property property) { private String encode(String textContent) { if(textContent==null) { - //System.out.println("encode1, textContent is null"); LOG.info("C#:encode1, textContent is null"); return null; } textContent = textContent.replace("'", "\\'").replace("\"", "\\\""); - //System.out.println("encode2, textContent: " + textContent); LOG.info("C#:encode2, textContent: " + textContent); return textContent; @@ -369,17 +378,14 @@ private boolean writeCommentAndAnnotations(Element root, Document document, Prop boolean bReturn = false; - //System.out.println("writeCommentAndAnnotations1, property: " + property.toString()); - LOG.info("C#:writeCommentAndAnnotations1, property: " + property.toString()); + LOG.info("C#:writeCommentAndAnnotations1, property: " + property.toString() + " property.getAnnotations().size(): " + property.getAnnotations().size()); if(property.eIsSet(PropertiesPackage.Literals.PROPERTY__COMMENT) || property.getAnnotations().size()>0) { - //System.out.println("writeCommentAndAnnotations2"); LOG.info("C#:writeCommentAndAnnotations2"); String comment = property.getCommentWithoutAnnotations(); - //System.out.println("writeCommentAndAnnotations3, comment: " + comment); LOG.info("C#:writeCommentAndAnnotations3, comment: " + comment); StringBuilder builder = new StringBuilder(); @@ -387,6 +393,7 @@ private boolean writeCommentAndAnnotations(Element root, Document document, Prop PropertyAnnotation nonTranslatable = property.findAnnotation(PropertyAnnotations.NON_TRANSLATABLE); if (null != nonTranslatable) { bReturn = true; // this property is non-translatable + LOG.info("C#:writeCommentAndAnnotations4, property has NON_TRANSLATABLE annotation " + comment); } if(builder.length()>0 && comment!=null && comment.length()>0 ) @@ -397,12 +404,10 @@ private boolean writeCommentAndAnnotations(Element root, Document document, Prop String stringFromComment = builder.toString(); - //System.out.println("writeCommentAndAnnotations3, stringFromComment: " + stringFromComment); - LOG.info("C#:writeCommentAndAnnotations3, stringFromComment: " + stringFromComment); + LOG.info("C#:writeCommentAndAnnotations5, stringFromComment: " + stringFromComment); Comment node = document.createComment(stringFromComment); - //System.out.println("writeCommentAndAnnotations4, node: " + node.toString()); LOG.info("C#:writeCommentAndAnnotations4, node: " + node.toString()); root.appendChild(node); @@ -410,9 +415,7 @@ private boolean writeCommentAndAnnotations(Element root, Document document, Prop return bReturn; } - private boolean isFilled(String s){ - //System.out.println("isFilled1, s: " + s); LOG.info("C#:isFilled1, s: " + s); return s!=null && !s.isEmpty(); } diff --git a/csharp/src/main/java/org/jabylon/csharp/CSharpScanner.java b/csharp/src/main/java/org/jabylon/csharp/CSharpScanner.java index 06e04a1..4ca5867 100644 --- a/csharp/src/main/java/org/jabylon/csharp/CSharpScanner.java +++ b/csharp/src/main/java/org/jabylon/csharp/CSharpScanner.java @@ -52,9 +52,7 @@ public CSharpScanner() { @Override public String[] getDefaultIncludes() { - LOG.info("C#:getDefaultIncludes1"); - return DEFAULT_INCLUDES; } @@ -63,16 +61,13 @@ public String[] getDefaultIncludes() { */ @Override public String[] getDefaultExcludes() { - LOG.info("C#:getDefaultExcludes1"); - return DEFAULT_EXCLUDES; } @Override public boolean isTemplate(File propertyFile, String masterLocale) { - LOG.info("C#:isTemplate1"); LOG.info("C#:isTemplate2 propertyFile: " + propertyFile.getName() + " masterLocale: " + masterLocale); @@ -85,11 +80,8 @@ public boolean isTemplate(File propertyFile, String masterLocale) { @Override public boolean isTranslation(File propertyFile, ScanConfiguration config) { - LOG.info("C#:isTranslation1"); - String fileName = propertyFile.getName(); - LOG.info("C#:isTranslation2 fileName: " + fileName); if (isResourceFile(propertyFile) && (countingPeriodsFullfillsTranslationFileCondition(propertyFile))) { @@ -107,7 +99,6 @@ private boolean countingPeriodsFullfillsTranslationFileCondition(File propertyFi LOG.info("C#:countingPeriodsFullfillsTranslationFileCondition2: translation file" ); return true; } - LOG.info("C#:countingPeriodsFullfillsTranslationFileCondition3: no translation file" ); return false; } @@ -116,23 +107,16 @@ private boolean countingPeriodsFullfillsTranslationFileCondition(File propertyFi private boolean countingPeriodsFullfillsTemplateFileCondition(File propertyFile) { //E.g.: Resources.nl.resx is a translation file, Resources.resx is a template file + boolean bReturn = false; LOG.info("C#:countingPeriodsFullfillsTemplateFileCondition1: propertyFile: " + propertyFile.getName()); if (1 == propertyFile.getName().length() - propertyFile.getName().replace(".","").length()) { LOG.info("C#:countingPeriodsFullfillsTemplateFileCondition2: template" ); - return true; + bReturn = true; } - LOG.info("C#:countingPeriodsFullfillsTemplateFileCondition3: no template" ); - return false; - - // did not work: - /*if (2 == propertyFile.getName().split(".", -1).length) { - LOG.info("C#:countingPeriodsFullfillsTemplateFileCondition3: template" ); - return true; - } - LOG.info("C#:countingPeriodsFullfillsTemplateFileCondition4: no template" ); - return false;*/ + LOG.info("C#:countingPeriodsFullfillsTemplateFileCondition3: bReturn: " + bReturn); + return bReturn; } @@ -140,13 +124,15 @@ private boolean isResourceFile(File propertyFile) { LOG.info("C#:isResourceFile1" ); LOG.info("C#:isResourceFile2, propertyFile: " + propertyFile.getName()); + + boolean isResFile = false; if(propertyFile.getName().endsWith(".resx")) { LOG.info("C#:isResourceFile3: resource file" ); - return true; + isResFile = true; } - LOG.info("C#:isResourceFile4: no resource file" ); - return false; + LOG.info("C#:isResourceFile4: isResFile: " + isResFile ); + return isResFile; } @@ -174,26 +160,44 @@ public File findTemplate(File propertyFile, ScanConfiguration config) { @Override public Map findTranslations(File template, ScanConfiguration config) { - LOG.info("C#:findTranslations1"); + LOG.info("C#:findTranslations1, template: " + template.getName()); if (isTemplate(template, "")) { + + // instead of using org.apache.commons + String templateWithoutExtension = getFirstPart(template); + String folder = template.getParent(); LOG.info("C#:findTranslations2: folder: " + folder); File[] files = new File(folder).listFiles(); Map translations = new HashMap(); for (File file : files) { LOG.info("C#:findTranslations3: file: " + file.getName()); - if (isTranslation(file, config)) { - LOG.info("C#:findTranslations4: is translation"); - translations.put(getLocale(file), file); + if (templateWithoutExtension.equals(getFirstPart(file))) { + LOG.info("C#:findTranslations4: first part matches"); + if (isTranslation(file, config)) { + LOG.info("C#:findTranslations5: is translation"); + translations.put(getLocale(file), file); + } } } - if (!translations.isEmpty()) { - return translations; - } + return translations; } return null; } + + private String getFirstPart(File file) { + String firstPart = ""; + String fileParts[] = file.getName().split("\\."); + + if (0 < fileParts.length) { + firstPart = fileParts[0]; + } + LOG.info("C#:getFirstPart, return: " + firstPart); + return(firstPart); + } + + @Override @@ -211,11 +215,8 @@ public File computeTranslationPath(File template, Locale templateLocale, Locale @Override public Locale getLocale(File propertyFile) { - LOG.info("C#:getLocale1, propertyFile: " + propertyFile); - String propFileName = propertyFile.getName(); // e.g.: dialog.resx (template file), dialog.nl.resx (translation file) - LOG.info("C#:getLocale2, propFileName: " + propFileName); String[] splittedPropFileName = propFileName.split("\\."); @@ -229,42 +230,35 @@ public Locale getLocale(File propertyFile) { } else if (1 < splittedPropFileName.length) { LOG.info("C#:getLocale4, splittedPropFileName.length: " + splittedPropFileName.length); - String extension = splittedPropFileName[splittedPropFileName.length-1]; if (2 == splittedPropFileName.length) { //e.g.: dialog.resx (template file) + isTemplate = true; } - else { - if (5 == splittedPropFileName[splittedPropFileName.length-2].length()) { - if ("_" == splittedPropFileName[splittedPropFileName.length-2].substring(2,3)) { - LOG.info("C#:getLocale5, language + culture "); - language = splittedPropFileName[splittedPropFileName.length-2].substring(0,2); - culture = splittedPropFileName[splittedPropFileName.length-2].substring(3,5); - } - else { - LOG.info("C#:getLocale6, template "); - isTemplate = true; - } - } else if (2 == splittedPropFileName[splittedPropFileName.length-2].length()) { - LOG.info("C#:getLocale7, only language "); + else if (3 == splittedPropFileName.length){ + if (2 == splittedPropFileName[splittedPropFileName.length-2].length()) { + LOG.info("C#:getLocale6, only language "); language = splittedPropFileName[splittedPropFileName.length-2]; } else { - LOG.info("C#:getLocale8, template "); - isTemplate = true; + LOG.info("C#:getLocale7, splittedPropFileName[splittedPropFileName.length-2].substring(2,3): " + splittedPropFileName[splittedPropFileName.length-2].substring(2,3)); + if ("-".equals(splittedPropFileName[splittedPropFileName.length-2].substring(2,3))) { + LOG.info("C#:getLocale8, language + culture "); + language = splittedPropFileName[splittedPropFileName.length-2].substring(0,2); + culture = splittedPropFileName[splittedPropFileName.length-2].substring(3); + } } } } Locale loc = null; - if (true == isTemplate) { - LOG.info("C#:getLocale9, isTemplate"); - loc = new Locale("en", "US"); // In C# we actually translate from American English - } - else if (0 < language.length()){ - LOG.info("C#:getLocale10, isTranslation File, language: " + language + " culture: " + culture); - loc = new Locale(language, culture); + if (false == isTemplate) { + LOG.info("C#:getLocale11, no Template"); + if (0 < language.length()){ + LOG.info("C#:getLocale12, isTranslation File, language: " + language + " culture: " + culture); + loc = new Locale(language, culture); + } } return loc; } @@ -272,27 +266,21 @@ else if (0 < language.length()){ @Override public boolean isBilingual() { - LOG.info("C#:isBilingual1"); - return false; } @Override public PropertyConverter createConverter(URI resource) { - LOG.info("C#:createConverter1, resource: " + resource.path()); - return new CSharpConverter(resource, true); } @Override public String getEncoding() { - LOG.info("C#:getEncoding1"); - return "UTF-8"; } } From fd87d174fd5253a4a2f34a61ef93f59db4be558e Mon Sep 17 00:00:00 2001 From: "c.gromer" Date: Thu, 9 May 2019 16:30:00 +0200 Subject: [PATCH 03/15] non translatable text treated well now --- .../org/jabylon/csharp/CSharpConverter.java | 115 ++++++++++++------ 1 file changed, 80 insertions(+), 35 deletions(-) diff --git a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java index 2518c4d..7125d09 100644 --- a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java +++ b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java @@ -3,6 +3,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.StringWriter; +import java.io.StringReader; + import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -34,6 +37,7 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; +import org.xml.sax.InputSource; public class CSharpConverter implements PropertyConverter{ @@ -69,7 +73,7 @@ public CSharpConverter(URI resourceLocation, boolean prettyPrint) { public PropertyFile load(InputStream in, String encoding) throws IOException { // TODO Auto-generated method stub - LOG.info("C#:load1, in: " + in.toString()); + LOG.info("C#:load0, in: " + in.toString()); try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); @@ -78,25 +82,53 @@ public PropertyFile load(InputStream in, String encoding) throws IOException { Document result = builder.parse(in); PropertyFile file = PropertiesFactory.eINSTANCE.createPropertyFile(); - Node firstNode = result.getChildNodes().item(0); - if(firstNode.getNodeType()==Node.COMMENT_NODE) { - String nodeValue = firstNode.getNodeValue(); - LOG.info("C#:load2, value first node: " + nodeValue); - file.setLicenseHeader(nodeValue); - } - Node resources = result.getDocumentElement(); - LOG.info("C#:load3, resources, TextContent: " + resources.getTextContent()); + LOG.info("C#:load2, resources, TextContent: " + resources.getTextContent()); + + LOG.info("C#:load3, result.getTextContent: " + result.getTextContent()); NodeList nodes = resources.getChildNodes(); + + int nodesLength = nodes.getLength(); + LOG.info("C#:load4, nodesLength: " + nodesLength); - for (int i = 0; i < nodes.getLength(); i++) { + for (int i = nodesLength-1; i >= 0; i--) { Node node = nodes.item(i); - LOG.info("C#:load4, child node_" + i + " Name: " + node.getNodeName() + " Value: " + node.getNodeValue() + " Content:" + node.getTextContent() + " Type: " + node.getNodeType()); + LOG.info("C#:load5, child node_" + i + " Name: " + node.getNodeName() + " Value: " + node.getNodeValue() + " Content:" + node.getTextContent() + " Type: " + node.getNodeType()); - loadNode(node,file); + if (true == loadNode(node,file)) { + resources.removeChild(node); + LOG.info("C#:load6, child node_" + i + " removed. nodes.getLength afterwards: " + nodes.getLength()); + } } + + // Build a new Document without the nodes being treated by Jabylon + DocumentBuilderFactory docBuilderFact = DocumentBuilderFactory.newInstance(); + docBuilderFact.setNamespaceAware(true); + DocumentBuilder docBuilder = docBuilderFact.newDocumentBuilder(); + Document newDoc = docBuilder.newDocument(); + Node importedNode = newDoc.importNode(resources, true); + newDoc.appendChild(importedNode); + + StringWriter sw = new StringWriter(); + String resFileAsString = ""; + + Node firstNode = newDoc.getChildNodes().item(0); + + try { + Transformer t = TransformerFactory.newInstance().newTransformer(); + t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + t.setOutputProperty(OutputKeys.INDENT, "yes"); + t.transform(new DOMSource(firstNode), new StreamResult(sw)); + resFileAsString = sw.toString(); + LOG.info("C#:load7, resFileAsString: " + resFileAsString); + } catch (TransformerException te) { + LOG.error("C#:load8, nodeToString Transformer exception: ", te); + } + + file.setLicenseHeader(resFileAsString); + return file; } catch (SAXException e) { @@ -109,14 +141,9 @@ public PropertyFile load(InputStream in, String encoding) throws IOException { } - private void loadNode(Node node, PropertyFile file) { - //Android as a blueprint: - /*if(node.getNodeType()==Node.TEXT_NODE) - return; - if(node.getNodeType()==Node.COMMENT_NODE) { - comment = node.getNodeValue(); - return; - }*/ + private boolean // = true: node is provided for translation + // = false: node is not provided for translation and therefore transferred to licenseHeader for not being lost + loadNode(Node node, PropertyFile file) { Property property = PropertiesFactory.eINSTANCE.createProperty(); String name = node.getNodeName(); @@ -125,7 +152,7 @@ private void loadNode(Node node, PropertyFile file) { if (false == loadString(node, property)) { LOG.info("C#:loadNode2, node not appropiate"); - return; + return false; } // for analysis purpose @@ -133,13 +160,13 @@ private void loadNode(Node node, PropertyFile file) { int nCount = eListPropAnn.size(); LOG.info("C#:loadNode3, was saved? nCount: " + nCount); - property.setComment(comment); LOG.info("C#:loadNode4, comment: " + comment); comment = null; file.getProperties().add(property); LOG.info("C#:loadNode5, comment: " + comment); + return true; } @@ -216,8 +243,8 @@ private boolean loadString(Node node, Property property) { } - private Boolean isCandidateForTranslation(String key, String nodeName) { - Boolean bReturn = false; + private boolean isCandidateForTranslation(String key, String nodeName) { + boolean bReturn = false; LOG.info("C#:isCandidateForTranslation1, key: " + key + " nodeName: " + nodeName); @@ -261,46 +288,64 @@ public int write(OutputStream out, PropertyFile file, String encoding) throws IO int counter = 0; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - Document document = factory.newDocumentBuilder().newDocument(); + DocumentBuilder documentBuilder = factory.newDocumentBuilder(); + Document document = documentBuilder.newDocument(); LOG.info("C#:write2"); + + String licenseHeader = file.getLicenseHeader(); - if(isFilled(file.getLicenseHeader())) + if(isFilled(licenseHeader)) { - LOG.info("C#:write3"); - document.appendChild(document.createComment(file.getLicenseHeader())); + LOG.info("C#:write3, licenseHeader: " + licenseHeader); + + // not as comment{ +// Comment commentLicenseHeader = document.createComment(licenseHeader); +// LOG.info("C#:write4, commentLicenseHeader.getTextContent: " + commentLicenseHeader.getTextContent() + " commentLicenseHeader.toString(): " + commentLicenseHeader.toString()); +// Node nodeLicenseHeader = document.appendChild(commentLicenseHeader); +// LOG.info("C#:write5, nodeLicenseHeader.getTextContent: " + nodeLicenseHeader.getTextContent() + " nodeLicenseHeader.toString(): " + nodeLicenseHeader.toString()); + // not as comment} + + Document docLicenseHeader = null; + try + { + document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(licenseHeader))); + } catch (Exception e) { + LOG.error("C#:write8 Exception when rewriting the non translatable part of the .resx file", e); + } } - LOG.info("C#:write4"); + LOG.info("C#:write9"); Element root = document.createElement(ROOT_NODE); document.appendChild(root); + EList properties = file.getProperties(); for (Property property : properties) { - LOG.info("C#:write5, property: " + property.toString()); + LOG.info("C#:write10, property: " + property.toString()); if(writeProperty(root, document, property)) { counter++; - LOG.info("C#:write6, counter: " + counter); + LOG.info("C#:write11, counter: " + counter); } } - LOG.info("C#:write7"); + LOG.info("C#:write12"); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); if(prettyPrint){ - LOG.info("C#:write8"); + LOG.info("C#:write13"); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); } DOMSource source = new DOMSource(document); StreamResult result = new StreamResult(out); - LOG.info("C#:write9"); + LOG.info("C#:write14"); transformer.transform(source, result); - LOG.info("C#:write10"); + LOG.info("C#:write15"); return counter; } catch (ParserConfigurationException e) { From 57e7453fd2d317d5bd7f47033e265e51abb6852c Mon Sep 17 00:00:00 2001 From: "c.gromer" Date: Thu, 16 May 2019 11:31:18 +0200 Subject: [PATCH 04/15] Plan b performed: Replacing the value in .resx file works now --- .../org/jabylon/csharp/CSharpConverter.java | 212 +++++++++++++----- 1 file changed, 152 insertions(+), 60 deletions(-) diff --git a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java index 7125d09..00c9191 100644 --- a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java +++ b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java @@ -6,6 +6,11 @@ import java.io.StringWriter; import java.io.StringReader; +import java.util.Map; + +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -36,12 +41,14 @@ import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import org.w3c.dom.DOMException; import org.xml.sax.SAXException; import org.xml.sax.InputSource; public class CSharpConverter implements PropertyConverter{ private static final String NAME_ATTRIBUTE = "name"; + private static final String XML_SPACE = "xml:space"; private static final String ROOT_NODE = "root"; private static final String DATA = "data"; @@ -58,16 +65,12 @@ public class CSharpConverter implements PropertyConverter{ private String comment; - // If LOG... is running stable we can remove the System.out.println statemenets entirely - - public CSharpConverter(URI resourceLocation, boolean prettyPrint) { this.uri = resourceLocation; this.prettyPrint = prettyPrint; LOG.info("C#:CSharpConverter1"); } - @Override public PropertyFile load(InputStream in, String encoding) throws IOException { @@ -98,12 +101,13 @@ public PropertyFile load(InputStream in, String encoding) throws IOException { LOG.info("C#:load5, child node_" + i + " Name: " + node.getNodeName() + " Value: " + node.getNodeValue() + " Content:" + node.getTextContent() + " Type: " + node.getNodeType()); if (true == loadNode(node,file)) { - resources.removeChild(node); - LOG.info("C#:load6, child node_" + i + " removed. nodes.getLength afterwards: " + nodes.getLength()); + // 5/14/2019: Now we try plan B and replace the values in the xml file + //resources.removeChild(node); + //LOG.info("C#:load6, child node_" + i + " removed. nodes.getLength afterwards: " + nodes.getLength()); } } - // Build a new Document without the nodes being treated by Jabylon + // Build a new Document includes the nodes getting treated by Jabylon DocumentBuilderFactory docBuilderFact = DocumentBuilderFactory.newInstance(); docBuilderFact.setNamespaceAware(true); DocumentBuilder docBuilder = docBuilderFact.newDocumentBuilder(); @@ -127,7 +131,7 @@ public PropertyFile load(InputStream in, String encoding) throws IOException { LOG.error("C#:load8, nodeToString Transformer exception: ", te); } - file.setLicenseHeader(resFileAsString); + file.setLicenseHeader(resFileAsString); // we take the license header to store everything from our resx file that should not be treated by Jabylon return file; @@ -139,33 +143,43 @@ public PropertyFile load(InputStream in, String encoding) throws IOException { in.close(); } } + - - private boolean // = true: node is provided for translation - // = false: node is not provided for translation and therefore transferred to licenseHeader for not being lost - loadNode(Node node, PropertyFile file) { - + /** + * + * @param node + * @param file + * @return true: node is provided for translation + * false: node is not provided for translation and therefore transferred to licenseHeader for not being lost (no child left behind) + */ + private boolean loadNode(Node node, PropertyFile file) { Property property = PropertiesFactory.eINSTANCE.createProperty(); String name = node.getNodeName(); LOG.info("C#:loadNode1, Name: " + name); + + if(false == name.equals(DATA)){ + LOG.info("C#:loadNode2, NodeName not appropriate+"); + return false; + } if (false == loadString(node, property)) { - LOG.info("C#:loadNode2, node not appropiate"); + LOG.info("C#:loadNode3, node not appropiate"); return false; } // for analysis purpose EList eListPropAnn = property.getAnnotations(); int nCount = eListPropAnn.size(); - LOG.info("C#:loadNode3, was saved? nCount: " + nCount); + LOG.info("C#:loadNode4, was saved? nCount: " + nCount); - property.setComment(comment); + // made our annotations disappear: + //property.setComment(comment); - LOG.info("C#:loadNode4, comment: " + comment); + LOG.info("C#:loadNode5, comment: " + comment); comment = null; file.getProperties().add(property); - LOG.info("C#:loadNode5, comment: " + comment); + LOG.info("C#:loadNode6, comment: " + comment); return true; } @@ -190,8 +204,16 @@ private boolean hasTypeAttribute(Node node) { } + /** + * + * @param node e.g.: + Banana.AutoCode + + * @param property + * @return true: node is provided for translation + * false: node is not provided for translation and therefore transferred to licenseHeader for not being lost + */ private boolean loadString(Node node, Property property) { - LOG.info("C#:loadString1, node.getTextContent(): " + node.getTextContent() + " property: " + property.getValue()); NamedNodeMap namedNodeMap = node.getAttributes(); @@ -201,18 +223,18 @@ private boolean loadString(Node node, Property property) { return false; } - Node name = namedNodeMap.getNamedItem(NAME_ATTRIBUTE); + Node namedNode = namedNodeMap.getNamedItem(NAME_ATTRIBUTE); - if (null == name) { + if (null == namedNode) { LOG.info("C#:loadString3, NAME_ATTRIBUTE not found"); return false; } - String textContentName = name.getTextContent(); + String textContentName = namedNode.getTextContent(); LOG.info("C#:loadString4, textContentName: " + textContentName); - String key = name.getNodeValue(); + String key = namedNode.getNodeValue(); property.setKey(key); String textContentNode = node.getTextContent(); @@ -220,40 +242,62 @@ private boolean loadString(Node node, Property property) { // most of the xml elements in a C# resource file are not for translation String nodeName = node.getNodeName(); - if (false == isCandidateForTranslation(key, nodeName)) { - PropertyAnnotation annotation = PropertiesFactory.eINSTANCE.createPropertyAnnotation(); - - annotation.setName(PropertyAnnotations.NON_TRANSLATABLE); - - // for better debugging: - //property.getAnnotations().add(annotation); - EList eListPropAnn = property.getAnnotations(); - int nCount = eListPropAnn.size(); - LOG.info("C#:loadString7, nCount annotations before adding: " + nCount); - eListPropAnn.add(annotation); - - nCount = eListPropAnn.size(); - LOG.info("C#:loadString8, nCount annotations after adding: " + nCount + " not provided for translation"); + //if (false == isCandidateForTranslation(key, nodeName)) { + if (false == isCandidateForTranslation(namedNode)) { + LOG.info("C#:loadString8, no candidate for translation "); + return false; } else { // provided for translation + // todo: Collect the other attributes LOG.info("C#:loadString10, provided for translation "); } + property.setValue(decode(textContentNode)); + + //property.setComment("Test @Foo Bu Test2"); + + Node namedNodeXmlSpace = namedNodeMap.getNamedItem(XML_SPACE); + if (null != namedNodeXmlSpace) { + String xmlSpaceName = namedNodeXmlSpace.getTextContent(); + String valueXmlSpace = namedNodeXmlSpace.getNodeValue(); + LOG.info("C#:loadString11, xmlSpaceName: " + xmlSpaceName + " valueXmlSpace: " + valueXmlSpace); + + int nCounter = property.getAnnotations().size(); + LOG.info("C#:loadString12, nCounter before: " + nCounter); + PropertyAnnotation annotation = PropertiesFactory.eINSTANCE.createPropertyAnnotation(); + annotation.getValues().put(XML_SPACE, xmlSpaceName); + annotation.setName(XML_SPACE); + + // does not work proper actually (5/14/2019) + property.getAnnotations().add(annotation); + + nCounter = property.getAnnotations().size(); + LOG.info("C#:loadString13, nCounter after: " + nCounter); + } return true; } - - private boolean isCandidateForTranslation(String key, String nodeName) { + + /** + * + * @param key + * @param nodeName + * @return + */ + //private boolean isCandidateForTranslation(String key, String nodeName) { + private boolean isCandidateForTranslation(Node node) { boolean bReturn = false; - - LOG.info("C#:isCandidateForTranslation1, key: " + key + " nodeName: " + nodeName); + + String key = node.getNodeValue(); + String nodeName = node.getNodeName(); + short nodeType = node.getNodeType(); + + LOG.info("C#:isCandidateForTranslation1, key: " + key + " nodeType: " + nodeType + " nodeName: " + nodeName); if (key.endsWith(".Text")) { - LOG.info("C#:isCandidateForTranslation2, key ends with .Text"); - if(nodeName.equals(DATA)){ - LOG.info("C#:isCandidateForTranslation3, nodeName equals DATA"); - bReturn = true; - } + //if (Node.TEXT_NODE == nodeType) { // did not work, nodeType was always 2 + LOG.info("C#:isCandidateForTranslation2, node is a text node"); + bReturn = true; } LOG.info("C#:isCandidateForTranslation4, bReturn: " + bReturn); return bReturn; @@ -314,38 +358,67 @@ public int write(OutputStream out, PropertyFile file, String encoding) throws IO LOG.error("C#:write8 Exception when rewriting the non translatable part of the .resx file", e); } } - - LOG.info("C#:write9"); - - Element root = document.createElement(ROOT_NODE); - document.appendChild(root); - + + //Element root = document.getDocumentElement(); + EList properties = file.getProperties(); + + LOG.info("C#:write9, Count Properties: " + properties.size()); + for (Property property : properties) { LOG.info("C#:write10, property: " + property.toString()); - if(writeProperty(root, document, property)) { - counter++; - LOG.info("C#:write11, counter: " + counter); + + try { + + XPath xPath = XPathFactory.newInstance().newXPath(); + + String searchStr = "//data[@name=\"" + property.getKey() + "\"]"; + + LOG.info("C#:write11, searchstr: " + searchStr); + + Node nodeWithValue = (Node)xPath.evaluate(searchStr, document, XPathConstants.NODE); + NodeList childNodes = nodeWithValue.getChildNodes(); + + if (null != childNodes) { + + int numberOfChildren = childNodes.getLength(); + String newVal = property.getValue(); + + LOG.info("C#:write12, number of child nodes: " + numberOfChildren + " new value: " + newVal); + + for (int i=0; i annotations = property.getAnnotations(); + PropertyAnnotation findAnnotation = property.findAnnotation(XML_SPACE); + if(findAnnotation !=null) { + LOG.info("C#:writeString5"); + } + if (0 < annotations.size()) { + LOG.info("C#:writeString6"); + PropertyAnnotation annotation = annotations.get(0); + LOG.info("C#:writeString7, annotation.getName(): " + annotation.getName()); + if (0 < annotations.get(0).getValues().size()) { + LOG.info("C#:writeString8"); + String attributeValue = annotations.get(0).getValues().get(XML_SPACE).toString(); + if (null != attributeValue) { + LOG.info("C#:writeString9, attributeValue: " + attributeValue); + data.setAttribute(XML_SPACE, attributeValue); + } + } + } } From 7f5beb122e3714b0252ab52fbfc92fdfdc0d960a Mon Sep 17 00:00:00 2001 From: "c.gromer" Date: Fri, 17 May 2019 13:31:26 +0200 Subject: [PATCH 05/15] C# plugin works now but not cleaned up yet --- .../org/jabylon/csharp/CSharpConverter.java | 147 +++++++++--------- 1 file changed, 76 insertions(+), 71 deletions(-) diff --git a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java index 00c9191..bd0787c 100644 --- a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java +++ b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java @@ -51,6 +51,8 @@ public class CSharpConverter implements PropertyConverter{ private static final String XML_SPACE = "xml:space"; private static final String ROOT_NODE = "root"; private static final String DATA = "data"; + private static final String TYPE = "type"; + private static final String SYSTEM_STRING = "System.String"; private static final String NO_TRANS = "No_Translation"; // denotes a property a non-candidate for translation (most of the properties are non-candidates) @@ -88,8 +90,6 @@ public PropertyFile load(InputStream in, String encoding) throws IOException { Node resources = result.getDocumentElement(); LOG.info("C#:load2, resources, TextContent: " + resources.getTextContent()); - - LOG.info("C#:load3, result.getTextContent: " + result.getTextContent()); NodeList nodes = resources.getChildNodes(); @@ -101,7 +101,7 @@ public PropertyFile load(InputStream in, String encoding) throws IOException { LOG.info("C#:load5, child node_" + i + " Name: " + node.getNodeName() + " Value: " + node.getNodeValue() + " Content:" + node.getTextContent() + " Type: " + node.getNodeType()); if (true == loadNode(node,file)) { - // 5/14/2019: Now we try plan B and replace the values in the xml file + // 5/14/2019: Now we try plan B and replace the values in the xml file therefore there is no removal anymore of the Jabylon treated nodes //resources.removeChild(node); //LOG.info("C#:load6, child node_" + i + " removed. nodes.getLength afterwards: " + nodes.getLength()); } @@ -162,24 +162,39 @@ private boolean loadNode(Node node, PropertyFile file) { LOG.info("C#:loadNode2, NodeName not appropriate+"); return false; } - + + + NamedNodeMap namedNodeMap = node.getAttributes(); + if (null != namedNodeMap) { + for (int j=0; j eListPropAnn = property.getAnnotations(); int nCount = eListPropAnn.size(); - LOG.info("C#:loadNode4, was saved? nCount: " + nCount); + LOG.info("C#:loadNode6, was saved? nCount: " + nCount); // made our annotations disappear: //property.setComment(comment); - LOG.info("C#:loadNode5, comment: " + comment); + LOG.info("C#:loadNode7, comment: " + comment); comment = null; file.getProperties().add(property); - LOG.info("C#:loadNode6, comment: " + comment); + LOG.info("C#:loadNode8, comment: " + comment); return true; } @@ -214,7 +229,7 @@ private boolean hasTypeAttribute(Node node) { * false: node is not provided for translation and therefore transferred to licenseHeader for not being lost */ private boolean loadString(Node node, Property property) { - LOG.info("C#:loadString1, node.getTextContent(): " + node.getTextContent() + " property: " + property.getValue()); + LOG.info("C#:loadString1, node.getTextContent(): " + node.getTextContent() + " property: " + property.getValue() + " type: " + node.getNodeType()); NamedNodeMap namedNodeMap = node.getAttributes(); @@ -237,44 +252,49 @@ private boolean loadString(Node node, Property property) { String key = namedNode.getNodeValue(); property.setKey(key); - String textContentNode = node.getTextContent(); - LOG.info("C#:loadString5, textContentNode: " + textContentNode); - // most of the xml elements in a C# resource file are not for translation - String nodeName = node.getNodeName(); - //if (false == isCandidateForTranslation(key, nodeName)) { if (false == isCandidateForTranslation(namedNode)) { - LOG.info("C#:loadString8, no candidate for translation "); + LOG.info("C#:loadString5, no candidate for translation "); return false; } else { // provided for translation // todo: Collect the other attributes - LOG.info("C#:loadString10, provided for translation "); + LOG.info("C#:loadString6, provided for translation "); } - property.setValue(decode(textContentNode)); + + // not correct: we get an extra empty row{ + //String textContentNode = node.getTextContent(); + //LOG.info("C#:loadString10, textContentNode: " + textContentNode); + //property.setValue(decode(textContentNode)); + // not correct: we get an extra empty row} - //property.setComment("Test @Foo Bu Test2"); + Node valueNode = getValueNode(node); + if (null != valueNode) { + property.setValue(valueNode.getTextContent()); + } - Node namedNodeXmlSpace = namedNodeMap.getNamedItem(XML_SPACE); - if (null != namedNodeXmlSpace) { - String xmlSpaceName = namedNodeXmlSpace.getTextContent(); - String valueXmlSpace = namedNodeXmlSpace.getNodeValue(); - LOG.info("C#:loadString11, xmlSpaceName: " + xmlSpaceName + " valueXmlSpace: " + valueXmlSpace); - - int nCounter = property.getAnnotations().size(); - LOG.info("C#:loadString12, nCounter before: " + nCounter); - PropertyAnnotation annotation = PropertiesFactory.eINSTANCE.createPropertyAnnotation(); - annotation.getValues().put(XML_SPACE, xmlSpaceName); - annotation.setName(XML_SPACE); + return true; + } + + private Node getValueNode(Node node) { + NodeList childNodes = node.getChildNodes(); + + if (null != childNodes) { + int numberOfChildren = childNodes.getLength(); - // does not work proper actually (5/14/2019) - property.getAnnotations().add(annotation); + LOG.debug("C#:getValueNode1, number of child nodes: " + numberOfChildren); - nCounter = property.getAnnotations().size(); - LOG.info("C#:loadString13, nCounter after: " + nCounter); - } - return true; + for (int i=0; i properties = file.getProperties(); LOG.info("C#:write9, Count Properties: " + properties.size()); @@ -369,7 +386,6 @@ public int write(OutputStream out, PropertyFile file, String encoding) throws IO LOG.info("C#:write10, property: " + property.toString()); try { - XPath xPath = XPathFactory.newInstance().newXPath(); String searchStr = "//data[@name=\"" + property.getKey() + "\"]"; @@ -377,25 +393,15 @@ public int write(OutputStream out, PropertyFile file, String encoding) throws IO LOG.info("C#:write11, searchstr: " + searchStr); Node nodeWithValue = (Node)xPath.evaluate(searchStr, document, XPathConstants.NODE); - NodeList childNodes = nodeWithValue.getChildNodes(); - if (null != childNodes) { - - int numberOfChildren = childNodes.getLength(); + Node valueNode = getValueNode(nodeWithValue); + + if (null != valueNode) { String newVal = property.getValue(); - LOG.info("C#:write12, number of child nodes: " + numberOfChildren + " new value: " + newVal); - - for (int i=0; i annotations = property.getAnnotations(); + /*EList annotations = property.getAnnotations(); PropertyAnnotation findAnnotation = property.findAnnotation(XML_SPACE); if(findAnnotation !=null) { LOG.info("C#:writeString5"); @@ -485,7 +490,7 @@ private void writeString(Element root, Document document, Property property) { data.setAttribute(XML_SPACE, attributeValue); } } - } + }*/ } From 7322b105eacc484a8972d3609af8305c2414b89f Mon Sep 17 00:00:00 2001 From: "c.gromer" Date: Tue, 21 May 2019 13:26:14 +0200 Subject: [PATCH 06/15] >> gets strained off now --- .../org/jabylon/csharp/CSharpConverter.java | 163 ++---------------- 1 file changed, 12 insertions(+), 151 deletions(-) diff --git a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java index bd0787c..a519c88 100644 --- a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java +++ b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java @@ -159,16 +159,20 @@ private boolean loadNode(Node node, PropertyFile file) { LOG.info("C#:loadNode1, Name: " + name); if(false == name.equals(DATA)){ - LOG.info("C#:loadNode2, NodeName not appropriate+"); + LOG.info("C#:loadNode2, NodeName not appropriate"); return false; } - NamedNodeMap namedNodeMap = node.getAttributes(); if (null != namedNodeMap) { for (int j=0; j>")) { + LOG.info("C#:loadNode3, node value not appropriate"); + return false; + } if (true == attribute.getNodeName().equals(TYPE)) { if (false == attribute.getNodeValue().equals(SYSTEM_STRING)) { LOG.info("C#:loadNode4, type attribute found which is not appropriate+"); @@ -198,26 +202,6 @@ private boolean loadNode(Node node, PropertyFile file) { return true; } - - private boolean hasTypeAttribute(Node node) { - boolean hasTypeAttribute = false; - - NamedNodeMap namedNodeMap = node.getAttributes(); - if (null != namedNodeMap) { - LOG.info("C#:hasTypeAttribute1, namedNodeMap.toString: " + namedNodeMap.toString()); - for (int j=0; j annotations = property.getAnnotations(); - PropertyAnnotation findAnnotation = property.findAnnotation(XML_SPACE); - if(findAnnotation !=null) { - LOG.info("C#:writeString5"); - } - if (0 < annotations.size()) { - LOG.info("C#:writeString6"); - PropertyAnnotation annotation = annotations.get(0); - LOG.info("C#:writeString7, annotation.getName(): " + annotation.getName()); - if (0 < annotations.get(0).getValues().size()) { - LOG.info("C#:writeString8"); - String attributeValue = annotations.get(0).getValues().get(XML_SPACE).toString(); - if (null != attributeValue) { - LOG.info("C#:writeString9, attributeValue: " + attributeValue); - data.setAttribute(XML_SPACE, attributeValue); - } - } - }*/ } @@ -507,58 +418,8 @@ private String encode(String textContent) { } - /** - * - * @param root - * @param document - * @param property - * @return = true: non translatable property - * = false: translatable property, the caller has to care for the property - * @throws IOException - */ - private boolean writeCommentAndAnnotations(Element root, Document document, Property property) throws IOException { - - boolean bReturn = false; - - LOG.info("C#:writeCommentAndAnnotations1, property: " + property.toString() + " property.getAnnotations().size(): " + property.getAnnotations().size()); - - if(property.eIsSet(PropertiesPackage.Literals.PROPERTY__COMMENT) || property.getAnnotations().size()>0) - { - LOG.info("C#:writeCommentAndAnnotations2"); - - String comment = property.getCommentWithoutAnnotations(); - - LOG.info("C#:writeCommentAndAnnotations3, comment: " + comment); - - StringBuilder builder = new StringBuilder(); - - PropertyAnnotation nonTranslatable = property.findAnnotation(PropertyAnnotations.NON_TRANSLATABLE); - if (null != nonTranslatable) { - bReturn = true; // this property is non-translatable - LOG.info("C#:writeCommentAndAnnotations4, property has NON_TRANSLATABLE annotation " + comment); - } - - if(builder.length()>0 && comment!=null && comment.length()>0 ) - { - builder.append("\n"); - } - builder.append(comment); - - String stringFromComment = builder.toString(); - - LOG.info("C#:writeCommentAndAnnotations5, stringFromComment: " + stringFromComment); - - Comment node = document.createComment(stringFromComment); - - LOG.info("C#:writeCommentAndAnnotations4, node: " + node.toString()); - - root.appendChild(node); - } - return bReturn; - } - private boolean isFilled(String s){ LOG.info("C#:isFilled1, s: " + s); return s!=null && !s.isEmpty(); } -} +} \ No newline at end of file From b632f1977e8e1b7e9b8893fb548794c8fd2b6d0e Mon Sep 17 00:00:00 2001 From: "c.gromer" Date: Tue, 21 May 2019 17:35:03 +0200 Subject: [PATCH 07/15] logging adjusted --- .../org/jabylon/csharp/CSharpConverter.java | 96 ++++++++--------- .../org/jabylon/csharp/CSharpScanner.java | 102 +++++++++--------- 2 files changed, 93 insertions(+), 105 deletions(-) diff --git a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java index a519c88..f638d4b 100644 --- a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java +++ b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java @@ -70,7 +70,7 @@ public class CSharpConverter implements PropertyConverter{ public CSharpConverter(URI resourceLocation, boolean prettyPrint) { this.uri = resourceLocation; this.prettyPrint = prettyPrint; - LOG.info("C#:CSharpConverter1"); + LOG.debug("C#:CSharpConverter1"); } @@ -78,7 +78,7 @@ public CSharpConverter(URI resourceLocation, boolean prettyPrint) { public PropertyFile load(InputStream in, String encoding) throws IOException { // TODO Auto-generated method stub - LOG.info("C#:load0, in: " + in.toString()); + LOG.debug("C#:load0, in: " + in.toString()); try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); @@ -89,16 +89,16 @@ public PropertyFile load(InputStream in, String encoding) throws IOException { Node resources = result.getDocumentElement(); - LOG.info("C#:load2, resources, TextContent: " + resources.getTextContent()); + LOG.debug("C#:load2, resources, TextContent: " + resources.getTextContent()); NodeList nodes = resources.getChildNodes(); int nodesLength = nodes.getLength(); - LOG.info("C#:load4, nodesLength: " + nodesLength); + LOG.debug("C#:load4, nodesLength: " + nodesLength); for (int i = nodesLength-1; i >= 0; i--) { Node node = nodes.item(i); - LOG.info("C#:load5, child node_" + i + " Name: " + node.getNodeName() + " Value: " + node.getNodeValue() + " Content:" + node.getTextContent() + " Type: " + node.getNodeType()); + LOG.debug("C#:load5, child node_" + i + " Name: " + node.getNodeName() + " Value: " + node.getNodeValue() + " Content:" + node.getTextContent() + " Type: " + node.getNodeType()); if (true == loadNode(node,file)) { // 5/14/2019: Now we try plan B and replace the values in the xml file therefore there is no removal anymore of the Jabylon treated nodes @@ -126,7 +126,7 @@ public PropertyFile load(InputStream in, String encoding) throws IOException { t.setOutputProperty(OutputKeys.INDENT, "yes"); t.transform(new DOMSource(firstNode), new StreamResult(sw)); resFileAsString = sw.toString(); - LOG.info("C#:load7, resFileAsString: " + resFileAsString); + LOG.debug("C#:load7, resFileAsString: " + resFileAsString); } catch (TransformerException te) { LOG.error("C#:load8, nodeToString Transformer exception: ", te); } @@ -156,10 +156,10 @@ private boolean loadNode(Node node, PropertyFile file) { Property property = PropertiesFactory.eINSTANCE.createProperty(); String name = node.getNodeName(); - LOG.info("C#:loadNode1, Name: " + name); + LOG.debug("C#:loadNode1, Name: " + name); if(false == name.equals(DATA)){ - LOG.info("C#:loadNode2, NodeName not appropriate"); + LOG.debug("C#:loadNode2, NodeName not appropriate"); return false; } @@ -168,14 +168,14 @@ private boolean loadNode(Node node, PropertyFile file) { for (int j=0; j>")) { - LOG.info("C#:loadNode3, node value not appropriate"); + LOG.debug("C#:loadNode3, node value not appropriate"); return false; } if (true == attribute.getNodeName().equals(TYPE)) { if (false == attribute.getNodeValue().equals(SYSTEM_STRING)) { - LOG.info("C#:loadNode4, type attribute found which is not appropriate+"); + LOG.debug("C#:loadNode4, type attribute found which is not appropriate+"); return false; } } @@ -183,22 +183,19 @@ private boolean loadNode(Node node, PropertyFile file) { } if (false == loadString(node, property)) { - LOG.info("C#:loadNode5, node not appropiate"); + LOG.debug("C#:loadNode5, node not appropiate"); return false; } // for analysis purpose EList eListPropAnn = property.getAnnotations(); int nCount = eListPropAnn.size(); - LOG.info("C#:loadNode6, was saved? nCount: " + nCount); + LOG.debug("C#:loadNode6, was saved? nCount: " + nCount); - // made our annotations disappear: - //property.setComment(comment); - - LOG.info("C#:loadNode7, comment: " + comment); + LOG.debug("C#:loadNode7, comment: " + comment); comment = null; file.getProperties().add(property); - LOG.info("C#:loadNode8, comment: " + comment); + LOG.debug("C#:loadNode8, comment: " + comment); return true; } @@ -213,30 +210,30 @@ private boolean loadNode(Node node, PropertyFile file) { * false: node is not provided for translation and therefore transferred to licenseHeader for not being lost */ private boolean loadString(Node node, Property property) { - LOG.info("C#:loadString1, node.getTextContent(): " + node.getTextContent() + " property: " + property.getValue() + " type: " + node.getNodeType()); + LOG.debug("C#:loadString1, node.getTextContent(): " + node.getTextContent() + " property: " + property.getValue() + " type: " + node.getNodeType()); NamedNodeMap namedNodeMap = node.getAttributes(); if (null == namedNodeMap) { - LOG.info("C#:loadString2, namedNodeMap is null"); + LOG.error("C#:loadString2, namedNodeMap is null"); return false; } Node namedNode = namedNodeMap.getNamedItem(NAME_ATTRIBUTE); if (null == namedNode) { - LOG.info("C#:loadString3, NAME_ATTRIBUTE not found"); + LOG.error("C#:loadString3, NAME_ATTRIBUTE not found"); return false; } String textContentName = namedNode.getTextContent(); - LOG.info("C#:loadString4, textContentName: " + textContentName); + LOG.debug("C#:loadString4, textContentName: " + textContentName); String key = namedNode.getNodeValue(); property.setKey(key); - LOG.info("C#:loadString6, provided for translation "); + LOG.debug("C#:loadString6, provided for translation "); Node valueNode = getValueNode(node); if (null != valueNode) { @@ -257,7 +254,7 @@ private Node getValueNode(Node node) { for (int i=0; i properties = file.getProperties(); - LOG.info("C#:write9, Count Properties: " + properties.size()); + LOG.debug("C#:write9, Count Properties: " + properties.size()); for (Property property : properties) { - LOG.info("C#:write10, property: " + property.toString()); + + LOG.debug("C#:write10, property: " + property.toString()); try { XPath xPath = XPathFactory.newInstance().newXPath(); String searchStr = "//data[@name=\"" + property.getKey() + "\"]"; - LOG.info("C#:write11, searchstr: " + searchStr); + LOG.debug("C#:write11, searchstr: " + searchStr); Node nodeWithValue = (Node)xPath.evaluate(searchStr, document, XPathConstants.NODE); @@ -336,27 +333,27 @@ public int write(OutputStream out, PropertyFile file, String encoding) throws IO valueNode.setTextContent(newVal); } } catch (Exception e) { - LOG.info("C#:write16 ", e); + LOG.error("C#:write16 ", e); } } - LOG.info("C#:write17"); + LOG.debug("C#:write17"); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); if(prettyPrint){ - LOG.info("C#:write18"); + LOG.debug("C#:write18"); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); } DOMSource source = new DOMSource(document); StreamResult result = new StreamResult(out); - LOG.info("C#:write19"); + LOG.debug("C#:write19"); transformer.transform(source, result); - LOG.info("C#:write20"); + LOG.debug("C#:write20"); return counter; } catch (ParserConfigurationException e) { @@ -372,17 +369,16 @@ public int write(OutputStream out, PropertyFile file, String encoding) throws IO private boolean writeProperty(Element root, Document document, Property property) throws IOException { - LOG.info("C#:writeProperty1"); + LOG.debug("C#:writeProperty1"); String value = property.getValue(); - LOG.info("C#:writeProperty2, value of property: " + value); + LOG.debug("C#:writeProperty2, value of property: " + value); if(!isFilled(value)) { - LOG.info("C#:writeProperty3, value not filled"); + LOG.error("C#:writeProperty3, value not filled"); return false; } - // property was created by a translatable xml-element. So write back the translation writeString(root,document,property); return true; @@ -390,36 +386,34 @@ private boolean writeProperty(Element root, Document document, Property property private void writeString(Element root, Document document, Property property) { - LOG.info("C#:writeString1"); + LOG.debug("C#:writeString1"); Element data = document.createElement(DATA); - LOG.info("C#:writeString2"); + LOG.debug("C#:writeString2"); root.appendChild(data); String key = property.getKey(); - LOG.info("C#:writeString3, key: " + key); + LOG.debug("C#:writeString3, key: " + key); data.setAttribute(NAME_ATTRIBUTE, key); String value = property.getValue(); - LOG.info("C#:writeString4, value: " + value); + LOG.debug("C#:writeString4, value: " + value); data.setTextContent(encode(value)); } private String encode(String textContent) { if(textContent==null) { - LOG.info("C#:encode1, textContent is null"); + LOG.debug("C#:encode1, textContent is null"); return null; } - textContent = textContent.replace("'", "\\'").replace("\"", "\\\""); - LOG.info("C#:encode2, textContent: " + textContent); - + LOG.debug("C#:encode2, textContent: " + textContent); return textContent; } private boolean isFilled(String s){ - LOG.info("C#:isFilled1, s: " + s); + LOG.debug("C#:isFilled1, s: " + s); return s!=null && !s.isEmpty(); } } \ No newline at end of file diff --git a/csharp/src/main/java/org/jabylon/csharp/CSharpScanner.java b/csharp/src/main/java/org/jabylon/csharp/CSharpScanner.java index 4ca5867..8b58bc3 100644 --- a/csharp/src/main/java/org/jabylon/csharp/CSharpScanner.java +++ b/csharp/src/main/java/org/jabylon/csharp/CSharpScanner.java @@ -46,13 +46,13 @@ public class CSharpScanner implements PropertyScanner { private static final Logger LOG = LoggerFactory.getLogger(CSharpScanner.class); public CSharpScanner() { - LOG.info("C#:CSharpScanner1"); + LOG.debug("C#:CSharpScanner1"); } @Override public String[] getDefaultIncludes() { - LOG.info("C#:getDefaultIncludes1"); + LOG.debug("C#:getDefaultIncludes1"); return DEFAULT_INCLUDES; } @@ -61,122 +61,117 @@ public String[] getDefaultIncludes() { */ @Override public String[] getDefaultExcludes() { - LOG.info("C#:getDefaultExcludes1"); + LOG.debug("C#:getDefaultExcludes1"); return DEFAULT_EXCLUDES; } @Override public boolean isTemplate(File propertyFile, String masterLocale) { - LOG.info("C#:isTemplate1"); - LOG.info("C#:isTemplate2 propertyFile: " + propertyFile.getName() + " masterLocale: " + masterLocale); + LOG.debug("C#:isTemplate2 propertyFile: " + propertyFile.getName() + " masterLocale: " + masterLocale); if(isResourceFile(propertyFile) && countingPeriodsFullfillsTemplateFileCondition(propertyFile)) { + LOG.debug("C#:isTemplate3 propertyFile is a template"); return true; } + + LOG.debug("C#:isTemplate4 propertyFile is not a template"); return false; } @Override public boolean isTranslation(File propertyFile, ScanConfiguration config) { - LOG.info("C#:isTranslation1"); String fileName = propertyFile.getName(); - LOG.info("C#:isTranslation2 fileName: " + fileName); + LOG.debug("C#:isTranslation2 fileName: " + fileName); if (isResourceFile(propertyFile) && (countingPeriodsFullfillsTranslationFileCondition(propertyFile))) { + LOG.debug("C#:isTranslation3 property file is a translation file"); return true; } + + LOG.debug("C#:isTranslation4 property file is not a translation file"); return false; } private boolean countingPeriodsFullfillsTranslationFileCondition(File propertyFile) { //E.g.: Resources.nl.resx is a translation file, Resources.resx is a template file - LOG.info("C#:countingPeriodsFullfillsTranslationFileCondition1: propertyFile: " + propertyFile.getName()); + LOG.debug("C#:countingPeriodsFullfillsTranslationFileCondition1: propertyFile: " + propertyFile.getName()); if (2 == propertyFile.getName().length() - propertyFile.getName().replace(".","").length()) { - LOG.info("C#:countingPeriodsFullfillsTranslationFileCondition2: translation file" ); + LOG.debug("C#:countingPeriodsFullfillsTranslationFileCondition2: translation file" ); return true; } - LOG.info("C#:countingPeriodsFullfillsTranslationFileCondition3: no translation file" ); + LOG.debug("C#:countingPeriodsFullfillsTranslationFileCondition3: no translation file" ); return false; } private boolean countingPeriodsFullfillsTemplateFileCondition(File propertyFile) { //E.g.: Resources.nl.resx is a translation file, Resources.resx is a template file - boolean bReturn = false; - LOG.info("C#:countingPeriodsFullfillsTemplateFileCondition1: propertyFile: " + propertyFile.getName()); + LOG.debug("C#:countingPeriodsFullfillsTemplateFileCondition1: propertyFile: " + propertyFile.getName()); if (1 == propertyFile.getName().length() - propertyFile.getName().replace(".","").length()) { - LOG.info("C#:countingPeriodsFullfillsTemplateFileCondition2: template" ); + LOG.debug("C#:countingPeriodsFullfillsTemplateFileCondition2: template" ); bReturn = true; } - LOG.info("C#:countingPeriodsFullfillsTemplateFileCondition3: bReturn: " + bReturn); + LOG.debug("C#:countingPeriodsFullfillsTemplateFileCondition3: bReturn: " + bReturn); return bReturn; } private boolean isResourceFile(File propertyFile) { - - LOG.info("C#:isResourceFile1" ); - LOG.info("C#:isResourceFile2, propertyFile: " + propertyFile.getName()); + LOG.debug("C#:isResourceFile2, propertyFile: " + propertyFile.getName()); boolean isResFile = false; if(propertyFile.getName().endsWith(".resx")) { - LOG.info("C#:isResourceFile3: resource file" ); + LOG.debug("C#:isResourceFile3: resource file" ); isResFile = true; } - LOG.info("C#:isResourceFile4: isResFile: " + isResFile ); + LOG.debug("C#:isResourceFile4: isResFile: " + isResFile ); return isResFile; } @Override public File findTemplate(File propertyFile, ScanConfiguration config) { - LOG.info("C#:findTemplate1"); - if (isTranslation(propertyFile, config)) { String fileName = propertyFile.getName(); - LOG.info("C#:findTemplate2: fileName: " + fileName ); + LOG.debug("C#:findTemplate2: fileName: " + fileName ); // e.g.: Resources.nl.resx String[] strings = fileName.split(".", -1); if (3 == strings.length) { String templateFile = strings[0] + "." + strings[2]; // e.g.: Resources.resx - LOG.info("C#:findTemplate3: templateFile: " + templateFile); + LOG.debug("C#:findTemplate3: templateFile: " + templateFile); return new File(templateFile); } } - LOG.info("C#:findTemplate4"); + LOG.debug("C#:findTemplate4"); return null; } @Override public Map findTranslations(File template, ScanConfiguration config) { - - LOG.info("C#:findTranslations1, template: " + template.getName()); - + LOG.debug("C#:findTranslations1, template: " + template.getName()); if (isTemplate(template, "")) { - - // instead of using org.apache.commons + // instead of using org.apache.commons: String templateWithoutExtension = getFirstPart(template); - String folder = template.getParent(); - LOG.info("C#:findTranslations2: folder: " + folder); + LOG.debug("C#:findTranslations2: folder: " + folder); File[] files = new File(folder).listFiles(); Map translations = new HashMap(); for (File file : files) { - LOG.info("C#:findTranslations3: file: " + file.getName()); + LOG.debug("C#:findTranslations3: file: " + file.getName()); if (templateWithoutExtension.equals(getFirstPart(file))) { - LOG.info("C#:findTranslations4: first part matches"); + LOG.debug("C#:findTranslations4: first part matches"); if (isTranslation(file, config)) { - LOG.info("C#:findTranslations5: is translation"); + LOG.debug("C#:findTranslations5: is translation"); translations.put(getLocale(file), file); } } @@ -185,6 +180,7 @@ public Map findTranslations(File template, ScanConfiguration confi } return null; } + private String getFirstPart(File file) { String firstPart = ""; @@ -193,21 +189,19 @@ private String getFirstPart(File file) { if (0 < fileParts.length) { firstPart = fileParts[0]; } - LOG.info("C#:getFirstPart, return: " + firstPart); + LOG.debug("C#:getFirstPart, return: " + firstPart); return(firstPart); } - - @Override public File computeTranslationPath(File template, Locale templateLocale, Locale translationLocale) { - LOG.info("C#:computeTranslationPath1, template:" + template.getName() + " template.getPath: " + template.getPath()); + LOG.debug("C#:computeTranslationPath1, template:" + template.getName() + " template.getPath: " + template.getPath()); File folder = template.getParentFile(); // template and translation files reside in the same folder - LOG.info("C#:computeTranslationPath2, folder: " + folder.getName()); - - LOG.info("C#:computeTranslationPath2.1, folder.getPath: " + folder.getPath()); - LOG.info("C#:computeTranslationPath2.2, folder.getParent: " + folder.getParent()); + + LOG.debug("C#:computeTranslationPath2, folder: " + folder.getName()); + LOG.debug("C#:computeTranslationPath2.1, folder.getPath: " + folder.getPath()); + LOG.debug("C#:computeTranslationPath2.2, folder.getParent: " + folder.getParent()); return folder; } @@ -215,9 +209,9 @@ public File computeTranslationPath(File template, Locale templateLocale, Locale @Override public Locale getLocale(File propertyFile) { - LOG.info("C#:getLocale1, propertyFile: " + propertyFile); + LOG.debug("C#:getLocale1, propertyFile: " + propertyFile); String propFileName = propertyFile.getName(); // e.g.: dialog.resx (template file), dialog.nl.resx (translation file) - LOG.info("C#:getLocale2, propFileName: " + propFileName); + LOG.debug("C#:getLocale2, propFileName: " + propFileName); String[] splittedPropFileName = propFileName.split("\\."); @@ -226,10 +220,10 @@ public Locale getLocale(File propertyFile) { boolean isTemplate = false; if (1 == splittedPropFileName.length) { - LOG.info("C#:getLocale3, obviously no property file: " + propFileName); + LOG.debug("C#:getLocale3, obviously no property file: " + propFileName); } else if (1 < splittedPropFileName.length) { - LOG.info("C#:getLocale4, splittedPropFileName.length: " + splittedPropFileName.length); + LOG.debug("C#:getLocale4, splittedPropFileName.length: " + splittedPropFileName.length); if (2 == splittedPropFileName.length) { //e.g.: dialog.resx (template file) @@ -237,13 +231,13 @@ else if (1 < splittedPropFileName.length) { } else if (3 == splittedPropFileName.length){ if (2 == splittedPropFileName[splittedPropFileName.length-2].length()) { - LOG.info("C#:getLocale6, only language "); + LOG.debug("C#:getLocale6, only language "); language = splittedPropFileName[splittedPropFileName.length-2]; } else { - LOG.info("C#:getLocale7, splittedPropFileName[splittedPropFileName.length-2].substring(2,3): " + splittedPropFileName[splittedPropFileName.length-2].substring(2,3)); + LOG.debug("C#:getLocale7, splittedPropFileName[splittedPropFileName.length-2].substring(2,3): " + splittedPropFileName[splittedPropFileName.length-2].substring(2,3)); if ("-".equals(splittedPropFileName[splittedPropFileName.length-2].substring(2,3))) { - LOG.info("C#:getLocale8, language + culture "); + LOG.debug("C#:getLocale8, language + culture "); language = splittedPropFileName[splittedPropFileName.length-2].substring(0,2); culture = splittedPropFileName[splittedPropFileName.length-2].substring(3); } @@ -254,9 +248,9 @@ else if (3 == splittedPropFileName.length){ Locale loc = null; if (false == isTemplate) { - LOG.info("C#:getLocale11, no Template"); + LOG.debug("C#:getLocale11, no Template"); if (0 < language.length()){ - LOG.info("C#:getLocale12, isTranslation File, language: " + language + " culture: " + culture); + LOG.debug("C#:getLocale12, isTranslation File, language: " + language + " culture: " + culture); loc = new Locale(language, culture); } } @@ -266,21 +260,21 @@ else if (3 == splittedPropFileName.length){ @Override public boolean isBilingual() { - LOG.info("C#:isBilingual1"); + LOG.debug("C#:isBilingual1"); return false; } @Override public PropertyConverter createConverter(URI resource) { - LOG.info("C#:createConverter1, resource: " + resource.path()); + LOG.debug("C#:createConverter1, resource: " + resource.path()); return new CSharpConverter(resource, true); } @Override public String getEncoding() { - LOG.info("C#:getEncoding1"); + LOG.debug("C#:getEncoding1"); return "UTF-8"; } } From 048b482f8539ec6e360f733fa049fe799a93437e Mon Sep 17 00:00:00 2001 From: "c.gromer" Date: Thu, 23 May 2019 17:18:14 +0200 Subject: [PATCH 08/15] Existing comment now alterable in translation --- .../org/jabylon/csharp/CSharpConverter.java | 112 ++++++++++++++---- 1 file changed, 91 insertions(+), 21 deletions(-) diff --git a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java index f638d4b..faf7826 100644 --- a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java +++ b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java @@ -51,6 +51,7 @@ public class CSharpConverter implements PropertyConverter{ private static final String XML_SPACE = "xml:space"; private static final String ROOT_NODE = "root"; private static final String DATA = "data"; + private static final String COMMENT = "comment"; private static final String TYPE = "type"; private static final String SYSTEM_STRING = "System.String"; @@ -168,34 +169,51 @@ private boolean loadNode(Node node, PropertyFile file) { for (int j=0; j>")) { - LOG.debug("C#:loadNode3, node value not appropriate"); + LOG.debug("C#:loadNode4, node value not appropriate"); return false; } if (true == attribute.getNodeName().equals(TYPE)) { if (false == attribute.getNodeValue().equals(SYSTEM_STRING)) { - LOG.debug("C#:loadNode4, type attribute found which is not appropriate+"); + LOG.debug("C#:loadNode5, type attribute found which is not appropriate+"); return false; } } } } + // search for comment + NodeList childNodes = node.getChildNodes(); + + int childNodesLength = childNodes.getLength(); + LOG.debug("C#:loadNode6, nodesLength: " + childNodesLength); + + for (int k = childNodesLength-1; k >= 0; k--) { + Node childNode = childNodes.item(k); + String nodeName = childNode.getNodeName(); + String nodeContent = childNode.getTextContent(); + LOG.debug("C#:loadNode7, childNode_" + k + " Name: " + nodeName + " Value: " + childNode.getNodeValue() + " Content: " + nodeContent + " Type: " + childNode.getNodeType()); + if (null != nodeName) { + if (nodeName.equals(COMMENT)) { + LOG.debug("C#:loadNode8, comment found"); + comment = nodeContent; + } + } + } + if (false == loadString(node, property)) { - LOG.debug("C#:loadNode5, node not appropiate"); + LOG.debug("C#:loadNode9, node not appropiate"); return false; } - - // for analysis purpose - EList eListPropAnn = property.getAnnotations(); - int nCount = eListPropAnn.size(); - LOG.debug("C#:loadNode6, was saved? nCount: " + nCount); - LOG.debug("C#:loadNode7, comment: " + comment); + if (null != comment) { + LOG.debug("C#:loadNode10, comment was set: " + comment); + property.setComment(comment); + } + comment = null; file.getProperties().add(property); - LOG.debug("C#:loadNode8, comment: " + comment); return true; } @@ -244,18 +262,31 @@ private boolean loadString(Node node, Property property) { private Node getValueNode(Node node) { + LOG.debug("C#:getValueNode1"); + Node childNode = getChildNode(node, "value"); + return childNode; + } + + + private Node getCommentNode(Node node) { + LOG.debug("C#:getCommentNode1"); + Node childNode = getChildNode(node, "comment"); + return childNode; + } + + + private Node getChildNode(Node node, String desiredNodeName) { + LOG.debug("C#:getChildNode1, desiredNodeName: " + desiredNodeName); NodeList childNodes = node.getChildNodes(); - if (null != childNodes) { int numberOfChildren = childNodes.getLength(); - - LOG.debug("C#:getValueNode1, number of child nodes: " + numberOfChildren); + LOG.debug("C#:getChildNode2, number of child nodes: " + numberOfChildren); for (int i=0; i0) + { + LOG.debug("C#:writeCommentAndAnnotations2"); + String comment = property.getCommentWithoutAnnotations(); + LOG.debug("C#:writeCommentAndAnnotations3, comment: " + comment); + StringBuilder builder = new StringBuilder(); + for (PropertyAnnotation annotation : property.getAnnotations()) { + builder.append(annotation); + LOG.debug("C#:writeCommentAndAnnotations4, builder: " + builder.toString()); + } + if(builder.length()>0 && comment!=null && comment.length()>0 ) + { + builder.append("\n"); + LOG.debug("C#:writeCommentAndAnnotations5, builder: " + builder.toString()); + } + builder.append(comment); + String builtComment = builder.toString(); + LOG.debug("C#:writeCommentAndAnnotations6, builder: " + builtComment); + Comment node = document.createComment(builtComment); + root.appendChild(node); + LOG.debug("C#:writeCommentAndAnnotations7"); + } + } + + private void writeString(Element root, Document document, Property property) { LOG.debug("C#:writeString1"); Element data = document.createElement(DATA); From 5aa3b4687ef377491f7f60959fe5587d69dcafcd Mon Sep 17 00:00:00 2001 From: "c.gromer" Date: Thu, 23 May 2019 18:23:58 +0200 Subject: [PATCH 09/15] comment now also inserted in translation file --- .../org/jabylon/csharp/CSharpConverter.java | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java index faf7826..3c38f66 100644 --- a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java +++ b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java @@ -270,7 +270,7 @@ private Node getValueNode(Node node) { private Node getCommentNode(Node node) { LOG.debug("C#:getCommentNode1"); - Node childNode = getChildNode(node, "comment"); + Node childNode = getChildNode(node, COMMENT); return childNode; } @@ -365,22 +365,31 @@ public int write(OutputStream out, PropertyFile file, String encoding) throws IO LOG.debug("C#:write13, newVal: " + newVal); valueNode.setTextContent(newVal); } + - Node commentNode = getCommentNode(nodeWithValue); - if (null != commentNode) { - String newVal = property.getComment(); - // remove the carriage return: - newVal = newVal.replaceAll("\\r", ""); - LOG.debug("C#:write14, newVal: " + newVal); - commentNode.setTextContent(newVal); + String newComment = property.getComment(); + // remove the carriage return: + newComment = newComment.replaceAll("\\r", ""); + if (null != newComment) { + LOG.debug("C#:write14, newComment: " + newComment); + Node commentNode = getCommentNode(nodeWithValue); + if (null != commentNode) { + LOG.debug("C#:write15, comment replaced"); + commentNode.setTextContent(newComment); + } + else { + Node newNode = nodeWithValue.appendChild(document.createElement(COMMENT)); + LOG.debug("C#:write16, comment inserted"); + newNode.setTextContent(newComment); + } } } catch (Exception e) { - LOG.error("C#:write16 ", e); + LOG.error("C#:write17 ", e); } } - LOG.debug("C#:write17"); + LOG.debug("C#:write18"); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); From 855ee9bb38b2c44e17b70236fe67aff6b8e5a1c5 Mon Sep 17 00:00:00 2001 From: "c.gromer" Date: Fri, 24 May 2019 14:57:16 +0200 Subject: [PATCH 10/15] missing value nodes now inserted --- .../org/jabylon/csharp/CSharpConverter.java | 178 +++++------------- 1 file changed, 51 insertions(+), 127 deletions(-) diff --git a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java index 3c38f66..5ba1781 100644 --- a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java +++ b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java @@ -10,6 +10,7 @@ import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import javax.xml.parsers.DocumentBuilder; @@ -49,14 +50,13 @@ public class CSharpConverter implements PropertyConverter{ private static final String NAME_ATTRIBUTE = "name"; private static final String XML_SPACE = "xml:space"; - private static final String ROOT_NODE = "root"; private static final String DATA = "data"; private static final String COMMENT = "comment"; + private static final String PRESERVE = "preserve"; + private static final String VALUE = "value"; private static final String TYPE = "type"; private static final String SYSTEM_STRING = "System.String"; - private static final String NO_TRANS = "No_Translation"; // denotes a property a non-candidate for translation (most of the properties are non-candidates) - private static final Logger LOG = LoggerFactory.getLogger(CSharpConverter.class); /** @@ -64,12 +64,9 @@ public class CSharpConverter implements PropertyConverter{ */ private boolean prettyPrint = true; - private URI uri; - private String comment; public CSharpConverter(URI resourceLocation, boolean prettyPrint) { - this.uri = resourceLocation; this.prettyPrint = prettyPrint; LOG.debug("C#:CSharpConverter1"); } @@ -131,8 +128,7 @@ public PropertyFile load(InputStream in, String encoding) throws IOException { } catch (TransformerException te) { LOG.error("C#:load8, nodeToString Transformer exception: ", te); } - - file.setLicenseHeader(resFileAsString); // we take the license header to store everything from our resx file that should not be treated by Jabylon + file.setLicenseHeader(resFileAsString); // we take the license header to store everything from our .resx return file; @@ -151,7 +147,7 @@ public PropertyFile load(InputStream in, String encoding) throws IOException { * @param node * @param file * @return true: node is provided for translation - * false: node is not provided for translation and therefore transferred to licenseHeader for not being lost (no child left behind) + * false: node is not provided for translation */ private boolean loadNode(Node node, PropertyFile file) { Property property = PropertiesFactory.eINSTANCE.createProperty(); @@ -211,7 +207,6 @@ private boolean loadNode(Node node, PropertyFile file) { LOG.debug("C#:loadNode10, comment was set: " + comment); property.setComment(comment); } - comment = null; file.getProperties().add(property); return true; @@ -263,7 +258,7 @@ private boolean loadString(Node node, Property property) { private Node getValueNode(Node node) { LOG.debug("C#:getValueNode1"); - Node childNode = getChildNode(node, "value"); + Node childNode = getChildNode(node, VALUE); return childNode; } @@ -295,26 +290,10 @@ private Node getChildNode(Node node, String desiredNodeName) { } - - /** - * decodes a string - * @param textContent - * @return the decoded string - */ - private String decode(String textContent) { - if(textContent==null) { - LOG.error("C#:decode1, textContent is null" ); - return null; - } - LOG.debug("C#:decode2, textContent: " + textContent); - return textContent; - } - - @Override public int write(OutputStream out, PropertyFile file, String encoding) throws IOException { try { - LOG.debug("C#:write1, file:" + file.toString() + " encoding: " + encoding); + LOG.debug("C#:write1, file:" + file.toString() + " encoding: " + encoding + " out: " + out.toString()); int counter = 0; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); @@ -328,8 +307,6 @@ public int write(OutputStream out, PropertyFile file, String encoding) throws IO if(isFilled(licenseHeader)) { LOG.debug("C#:write3, licenseHeader: " + licenseHeader); - - Document docLicenseHeader = null; try { document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(licenseHeader))); @@ -339,74 +316,79 @@ public int write(OutputStream out, PropertyFile file, String encoding) throws IO } EList properties = file.getProperties(); - LOG.debug("C#:write9, Count Properties: " + properties.size()); for (Property property : properties) { - LOG.debug("C#:write10, property: " + property.toString()); try { XPath xPath = XPathFactory.newInstance().newXPath(); - - String searchStr = "//data[@name=\"" + property.getKey() + "\"]"; - - LOG.debug("C#:write11, searchstr: " + searchStr); + Node nodeWithValue = GetNodeWithValue(document, property.getKey(), xPath); - Node nodeWithValue = (Node)xPath.evaluate(searchStr, document, XPathConstants.NODE); + if (null == nodeWithValue) { + LOG.debug("C#:write11, node not found"); + Node rootNode = (Node)xPath.evaluate("/root", document, XPathConstants.NODE); + + Element newElem = document.createElement(DATA); + newElem.setAttribute(NAME_ATTRIBUTE, property.getKey()); + newElem.setAttribute(XML_SPACE, PRESERVE); + rootNode.appendChild(newElem); + nodeWithValue = GetNodeWithValue(document, property.getKey(), xPath); + } + LOG.debug("C#:write12, nodeWithValue: " + nodeWithValue); - LOG.debug("C#:write12, nodeWithValue.getNodeName: " + nodeWithValue.getNodeName() + " nodeWithValue.getTextContent: " + nodeWithValue.getTextContent() + " nodeWithValue.getNodeValue: " + nodeWithValue.getNodeValue() + " nodeWithValue.getNodeType: " + nodeWithValue.getNodeType()); + LOG.debug("C#:write13, nodeWithValue.getNodeName: " + nodeWithValue.getNodeName() + " nodeWithValue.getTextContent: " + nodeWithValue.getTextContent() + " nodeWithValue.getNodeValue: " + nodeWithValue.getNodeValue() + " nodeWithValue.getNodeType: " + nodeWithValue.getNodeType()); + String newVal = property.getValue(); + // remove the carriage return: + newVal = newVal.replaceAll("\\r", ""); Node valueNode = getValueNode(nodeWithValue); if (null != valueNode) { - String newVal = property.getValue(); - // remove the carriage return: - newVal = newVal.replaceAll("\\r", ""); - LOG.debug("C#:write13, newVal: " + newVal); + LOG.debug("C#:write14, newVal replaced: " + newVal); valueNode.setTextContent(newVal); } - - + else { + Element newElem = document.createElement(VALUE); + Node newNode = nodeWithValue.appendChild(newElem); + LOG.debug("C#:write15, value node inserted: " + newVal); + newElem.setTextContent(newVal); + } + String newComment = property.getComment(); - // remove the carriage return: - newComment = newComment.replaceAll("\\r", ""); if (null != newComment) { - LOG.debug("C#:write14, newComment: " + newComment); + // remove the carriage return: + newComment = newComment.replaceAll("\\r", ""); + LOG.debug("C#:write16, newComment: " + newComment); Node commentNode = getCommentNode(nodeWithValue); if (null != commentNode) { - LOG.debug("C#:write15, comment replaced"); + LOG.debug("C#:write17, comment replaced: " + newComment); commentNode.setTextContent(newComment); } else { Node newNode = nodeWithValue.appendChild(document.createElement(COMMENT)); - LOG.debug("C#:write16, comment inserted"); + LOG.debug("C#:write18, comment inserted"); newNode.setTextContent(newComment); } } - } catch (Exception e) { - LOG.error("C#:write17 ", e); + LOG.error("C#:write19 ", e); } } - LOG.debug("C#:write18"); - + LOG.debug("C#:write20"); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); if(prettyPrint){ - LOG.debug("C#:write18"); + LOG.debug("C#:write21"); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); } DOMSource source = new DOMSource(document); StreamResult result = new StreamResult(out); - LOG.debug("C#:write19"); - + LOG.debug("C#:write22"); transformer.transform(source, result); - - LOG.debug("C#:write20"); - + LOG.debug("C#:write23"); return counter; } catch (ParserConfigurationException e) { throw new IOException(e); @@ -419,75 +401,17 @@ public int write(OutputStream out, PropertyFile file, String encoding) throws IO } } - - private boolean writeProperty(Element root, Document document, Property property) throws IOException { - LOG.debug("C#:writeProperty1"); - String value = property.getValue(); - LOG.debug("C#:writeProperty2, value of property: " + value); - if(!isFilled(value)) { - LOG.error("C#:writeProperty3, value not filled"); - return false; - } - - writeCommentAndAnnotations(root, document, property); - - // property was created by a translatable xml-element. So write back the translation - writeString(root,document,property); - return true; - } - - - private void writeCommentAndAnnotations(Element root, Document document, Property property) throws IOException { - LOG.debug("C#:writeCommentAndAnnotations1"); - if(property.eIsSet(PropertiesPackage.Literals.PROPERTY__COMMENT) || property.getAnnotations().size()>0) - { - LOG.debug("C#:writeCommentAndAnnotations2"); - String comment = property.getCommentWithoutAnnotations(); - LOG.debug("C#:writeCommentAndAnnotations3, comment: " + comment); - StringBuilder builder = new StringBuilder(); - for (PropertyAnnotation annotation : property.getAnnotations()) { - builder.append(annotation); - LOG.debug("C#:writeCommentAndAnnotations4, builder: " + builder.toString()); - } - if(builder.length()>0 && comment!=null && comment.length()>0 ) - { - builder.append("\n"); - LOG.debug("C#:writeCommentAndAnnotations5, builder: " + builder.toString()); - } - builder.append(comment); - String builtComment = builder.toString(); - LOG.debug("C#:writeCommentAndAnnotations6, builder: " + builtComment); - Comment node = document.createComment(builtComment); - root.appendChild(node); - LOG.debug("C#:writeCommentAndAnnotations7"); - } - } - - private void writeString(Element root, Document document, Property property) { - LOG.debug("C#:writeString1"); - Element data = document.createElement(DATA); - LOG.debug("C#:writeString2"); - root.appendChild(data); - - String key = property.getKey(); - LOG.debug("C#:writeString3, key: " + key); - data.setAttribute(NAME_ATTRIBUTE, key); - - String value = property.getValue(); - LOG.debug("C#:writeString4, value: " + value); - data.setTextContent(encode(value)); - } - - - private String encode(String textContent) { - if(textContent==null) { - LOG.debug("C#:encode1, textContent is null"); - return null; - } - textContent = textContent.replace("'", "\\'").replace("\"", "\\\""); - LOG.debug("C#:encode2, textContent: " + textContent); - return textContent; + private Node GetNodeWithValue(Document document, String key, XPath xPath) { + String searchStr = "//data[@name=\"" + key + "\"]"; + LOG.debug("C#:GetNodeWithValue1, searchstr: " + searchStr); + Node nodeWithValue =null; + try { + nodeWithValue = (Node)xPath.evaluate(searchStr, document, XPathConstants.NODE); + } catch (XPathExpressionException e) { + LOG.debug("C#:GetNodeWithValue2 failed with exception: ", e); + } + return nodeWithValue; } From fb4ee7b6f4db2bdd2af8c3fc2d0a7fbfbc0be8ff Mon Sep 17 00:00:00 2001 From: "c.gromer" Date: Mon, 27 May 2019 16:24:27 +0200 Subject: [PATCH 11/15] Entries that the developer denotes not to be translated don't get translated --- .../org/jabylon/csharp/CSharpConverter.java | 112 +++++++----------- 1 file changed, 46 insertions(+), 66 deletions(-) diff --git a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java index 5ba1781..3328c1c 100644 --- a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java +++ b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java @@ -56,7 +56,8 @@ public class CSharpConverter implements PropertyConverter{ private static final String VALUE = "value"; private static final String TYPE = "type"; private static final String SYSTEM_STRING = "System.String"; - + private static final String INVARIANT = "@Invariant"; // denotes non translatable content + private static final Logger LOG = LoggerFactory.getLogger(CSharpConverter.class); /** @@ -150,7 +151,6 @@ public PropertyFile load(InputStream in, String encoding) throws IOException { * false: node is not provided for translation */ private boolean loadNode(Node node, PropertyFile file) { - Property property = PropertiesFactory.eINSTANCE.createProperty(); String name = node.getNodeName(); LOG.debug("C#:loadNode1, Name: " + name); @@ -161,21 +161,30 @@ private boolean loadNode(Node node, PropertyFile file) { } NamedNodeMap namedNodeMap = node.getAttributes(); - if (null != namedNodeMap) { - for (int j=0; j>")) { - LOG.debug("C#:loadNode4, node value not appropriate"); + if (null == namedNodeMap) { + LOG.error("C#:loadNode3, namedNodeMap is null"); + return false; + } + + Node namedNode = namedNodeMap.getNamedItem(NAME_ATTRIBUTE); + if (null == namedNode) { + LOG.error("C#:loadNode4, NAME_ATTRIBUTE not found"); + return false; + } + + for (int j=0; j>")) { + LOG.debug("C#:loadNode6, node value not appropriate"); + return false; + } + if (true == attribute.getNodeName().equals(TYPE)) { + if (false == attribute.getNodeValue().equals(SYSTEM_STRING)) { + LOG.debug("C#:loadNode7, type attribute found which is not appropriate"); return false; } - if (true == attribute.getNodeName().equals(TYPE)) { - if (false == attribute.getNodeValue().equals(SYSTEM_STRING)) { - LOG.debug("C#:loadNode5, type attribute found which is not appropriate+"); - return false; - } - } } } @@ -183,75 +192,48 @@ private boolean loadNode(Node node, PropertyFile file) { NodeList childNodes = node.getChildNodes(); int childNodesLength = childNodes.getLength(); - LOG.debug("C#:loadNode6, nodesLength: " + childNodesLength); + LOG.debug("C#:loadNode8, nodesLength: " + childNodesLength); for (int k = childNodesLength-1; k >= 0; k--) { Node childNode = childNodes.item(k); String nodeName = childNode.getNodeName(); String nodeContent = childNode.getTextContent(); - LOG.debug("C#:loadNode7, childNode_" + k + " Name: " + nodeName + " Value: " + childNode.getNodeValue() + " Content: " + nodeContent + " Type: " + childNode.getNodeType()); + LOG.debug("C#:loadNode9, childNode_" + k + " Name: " + nodeName + " Value: " + childNode.getNodeValue() + " Content: " + nodeContent + " Type: " + childNode.getNodeType()); if (null != nodeName) { if (nodeName.equals(COMMENT)) { - LOG.debug("C#:loadNode8, comment found"); - comment = nodeContent; + LOG.debug("C#:loadNode10, comment found"); + if (nodeContent.equals(INVARIANT)) { // identifies an entry that is not provided for translation + LOG.debug("C#:loadNode11, comment indicates that this entry is not provided for translation, nodeContent: " + nodeContent); + return false; + } + else { + comment = nodeContent; + } } } } - if (false == loadString(node, property)) { - LOG.debug("C#:loadNode9, node not appropiate"); - return false; - } - - if (null != comment) { - LOG.debug("C#:loadNode10, comment was set: " + comment); - property.setComment(comment); - } - comment = null; - file.getProperties().add(property); - return true; - } - - - /** - * - * @param node e.g.: - Banana.AutoCode - - * @param property - * @return true: node is provided for translation - * false: node is not provided for translation and therefore transferred to licenseHeader for not being lost - */ - private boolean loadString(Node node, Property property) { - LOG.debug("C#:loadString1, node.getTextContent(): " + node.getTextContent() + " property: " + property.getValue() + " type: " + node.getNodeType()); - - NamedNodeMap namedNodeMap = node.getAttributes(); - - if (null == namedNodeMap) { - LOG.error("C#:loadString2, namedNodeMap is null"); - return false; - } - - Node namedNode = namedNodeMap.getNamedItem(NAME_ATTRIBUTE); - - if (null == namedNode) { - LOG.error("C#:loadString3, NAME_ATTRIBUTE not found"); - return false; - } - String textContentName = namedNode.getTextContent(); - - LOG.debug("C#:loadString4, textContentName: " + textContentName); - + LOG.debug("C#:loadNode13, textContentName: " + textContentName); + + Property property = PropertiesFactory.eINSTANCE.createProperty(); String key = namedNode.getNodeValue(); property.setKey(key); - LOG.debug("C#:loadString6, provided for translation "); + LOG.debug("C#:loadNode14, provided for translation "); Node valueNode = getValueNode(node); if (null != valueNode) { property.setValue(valueNode.getTextContent()); } + + if (null != comment) { + LOG.debug("C#:loadNode15, comment was set: " + comment); + property.setComment(comment); + } + comment = null; + LOG.debug("C#:loadNode16, property to be added"); + file.getProperties().add(property); return true; } @@ -303,7 +285,6 @@ public int write(OutputStream out, PropertyFile file, String encoding) throws IO LOG.debug("C#:write2"); String licenseHeader = file.getLicenseHeader(); - if(isFilled(licenseHeader)) { LOG.debug("C#:write3, licenseHeader: " + licenseHeader); @@ -349,7 +330,6 @@ public int write(OutputStream out, PropertyFile file, String encoding) throws IO } else { Element newElem = document.createElement(VALUE); - Node newNode = nodeWithValue.appendChild(newElem); LOG.debug("C#:write15, value node inserted: " + newVal); newElem.setTextContent(newVal); } From fbc80ef1fb3c1812efcb803982033001c815fc4e Mon Sep 17 00:00:00 2001 From: "c.gromer" Date: Tue, 28 May 2019 10:59:11 +0200 Subject: [PATCH 12/15] minor mod. --- .../org/jabylon/csharp/CSharpConverter.java | 4 --- .../org/jabylon/csharp/CSharpScanner.java | 25 +++++++++---------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java index 3328c1c..73089c4 100644 --- a/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java +++ b/csharp/src/main/java/org/jabylon/csharp/CSharpConverter.java @@ -75,10 +75,7 @@ public CSharpConverter(URI resourceLocation, boolean prettyPrint) { @Override public PropertyFile load(InputStream in, String encoding) throws IOException { - // TODO Auto-generated method stub - LOG.debug("C#:load0, in: " + in.toString()); - try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setIgnoringComments(false); @@ -152,7 +149,6 @@ public PropertyFile load(InputStream in, String encoding) throws IOException { */ private boolean loadNode(Node node, PropertyFile file) { String name = node.getNodeName(); - LOG.debug("C#:loadNode1, Name: " + name); if(false == name.equals(DATA)){ diff --git a/csharp/src/main/java/org/jabylon/csharp/CSharpScanner.java b/csharp/src/main/java/org/jabylon/csharp/CSharpScanner.java index 8b58bc3..dafda72 100644 --- a/csharp/src/main/java/org/jabylon/csharp/CSharpScanner.java +++ b/csharp/src/main/java/org/jabylon/csharp/CSharpScanner.java @@ -125,9 +125,7 @@ private boolean countingPeriodsFullfillsTemplateFileCondition(File propertyFile) private boolean isResourceFile(File propertyFile) { LOG.debug("C#:isResourceFile2, propertyFile: " + propertyFile.getName()); - boolean isResFile = false; - if(propertyFile.getName().endsWith(".resx")) { LOG.debug("C#:isResourceFile3: resource file" ); isResFile = true; @@ -142,8 +140,7 @@ public File findTemplate(File propertyFile, ScanConfiguration config) { LOG.info("C#:findTemplate1"); if (isTranslation(propertyFile, config)) { String fileName = propertyFile.getName(); - LOG.debug("C#:findTemplate2: fileName: " + fileName ); - // e.g.: Resources.nl.resx + LOG.debug("C#:findTemplate2: fileName: " + fileName ); // e.g.: Resources.nl.resx String[] strings = fileName.split(".", -1); if (3 == strings.length) { String templateFile = strings[0] + "." + strings[2]; // e.g.: Resources.resx @@ -199,9 +196,11 @@ public File computeTranslationPath(File template, Locale templateLocale, Locale LOG.debug("C#:computeTranslationPath1, template:" + template.getName() + " template.getPath: " + template.getPath()); File folder = template.getParentFile(); // template and translation files reside in the same folder - LOG.debug("C#:computeTranslationPath2, folder: " + folder.getName()); - LOG.debug("C#:computeTranslationPath2.1, folder.getPath: " + folder.getPath()); - LOG.debug("C#:computeTranslationPath2.2, folder.getParent: " + folder.getParent()); + if (null != folder) { + LOG.debug("C#:computeTranslationPath2, folder: " + folder.getName()); + LOG.debug("C#:computeTranslationPath2.1, folder.getPath: " + folder.getPath()); + LOG.debug("C#:computeTranslationPath2.2, folder.getParent: " + folder.getParent()); + } return folder; } @@ -216,7 +215,7 @@ public Locale getLocale(File propertyFile) { String[] splittedPropFileName = propFileName.split("\\."); String language = ""; // "en" in "en_US" - String culture = ""; // "US" in "en_US" + String culture = ""; // "US" in "en_US" but there is also "Hans" in "zh-Hans" boolean isTemplate = false; if (1 == splittedPropFileName.length) { @@ -238,13 +237,12 @@ else if (3 == splittedPropFileName.length){ LOG.debug("C#:getLocale7, splittedPropFileName[splittedPropFileName.length-2].substring(2,3): " + splittedPropFileName[splittedPropFileName.length-2].substring(2,3)); if ("-".equals(splittedPropFileName[splittedPropFileName.length-2].substring(2,3))) { LOG.debug("C#:getLocale8, language + culture "); - language = splittedPropFileName[splittedPropFileName.length-2].substring(0,2); - culture = splittedPropFileName[splittedPropFileName.length-2].substring(3); + language = splittedPropFileName[splittedPropFileName.length-2].substring(0,2); // two chars + culture = splittedPropFileName[splittedPropFileName.length-2].substring(3); // can be more than two chars } } } } - Locale loc = null; if (false == isTemplate) { @@ -274,7 +272,8 @@ public PropertyConverter createConverter(URI resource) { @Override public String getEncoding() { - LOG.debug("C#:getEncoding1"); - return "UTF-8"; + String encoding = "UTF-8"; + LOG.debug("C#:getEncoding1, encoding: " + encoding); + return encoding; } } From 0c4b3e88383a4bd6db1059fcaed1e965a6571414 Mon Sep 17 00:00:00 2001 From: "c.gromer" Date: Wed, 29 May 2019 17:25:23 +0200 Subject: [PATCH 13/15] Unit tests added --- csharp/src/test/Resources/TestRibbon.de.resx | 129 +++++++++ csharp/src/test/Resources/TestRibbon.nl.resx | 141 ++++++++++ csharp/src/test/Resources/TestRibbon.resx | 253 ++++++++++++++++++ .../test/java/org/jabylon/csharp/AppTest.java | 38 --- .../jabylon/csharp/CSharpConverterTest.java | 63 +++++ .../org/jabylon/csharp/CSharpScannerTest.java | 94 +++++++ 6 files changed, 680 insertions(+), 38 deletions(-) create mode 100644 csharp/src/test/Resources/TestRibbon.de.resx create mode 100644 csharp/src/test/Resources/TestRibbon.nl.resx create mode 100644 csharp/src/test/Resources/TestRibbon.resx delete mode 100644 csharp/src/test/java/org/jabylon/csharp/AppTest.java create mode 100644 csharp/src/test/java/org/jabylon/csharp/CSharpConverterTest.java create mode 100644 csharp/src/test/java/org/jabylon/csharp/CSharpScannerTest.java diff --git a/csharp/src/test/Resources/TestRibbon.de.resx b/csharp/src/test/Resources/TestRibbon.de.resx new file mode 100644 index 0000000..a2e36d3 --- /dev/null +++ b/csharp/src/test/Resources/TestRibbon.de.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + BIS FileExchange SyncManager Status-Übersicht + + + BIS FileExchange Einstellungen... + + + Über BIS FileExchange... + + \ No newline at end of file diff --git a/csharp/src/test/Resources/TestRibbon.nl.resx b/csharp/src/test/Resources/TestRibbon.nl.resx new file mode 100644 index 0000000..5ba5a81 --- /dev/null +++ b/csharp/src/test/Resources/TestRibbon.nl.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + BIS FileExchange SyncManager status overzicht + + + BIS FileExchange voorkeuren … + + + Over BIS FileExchange ... + + + BIS FileExchange bestanden of permissies als bijlage toevoegen + + + Toon permissie instellingen + + + Toon de eigenschappen van de permissies + + + Activering van permissive weergave-instellingen. + + \ No newline at end of file diff --git a/csharp/src/test/Resources/TestRibbon.resx b/csharp/src/test/Resources/TestRibbon.resx new file mode 100644 index 0000000..4618176 --- /dev/null +++ b/csharp/src/test/Resources/TestRibbon.resx @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + BIS FileExchange SyncManager Status Overview + + + SeeFxSyncManagerStateViewButton + + + Microsoft.VisualStudio.Tools.Office.Ribbon.View.ButtonView, Microsoft.VisualStudio.Tools.Office.Designer, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + GroupWindow + + + 0 + + + BIS FileExchange + @Invariant + + + GroupWindow + + + Microsoft.VisualStudio.Tools.Office.Ribbon.View.GroupView, Microsoft.VisualStudio.Tools.Office.Designer, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + tab1 + + + 0 + + + TabView + @Invariant + + + tab1 + + + Microsoft.VisualStudio.Tools.Office.Ribbon.View.TabView, Microsoft.VisualStudio.Tools.Office.Designer, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + BIS FileExchange Prefs... + + + SeeFxPrefsButton + + + Microsoft.VisualStudio.Tools.Office.Ribbon.View.ButtonView, Microsoft.VisualStudio.Tools.Office.Designer, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + SeeFxToolBarButton.Items + + + 0 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAACwwAAAsMAT9AIsgAAAB6SURBVDhPpYwBDoRACAPv/5/mUgqxENCNNpkqLezPzMCm + 7FdgFH6VSxhWYPxMPCu2+uEJIf5NCyfglN6KU3Dq/kHxjLw6se0gprdCSS1deCuSTdKHR5BHfYY0ky68 + hq6e6Sw5fdN0pGCFXkOXZhtYo9ewzHdg1f21zP7N7NRI5EAs1QAAAABJRU5ErkJggg== + + + + About BIS FileExchange... + + + SeeFxAboutButton + + + Microsoft.VisualStudio.Tools.Office.Ribbon.View.ButtonView, Microsoft.VisualStudio.Tools.Office.Designer, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + SeeFxToolBarButton.Items + + + 1 + + + SeeFxToolBarButton + + + Microsoft.VisualStudio.Tools.Office.Ribbon.View.SplitButtonView, Microsoft.VisualStudio.Tools.Office.Designer, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + group1 + + + 0 + + + BIS FileExchange + @Invariant + + + group1 + + + Microsoft.VisualStudio.Tools.Office.Ribbon.View.GroupView, Microsoft.VisualStudio.Tools.Office.Designer, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + tab2 + + + 0 + + + TabMail + @Invariant + + + tab2 + + + Microsoft.VisualStudio.Tools.Office.Ribbon.View.TabView, Microsoft.VisualStudio.Tools.Office.Designer, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + True + + + SeeFxViewRibbon.OfficeMenu + + + Microsoft.VisualStudio.Tools.Office.Ribbon.View.OfficeMenuView, Microsoft.VisualStudio.Tools.Office.Designer, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + $this + + + 0 + + \ No newline at end of file diff --git a/csharp/src/test/java/org/jabylon/csharp/AppTest.java b/csharp/src/test/java/org/jabylon/csharp/AppTest.java deleted file mode 100644 index 8a9ea3c..0000000 --- a/csharp/src/test/java/org/jabylon/csharp/AppTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.jabylon.csharp; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -/** - * Unit test for simple App. - */ -public class AppTest - extends TestCase -{ - /** - * Create the test case - * - * @param testName name of the test case - */ - public AppTest( String testName ) - { - super( testName ); - } - - /** - * @return the suite of tests being tested - */ - public static Test suite() - { - return new TestSuite( AppTest.class ); - } - - /** - * Rigourous Test :-) - */ - public void testApp() - { - assertTrue( true ); - } -} diff --git a/csharp/src/test/java/org/jabylon/csharp/CSharpConverterTest.java b/csharp/src/test/java/org/jabylon/csharp/CSharpConverterTest.java new file mode 100644 index 0000000..bd8f751 --- /dev/null +++ b/csharp/src/test/java/org/jabylon/csharp/CSharpConverterTest.java @@ -0,0 +1,63 @@ +package org.jabylon.csharp; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.URI; +import org.jabylon.csharp.CSharpConverter; +import org.jabylon.properties.Property; +import org.jabylon.properties.PropertyFile; +import org.junit.Before; +import org.junit.Test; + + +public class CSharpConverterTest { + + private CSharpConverter fixture; + + private static final String RESX_FILE = "src/test/resources/TestRibbon.resx"; + + @Before + public void setup() { + fixture = new CSharpConverter(URI.createFileURI(RESX_FILE), false); + } + + @Test + public void testLoad() throws IOException { + PropertyFile result = fixture.load(loadXML(new File(RESX_FILE)), "UTF-8"); + EList properties = result.getProperties(); + int sizeOfProperties = properties.size(); + assertEquals(3, sizeOfProperties); + for (int i=0; i translationFiles = fixture.findTranslations(template, null); + assertEquals(2, translationFiles.size()); + + Locale de = new Locale("de"); + if (false == translationFiles.containsKey(de)) + fail("No translation file found that was suitable for German local"); + Locale nl = new Locale("nl"); + if (false == translationFiles.containsKey(nl)) + fail("No translation file found that was suitable for Dutch local"); + + File trans_NL = getFileObject(RESX_FILE_NL); + if (false == translationFiles.containsValue(trans_NL)) + fail(" Dutch translation file not found! "); + + File trans_DE = getFileObject(RESX_FILE_DE); + if (false == translationFiles.containsValue(trans_DE)) + fail(" German translation file not found! "); + } +} From 1e07904c4662918ab4882c4ae3a23b5aac794142 Mon Sep 17 00:00:00 2001 From: "c.gromer" Date: Mon, 3 Jun 2019 09:35:41 +0200 Subject: [PATCH 14/15] changed gitignore --- .gitignore | 1 + csharp/.classpath | 8 ++------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index f5ab8b8..9ffdf26 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ target /.project +/.metadata/ diff --git a/csharp/.classpath b/csharp/.classpath index 351f14c..7f0537f 100644 --- a/csharp/.classpath +++ b/csharp/.classpath @@ -8,13 +8,8 @@ - - - - - - + @@ -23,5 +18,6 @@ + From f4720aeb02a192537ef3d0f5503b62cded2048e1 Mon Sep 17 00:00:00 2001 From: "c.gromer" Date: Mon, 3 Jun 2019 09:37:32 +0200 Subject: [PATCH 15/15] added recommenders to gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9ffdf26..17832f2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ target /.project -/.metadata/ +.metadata/ +.recommenders/ \ No newline at end of file