How to group resources in a resource bundle? - java

What is the best approach for grouping resources in a resource bundle file? The one I see most common is to group resources by web page, an example would be:
# -- company page
company.name.lbl=Name:
company.address.lbl=Address:
# -- contact page
contact.name.lbl=Name:
contact.email.lbl=Email:
The problem with this is that a lot of fields with the same name are duplicated. Would you then recommend identifying all the common names and group them separately? Something like:
name.lbl=Name:
address.lbl=Address:
email.lbl=Email:
Of course this also has some drawbacks, if you want to change the company name label to 'Company Name' then it is possible you change the contact name label without meaning to. Of course you should create a new resource for this, but it is possible the person making the change might overlook creating a new resource.

I would keep to the former example of grouping by web page, since the text displayed on each page has its own separate context.
You could try to keep things DRY and identify all of the common text, but should the context of any page change, you may find yourself creating new resources that you would have already done if you kept the page resources separate.
Another reason for keeping the resources separated by page is that if you ever need to translate your resources, the context for creating translations will be self-evident. That helps you keep a clean separation of concerns, so your coders will not have to worry about how words might be translated, and your translators will not have to mess with any code.

The first option may mean repeating texts, but is more flexible. What happens if, for example, company name is completely different from personal name? Or if tomorrow you boss decides that the label for the name of the company should change from "Name" to "Company name".
If you use the second option you are losing most of the advantages of using resource bundles.

Related

The best practice to distinguish DTO for view and for action

can you tell me what are the best practices to distinguish DTO's which serve for transfer data for frontend (for instance show user profile) and DTO's which serve for some action (for instance create user, update user, ...)
What do you think about naming like this:
CreateUserDto, UpdateUserDto for action and UserDto, UserBaseDto for showing data on FE? I was also thinking about using suffix Command like CreateUserCommand instead of DTO suffix.
There's no distinction - in both cases you're talking about data transfer object. It's what sent back and/or forth. Moreover if your UI creates a user then it may use the same structure (hence same DTO) for GETing and POSTing - which I think is a widespread scenario.
There are no common conventions and thus your question boils down to "how to name a class or a package in my particular case" which opens a lot of possibilities. Like CreateUserDto that you suggested, or UserCreationRequestDto, or simply putting these classes into different packages.
Command is a GoF design pattern which has nothing to do with DTOs, so it may lead to confusion.

2 Classes with the same name, serving different purposes

The question I have is so weird that I couldn't even come up with a better title at the moment. Anyhow, I am looking for a way to name 2 classes but cannot figure out what would be the best way forward. I do understand this is an opinion based question but I'm stuck with this... so I would appreciate any opinion on this
Project: A
-> Class name: Call (This class will represent the call from one telephone to another) Other classes may/may not subclass this particular class and if so the name of these subclasses would probably relate somehow to the parent class (CallState, CallEndPoint, CallSomething). This Class will not know about the existence of the database, one could say this class will be part of the general telephony driver.
Project: B
-> Class name: Call? (This will represent the actual table in a database. The table will have some information about the call like call id, time it entered the system etc, but also other information that may/may not relate to the call). This class will serve essentially as a RowMapper.
Now, these 2 projects most likely will be combined down the line, and If I name the classes the same I would then end up with 2 same name classes in a single project serving 2 different purposes. Now if I was the only person to build this application I could probably digest this, but if multiple people start work on the application it will become confusing to others, especially if more classes will follow the same pattern.
I'm not entire sure what the question here is. Do you want to know if it's possible to give 2 classes the same name, or just whether it's a bad idea?
A convention that is often used for classes that are meant to model database entities, is to postfix the classname with Entity. So you could name the first class Call and the second CallEntity. This removes some ambiguity about the classes purposes. Most professional developers will also immediately make the assumption that the Entity class is supposed to represent something that is persisted.
However if you really insist on giving both classes the same name. That's perfectly possible, if you put them in separate packages. The package you put them in can also provide more clarity about the intent of the class. The first could be domain.model.Call, while the second could be domain.entity.Call
Hope this is somewhat helpful :)
Now, these 2 projects most likely will be combined down the line, and
If I name the classes the same I would then end up with 2 same name
classes in a single project serving 2 different purposes.
When inside a same application two classes with distinct responsibilities/data need to have the same simple name (that is without the package), you should indeed consider it as something to think of and very probably fix.
Of course you could define these classes in distinct packages but does it really solve your issue ? I don't think. It will make things less clear as client code could use the bad one and at each time developers manipulate/read Call in the code they have to wonder "which Call" they are currently copping with.
Today you have two distinct Call. With such permissive naming conventions, why not a new one in the future ?
Really, not a good idea.
The source of the problem is the way which you design your application.
You split the model in two pats : the agnostic persistence part in a class and the data persistence part in another class. It is a choice (that personally I avoid) but if you make this choice you have to go until the end : distinct clearly each class with a different name. This choice has to be visible and not hidden in a package name only.
For example :
Call (domain) and CallEntity (persistence) or in the reverse way CallDTO(domain) and Call(persistence)

