For many projects I have worked on, programming teams work with the style of placholding every piece of static text in an xhtml file into a properties file. For example:
xhtml=
...
<h1>${messages.resourceBundle['key.to.static.text.placeholder']}</h1>
...
messages.properties=
...
key.to.static.text.placeholder=This will be the heading for this page only
...
Would anybody be able to explain what the advantage in this is?
So far, I can only see the following disadvantages:
making changes to any xhtml file requires you to hunt for the correct .properties file, and then the individual property to make the change to
if others have re-used properties, then deleting them becomes tricky as you have to be certain no other page is referencing the property, therefore after several change request rounds, properties files become large with redundant properties
if there are 1000 xhtmls, there will be 1000 .properties files to load, which is more cycles on the cpu to load and inject static pieces of text
if your using WebFlow and have flows that pass into other flows, properties have to be duplicated, meaning that sometimes you must place the same property in many different properties files to render correctly
hard to read code; if you know you want to work on the text 'This will be the heading for this page' only, you'll need to work out where that is on the xhtml from the property files first - you can't simply look at the xhtml and see clearly how the content will be laid out once rendered.
The only advantages I can see are text reuse and possibly html escaping.
Apologies if its coding 101, but I've had a hunt around Google and can't find the reasoning to the pattern.
Many Thanks
This is a common practice for internationalizing content.
You create one property file per language (or locale) and use a dynamic way off resolving which one to load depending on the context. (e.g. Language HTTP header the browser sends).
It is arguably more flexible than providing 1 jsp file per language, and can still deal with complex cases where plurals or stylistic differences might change the way you write localized text.
This is a standard JDK feature, lookup resource bundles.
You do not have to build 1 file per jsp (maybe your framework works this way?), although doing so can help the person writing the translation.
Related
In the resource XML there are all these values associated with keys.I want to modify a value associated with a key directly from Java.
For instance,I have <entry key="greetingMessage">Welcome to my app</entry> and this is displayed in the view,but also the message can be modified from the view and I want to be automatically updated in the XML.
I have managed to do this by parsing and changing the XML with javax.xml and org.w3c but I feel I am missing something.Does Java internationalization or Wicket framework have a method to achieve this?
Wicket only has facilities to read i18n resources (for example, XmlFilePropertiesLoader). Properties.storeToXML() is not used in Wicket 6 code, while Properties.loadFromXML() is used to read those XML properties files.
To store those translations back to XML files you need to be cautious. At least, synchronization has to be implemented to make sure that simultaneous edits are not lost.
I'd not recommend to store the edits in XML (especially in the original XML files). It seems better to have two levels of properties:
First, immutable, level, is based on the original (and immutable) XML files.
Second level consisting of 'edits' acts like a patch over the first level. It may be stored in a database which is much more convenient for storing a constantly updating data (like such edits).
I'm wondering what the drawbacks are for using strings that are defined in the java files in Android code.
I like to use plain old Java strings for things that are not visible strings like e.g. names in XML documents that I'm parsing, or keys for bundles. Seems to be a good idea to just keep all those things in the java file where they are used instead of moving them out into an XML file and making the code more complicated.
Yet, I see many examples of Android code that seem to put every string into a resource file.
What's the issue with having strings in java files? What are the reasons that people don't do it? I've been doing it in my apps and haven't seen any issues yet so far.
Note that I'm aware that XML files make a ton of sense for stuff that needs to be translated. This question is for cases where the strings stay the same.
Let me try to make this question clearer:
Are there any reasons except:
Because it's a standard / best practise etc. - my question is basically: why is it a best practise, only because of i8n, or are there other reasons?
Because it allows you to use the resources framework for translation, device-dependent strings etc.
Because it allows you to use non-ASCII characters.
The simple answer to your question is its a standard to put all your string into resource. Also there are many reason that if you are keeping your string in xml/java file you have to update each and every reference in these file for a single string.
for eg. if You want to change "Ok" to "confirm" which are used in 5 different file you have to change in all those 5 files but for String resource you just have to update one file which string.xml.
Edit
Please find below some of reasons we should use String.xml
1) To update single reference to multiple occurrences. As according to the #treesAreEverywhere It can be done with public static String, but it will take memory on startup of application and till application is closed. But String written in String.xml will be loaded at time of use.
2) Multiple language support. You can create multiple language resource folder to support your multiple language application so language changed using Locale will be dynamically maintained by OS at run time according to language resource folder.
3) Please check Localization document which provide you more information about using string.xml
4) Strings don’t clutter up your application code, leaving it clear and easy to maintain.
It's a kind of coding standard like any other language has. But you can ignore it if you want and can create your code with public static string variable in code. It is not compulsory to use string.xml but its a good coding practice to use it. Good practice like closing the if block with parenthesis containing single statement rather than leaving it as it is.
if(condition){ statement; } rather than if(condition) statement;
Actually, good practices is a good reason to do it, but there are more.
For example, one reason that I can recall right now is that strings.xml is UTF-8 codified. Hardcoded strings doesn't show some characters properly.
The purpose of strings.xml (and other *.xml resource files) is to regroup similar values in one place. This facilitates finding values that would be otherwise buried in the code. Those resource files also makes the maintainability better, since a modification to one value can have app-wide effects (such as changing the title of the app or the theme). Finally, as you mentioned, it provides a framework for translating your app to other languages.
If you know your app will not be translated and won't be modified, it's not a bad thing to hard-code them. However, if you think your app will get a lot of updates, it is better to start using good foundations and use XML resource files.
Besides these reasons and the ones mentioned by #Zinc (which I am unaware of and cannot confirm), there are no other reasons regarding why you would want to use XML resource files.
The drawback of using resource files is that is is theoretically is slower and requires a bit more memory. Read android - strings.xml vs static constants and Does hard coding of string affect performance?
If you put all your strings which are related to your application, then you can implement I18N kind of applications very easily and it is very useful while doing application changes (Company takeover some other company). It is just change names in xml files. No need to touch any java file.
I'm following page object design pattern for Selenium automation and I can guess that many people store locators in .properties file and access them in code. It seems great to keep locators at separate place.
Since, I haven't work on any big project for Selenium automation, I would like to know thoughts on following so that I can avoid problems that might raise in future:
Is storing locators in properties file helpful in big projects(where test cases are more than 1000 or so)?
a) If not helpful in big projects, what are the difficulties that make us not to store locators in properties file?
b) If it's helpful, what are the precautions if that are taken makes job easier?
Is storing locators in page class itself is best way in comparison with properties file?
I would argue storing the files in the page class itself. Loading from properties file would incur additional overhead or parsing a large file. Maintaining such a file would also be harder, even with a good tool support you would be forced to use CTRL + F more than you should.
Even on a more conceptual level it feels wrong. A good fit for storing in properties files are configurable parameters, and especially the ones that are good candidates to be tweaked in runtime.
Locators don't have this nature. If the benefit you're seeking is declaring in a central place you should instead use dedicated constant class, which will give you much better refactoring options.
I would definitely agree with #Master Slave. The main purpose of selenium is to make the UI testing easier. Storing locators in the property file is cumbersome and additional overhead plus a nightmare for refactoring. One of the main reasons why the PageObject is popular is because it's ability to map elements with a very intuitive way
#FindBy(name="q")
private WebElement searchField;
#FindBy(name="btnG")
private WebElement searchButton;
It's just not only more readable but also far easier in case of refactoring and debugging. And, when something goes wrong on the page or changes there is a KNOWN place you go to change and you know where it is!
There are two basic ways:
1) Using FindBy annotation
#FindBy(xpath = "//*[#class = 'stackoverflow']")
private WebElement question;
2) Using By / WebElement class in the method structure
By stackoverflow = By.xpath("//*[#class = 'stackoverflow']");
WebElement stackoverflowElement = getDriver().findElement(stackoverflow);
And I completely agree with #Saifur and #MasterSlave.
I agree for the small projects with one running environment. Lets assume we have the project runs on two environments like Test and Production. Assume that in Test the locators are changed, then if you want to change code that will work properly in the both cases you should go to the branch. In case if locators placed in the property file you just change the file belongs to the environment.
I am not against storing locators in any format - either properties,INI, XML or xls as long as each file is small and manageable.
I think, as we are talking about 1000 test cases or more, for global variables [like URL, port number, username, password, email ] which are used only once, shall be stored in a separate global_variables file. Locators for EACH page can be stored in SEPARATE files. If one files is maintained for each page then locators are manageable. Pages will import ONLY file which is needed.
Clearly this approach creates more number of properties files as number of pages. This can be bettered by creating single file for related module or feature pages. Anyways as user we need to balance between less but huge locator file or more but smaller manageable locator files.
I am working on a similar strategy, where I need to decide which locator strategy is the best. What would be the best place to store the locators.
For code / property files, I have the following cons:
Time consuming to change the value of a single locator
Having stale locators/elements in the code
Makes the code bulky
Running tests on pre-prod and prod environment with different locators, results in creation of branches and duplication of code.
However, I am more inclined towards storing locators in a separate database and enabling its usage through a dashboard. I also feel this is very subjective to how your automation framework is setup. For a large scale framework, having over 1000 tests, having them separate makes more sense.
I've been given the (rather daunting) task of introducing i18n to a J2EE web application using the 2.3 servlet specification. The application is very large and has been in active development for over 8 years.
As such, I want to get things right the first time so I can limit the amount of time I need to scrawl through JSPs, JavaScript files, servlets and wherever else, replacing hard-coded strings with values from message bundles.
There is no framework being used here. How can I approach supporting i18n. Note that I want to have a single JSP per view that loads text from (a) properties file(s) and not a different JSP for each supported locale.
I guess my main question is whether I can set the locale somewhere in the 'backend' (i.e. read locale from user profile on login and store value in session) and then expect that the JSP pages will be able to correctly load the specified string from the correct properties file (i.e. from messages_fr.properties when the locale is to French) as opposed to adding logic to find the correct locale in each JSP.
Any ideas how I can approach this?
There are a lot of things that need to be taken care of while internationalizing application:
Locale detection
The very first thing you need to think about is to detect end-user's Locale. Depending on what you want to support it might be easy or a bit complicated.
As you surely know, web browsers tend to send end-user's preferred language via HTTP Accept-Language header. Accessing this information in the Servlet might be as simple as calling request.getLocale(). If you are not planning to support any fancy Locale Detection workflow, you might just stick to this method.
If you have User Profiles in your application, you might want to add Preferred Language and Preferred Formatting Locale to it. In such case you would need to switch Locale after user logs in.
You might want to support URL-based language switching (for example: http://deutsch.example.com/ or http://example.com?lang=de). You would need to set valid Locale based on URL information - this could be done in various ways (i.e. URL Filter).
You might want to support language switching (selecting it from drop-down menu, or something), however I would not recommend it (unless it is combined with point 3).
JSTL approach could be sufficient if you just want to support first method or if you are not planning to add any additional dependencies (like Spring Framework).
While we are at Spring Framework it has quite a few nice features that you can use both to detect Locale (like CookieLocaleResolver, AcceptHeaderLocaleResolver, SessionLocaleResolver and LocaleChangeInterceptor) and externalizing strings and formatting messages (see spring:message tab).
Spring Framework would allow you to quite easily implement all the scenarios above and that is why I prefer it.
String externalization
This is something that should be easy, right? Well, mostly it is - just use appropriate tag. The only problem you might face is when it comes to externalizing client-side (JavaScript) texts. There are several possible approaches, but let me mention these two:
Have each JSP written array of translated strings (with message tag) and simply access that array in client code. This is easier approach but less maintainable - you would need to actually write valid strings from valid pages (the ones that actually reference your client-side scripts). I have done that before and believe me, this is not something you want to do in large application (but it is probably the best solution for small one).
Another approach may sound hard in principle but it is actually way easier to handle in the future. The idea is to centralize strings on client side (move them to some common JavaScript file). After that you would need to implement your own Servlet that will return this script upon request - the contents should be translated. You won't be able to use JSTL here, you would need to get strings from Resource Bundles directly.
It is much easier to maintain, because you would have one, central point to add translatable strings.
Concatenations
I hate to say that, but concatenations are really painful from Localizability perspective. They are very common and most people don't realize it.
So what is concatenation then?
On the principle, each English sentence need to be translated to target language. The problem is, it happens many times that correctly translated message uses different word order than its English counterpart (so English "Security policy" is translated to Polish "Polityka bezpieczeństwa" - "policy" is "polityka" - the order is different).
OK, but how it is related to software?
In web application you could concatenate Strings like this:
String securityPolicy = "Security " + "policy";
or like this:
<p><span style="font-weight:bold">Security</span> policy</p>
Both would be problematic. In the first case you would need to use MessageFormat.format() method and externalize strings as (for example) "Security {0}" and "policy", in the latter you would externalize the contents of the whole paragraph (p tag), including span tag. I know that this is painful for translators but there is really no better way.
Sometimes you have to use dynamic content in your paragraph - JSTL fmt:format tag will help you here as well (it works lime MessageFormat on the backend side).
Layouts
In localized application, it often happens that translated strings are way longer than English ones. The result could look very ugly. Somehow, you would need to fix styles. There are again two approaches:
Fix issues as they happen by adjusting common styles (and pray that it won't break other languages). This is very painful to maintain.
Implement CSS Localization Mechanism. The mechanism I am talking about should serve default, language-independent CSS file and per-language overrides. The idea is to have override CSS file for each language, so that you can adjust layouts on-demand (just for one language). In order to do that, default CSS file, as well as JSP pages must not contain !important keyword next to any style definitions. If you really have to use it, move them to language-based en.css - this would allow other languages to modify them.
Culture specific issues
Avoid using graphics, colors and sounds that might be specific for western culture. If you really need it, please provide means of Localization. Avoid direction-sensitive graphics (as this would be a problem when you try to localize to say Arabic or Hebrew). Also, do not assume that whole world is using the same numbers (i.e. not true for Arabic).
Dates and time zones
Handling dates in times in Java is to say the least not easy. If you are not going to support anything else than Gregorian Calendar, you could stick to built-in Date and Calendar classes.
You can use JSTL fmt:timeZone, fmt:formatDate and fmt:parseDate to correctly set time zone, format and parse date in JSP.
I strongly suggest to use fmt:formatDate like this:
<fmt:formatDate value="${someController.somedate}"
timeZone="${someController.detectedTimeZone}"
dateStyle="default"
timeStyle="default" />
It is important to covert date and time to valid (end user's) time zone. Also it is quite important to convert it to easily understandable format - that is why I recommend default formatting style.
BTW. Time zone detection is not something easy, as web browsers are not so nice to send anything. Instead, you can either add preferred time zone field to User preferences (if you have one) or get current time zone offset from web browser via client side script (see Date object's methods)
Numbers and currencies
Numbers as well as currencies should be converted to local format. It is done in the similar way to formatting dates (parsing is also done similarly):
<fmt:formatNumber value="1.21" type="currency"/>
Compound messages
You already have been warned not to concatenate strings. Instead you would probably use MessgageFormat. However, I must state that you should minimize use of compound messages. That is just because target grammar rules are quite commonly different, so translators might need not only to re-order the sentence (this would be resolved by using placeholders and MessageFormat.format()), but translate the whole sentence in different way based on what will be substituted. Let me give you some examples:
// Multiple plural forms
English: 4 viruses found.
Polish: Znaleziono 4 wirusy. **OR** Znaleziono 5 wirusów.
// Conjugation
English: Program encountered incorrect character | Application encountered incorrect character.
Polish: Program napotkał nieznaną literę | Aplikacja napotkała nieznaną literę.
Character encoding
If you are planning to Localize into languages that does not support ISO 8859-1 code page, you would need to support Unicode - the best way is to set page encoding to UTF-8. I have seen people doing it like this:
<%# page contentType="text/html; charset=UTF-8" %>
I must warn you: this is not enough. You actually need this declaration:
<%#page pageEncoding="UTF-8" %>
Also, you would still need to declare encoding in the page header, just to be on the safe side:
<META http-equiv="Content-Type" content="text/html;charset=UTF-8">
The list I gave you is not exhaustive but this is good starting point. Good luck :)
You can do exactly this using JSTL standard tag library with the tag. Grab a copy of the JSTL specification, read the i8N chapters, which discuss general text + date, time, currency. Very clearly written and shows you how you can do it all with tags. You can also set things like Locale programmatically
You dont(and shouldnt) need to have a separate JSP file per locale. The hard task is to figure out the keys that arent i18n-ed and move them to a file per locale, say, messages_en.properties, messages_fr.properties and so on.
Locale calculation can happen in multiple places depending on your logic. We support user locales stored in a database as well as the browser locale. Every request that comes into your application will have a "Accept-Language" header that indicates what are the languages your browser has been configured with , with preferences, i.e. Japanese first and then English. If thats the case, the application should read the messages_ja.properties and for keys that are not in that file, fallback to messages_en.properties. The same can hold true for user locales that are stored inside the database. Please note that the standard is just to switch the language in the browser and expect the content to be i18n-ed. (We initially started with storing locale in the database and then moved to support locales from the browser). Also you will need a default anyway as translators miss copying keys and values from english (main language file) to other languages, so you will need to default to english for values that are not in other files.
Ive also found mygengo very useful when giving translation job to other people who know a particular language, its saved us a lot of time.
I'm a newbie when it comes to properties, and I read that XML is the preferred way to store these. I noticed however, that writing a regular .properties file in the style of
foo=bar
fu=baz
also works. This would mean a lot less typing (and maybe easier to read and more efficient as well). So what are the benefits of using an XML file?
In XML you can store more complex (e.g. hierarchical) data than in a properties file. So it depends on your usecase. If you just want to store a small number of direct properties a properties file is easier to handle (though the Java properties class can read XML based properties, too).
It would make sense to keep your configuration interface as generic as possible anyway, so you have no problem to switch to another representation ( e.g. by using Apache Commons Configuration ) if you need to.
The biggest benefit to using an XML file is that XML declares its encoding, while .properties does not.
If you are translating these properties files to N languages, it is possible that these files could come back in N different encodings. And if you're not careful, you or someone else could irreversibly corrupt the character encodings.
If you have a lot of repeating data, it can be simpler to process
<connections>
<connection>this</connection>
<connection>that</connection>
<connection>the other</connection>
</connections>
than it is to process
connection1=this
connection2=that
connection3=the other
especially if you are expecting to have to store a lot of data, or it must be stored in a definite hierarchy
If you are just storing a few scalar values though, I'd go for the simple Properties approach every time
If you have both hierarchical data & duplicate namespaces, then use XML.
1) To emulate just a hierarchical structure in a properties file, simply use dot notation:
a.b=The Joker
a.b.c=Batgirl
a.b=Batman
a.b=Superman
a.b.c=Supergirl
So, complex (hierarchical) data representation is *not a reason to use xml.
2) For just repeating data, we can use a 3rd party library like ini4j to peg explicitly in java a count identifier on an implicit quantifier in the properties file itself.
a.b=The Joker
a.b=Batgirl
a.b=Batman
is translated to (in the background)
a.b1=The Joker
a.b2=Batgirl
a.b3=Batman
However, numerating same name properties still doesn't maintain the specific parent-child relationships. ie. how do we represent whether Batgirl is with The Joker or Batman?
So, xml is required when both features are needed. We can now decide if the 1st xml entry is what we want or the 2nd.
[a]
[b]Joker[/b]
[b]
[c]Batgirl[/c]
[/b]
[a]
--or--
[a]
[b]Batman[/b]
[b]
[c]Batgirl[/c]
[/b]
[/a]
Further detail in ....
http://ilupper.blogspot.com/2010/05/xml-vs-properties.html
XML is handy for complex data structures and or relationships. It does a decent job for having a "common language" between systems.
However, xml comes at a cost. Its is heavy to consume. You've got to load a parser, ensure the file is in the correct format, find the information etc...
Whereas properties files is pretty light weight and easy to read. Works for simple key/value pairs.
It depends on the data you're encoding. With XML, you can define a more complex representation of the configuration data in your application. Take something like the struts framework as an example. Within the framework you have a number of Action classes that can contain 1...n number of forward branches. With an XML configuration file, you can define it like:
<action class="MyActionClass">
<forward name="prev" targetAction="..."/>
<forward name="next" targetAction="..."/>
<forward name="help" targetAction="..."/>
</action>
This kind of association is difficult to accomplish using just the key-value pair representation of the properties file. Most likely, you would need to come up with a delimiting character and then include all of the forward actions on a single property separated by this delimiting character. It's quite a bit of work for a hackish solution.
Yet, as you pointed out, the XML syntax can become a burden if you just want to state something very simple, like set feature blah to true.
The disadvantages of XML:
It is hard to read - the tags make it look busier than it really is
The hierarchies and tags make it hard to edit and more prone to human errors
It is not possible to "append" to an XML property file to introduce a new property or provide an overriding value for an existing property so that the last one wins. The ability to append a property can be very powerful - we can implement a property management logic around this so that certain properties are "hot" and we don't need to restart the instance when these change
The Java property file solves the above problems. Consistent naming conventions and dot notation can help in solving the issue of hierarchy.