"rename" FileItem

From the business prespective, here's the problem
We have a number of shared folders that people use, let's call it //shared/the/drive. However, our server might know this shared drive as some other name, perhaps //ir83pn3br8mwhonamesthesethingsanyway/the/drive since the networking group insists on having incredibly messed up server names. For most of the servers, it works just fine to use the simple name, but on this one, it's just not working right. So the bandaid for our problem is, in our code, to just be like "Oh you're using shared - we'll replace that with stupid name from networking.
Okay - now on to the more technical side of things:
I have a FileItem (Apache commons FileUpload module) object that might have a name //shared/the/drive/stuff/plans.doc. I need to create a FileItem that references //stupidname/the/drive/stuff/plans.doc. What should I do?
Should I edit the request object in the JSP? That sounds like a bad idea.
Should I use reflection to edit the FileItem object? That sounds like an even worse idea.
I'm not a front end guy (note which tags I have votes in... haha), really... more of a server dude... this just got dropped onto my plate. Is it possible to intercept the text box before it gets to the request, moving the change to the client side?
I can't possibly have been the first person to come across this problem. I'm not looking for code necessarily (would I mind? No I wouldn't.) but a general approach of both what will work, and/or how this sort of thing (changing what a user inputs) is handled in a 'best practicey' kind of way is most welcome.
Its not uncommon when dealing with distributed file systems to have a "fake path" which the user sees and deals with and a backend path which represent the actual node that allows you to manipulate the file in context of the request you receive.
Every page you hit on the web is not represented by the physical URL you type into the browser. Files live on CDNs, in CMS systems, are dynamically created out of databases ....whatever.
Theres no need to hack on any objects. You just wrap them with another object that contains their transient properties such as where Im going to access that file THIS time.

Correct java.util.ResourceBundle Organization

I have an internationalized project with many modules. Each module has its own set of bundles:
- database-module
+ com_naugler_project_database.properties
+ com_naugler_project_database_fr.properties
- mapping-module
+ com_naugler_project_mapping.properties
+ com_naugler_project_mapping_fr.properties
However, many of the internationalized terms are redundant (such as 'OK' or 'Cancel') and I would like have these terms in one place for easier maintenance and development.
I found this helpful explanation of ResourceBundle inheritance, but it appears as though a (not?) common ancestor would not be internationalized properly because:
- common-module
+ com_naugler_project.properties
+ com_naugler_project_fr.properties <-- this is not an ancestor
- database-module
+ com_naugler_project_database.properties
+ com_naugler_project_database_fr.properties <-- of this
Am I way off base with my bundle organization? What is the right way to provide a common internationalized ancestor?
What you want seems to be the hierarchy of Resources, that is, you probably want one class to derive from over (or being composed of some specific part and some common part).
Basically, ResourceBundle was not designed for it, and you are on your own.
But you want some advice, I suppose.
Make sure that common terms are really common. That is things like "OK", "Cancel", "Next >", "< Previous", "Open", "File", etc. will have common translations in their context. I mean it is fairly safe to translate such standard items only once, but if you want to use them in different context, you still need another entry. Why? Because "Open" button translation would be different than "Open" dialog title translation in quite a few languages.
Move all the .properties files to one place (for example a directory called "resources"). Of course module-specific files should be separated to different subdirectories...
Create a resource factory that will return an instance of the ResourceBundle class (or your own Facade - this approach will actually let you share some common bundle).
The good practice for large applications is to create some Language Pack, that is to separate language resources to their own directories (i.e. /resources/en, /resources/fr, /resources/zh-Hans). The problem with this approach, however would be the fact that you would need to implement resource fallback by yourself (with the aid of an article you mention in the question, the hierarchy is actually resource loading hierarchy). That means some special cases like falling back from language tag "nb" to "no" but not falling back from "nn"; falling back from "zh-CN" and "zh-SG" to "zh-Hans" and then to "zh" but falling back from "zh-HK" and "zh-TW" and "zh-MO" to "zh-Hant" and then to your default language, not falling from "pt-BR" to "pt" (falling back to default language instead).
Seems like a lot of work? Well, but the maintenance work afterwards would be minimal.
One thing might come in handy PropertyResourceBundle have two constructors that will let you load whatever properties file you want, namely: PropertyResourceBundle(InputStream stream) and PropertyResourceBundle(Reader reader). Honestly, in large projects standard ResourceBundle mechanism has too many limitations, so you really need your own resource access layer...
As Paweł Dyda indicated, resource bundles on their own do not support class hierarchy resolution. However the Rincl project, which my company just released, should do just what you're looking for---and handle UTF-8 .properties files and XML properties files as well. It even does message formatting for you on the fly.
As explained in the in the Rincl quick start, you can simply implement Rincled and then call getResources(); Rincl will load your resource bundles even if declared in a parent class or interface:
public class MyClass extends BaseClass implements Rincled {
…
final String userName = "Jane Doe";
//Retrieve the formatted user label based upon the current locale.
//en-US: "Settings for user Jane Doe."
//pt-BR: "Definições para usuário Jane Doe."
final String userLabel = getResources().getString("user-label", userName);
…
Rincl is available at http://rincl.io/ with an intro and even a full lesson on Java internationalization. There are many new features coming up, but the latest version should already work for you. Let me know if you have any questions or problems.

How to organize Java properties entries for internationalization?

In our app we have a messages.properties file which contains all of the strings that will be shown to the UI. We have a small app with a few screens and it's already getting unwieldy with duplicate string values throughout.
Right now we have it organized with page specific strings separated out with whitespace and comments, with a section for each jsp with the property name having a prefix of the page name. We also have sections for entities, for instance, anywhere we show the user's email address, we would reference the property user.email for the label for that input or output field. We have another section for error and status messages, and finally one last section with global messages like "Submit" and "Cancel"
There's got to be a better way, and I'm wondering if you know what it is.
I don't think there is a universal "better way". I tried Googling for "best practice" advice on this, and found nothing that talked about how best to structure the property namespace for i18n.
(This I found somewhat surprising. There's usually someone out there who is prepared to put forward their ill-considered opinions on something like this as "best practice". Or perhaps, I'm too cynical.)
FWIW, my general advice would be:
be systematic and consistent about the property names and the property file structure,.
don't be afraid to use resource bundle inheritance if there is a lot of duplication,
if the property files or resource bundles get too large, partition them.
But I expect you already know and do all of that.
Finally, don't get too hung up about getting this "just right". There is no perfect solution, and what you are currently doing is probably good enough ... according to the criteria of whoever is paying you to do this work.

Categories