Override i18n .properties file during runtime in Grails - grails

I am trying to override the main messages.properties file during runtime. My current task requires me to package application based on a product brand. For eg, if i pass a argument like "grails dev run-app -Dbrand=a", i should be able to change the messages in .properties file based on the brand.
Another requirement is that I need have one master .properties file which contains all the messages and I want to create a seperate folder to store the messages based on brand.
For eg, my master .properties file will contain A,B,C,D and my brand .properties file will be a subset of master which will only contain A. (Th message string for A in master will definitely be different than message string in .properties file present under the brand folder). For eg, A.productName in .properties file for master could be "hello" and A.product name in .properties file could be "world".
When I do run-app with brand=a as argument, I need to be able to laod the A.product name from the .properties file under brand folder without disturbing the current state of the master .properties file.(This is so that changes do show up in git).
I looked at some approaches and the only good solution I found required getting messages from DB which I dont want to do. I want a way to override using some grails configuration or event listener.
I am assuming there needs to be a way to override the messages in the memory during run-time in grails.
Hope, my I asked my question in detail.
Please help, I am really new to grails.

I think you should look at how Localizations plugin handles this. It implements
org.springframework.context.support.AbstractMessageSource
It looks up the original message source from properties, if it is not found in a database table. Sounds like you want to archive some of the same functionality.
Grails in it self uses either
org.codehaus.groovy.grails.context.support.ReloadableResourceBundleMessageSource
or
org.codehaus.groovy.grails.context.support.PluginAwareResourceBundleMessageSource
I have not looked into wich of them is injected into the artefacts in the application.

Related

Difference between $(Build.Repository.LocalPath) and $(Build.SourcesDirectory) in TFS Build Online 2017

I am trying to figure out if there is a difference between the two pre-defined variables in TFS Online 2017: $(Build.Repository.LocalPath) and $(Build.SourcesDirectory). I have a build that uses these two variables and didn't know if I could use them interchangeably or not.
Looking at Microsoft's documentation the descriptions are as follows:
$(Build.SourcesDirectory): The local path on the agent where your source code files are downloaded. For example: c:\agent_work\1\s
By default, new build definitions update only the changed files. You can modify how files are downloaded on the Repository tab.
$(Build.Repository.LocalPath): The local path on the agent where your source code files are downloaded. For example: c:\agent_work\1\s
By default, new build definitions update only the changed files. You can modify how files are downloaded on the Repository tab.
Are these representing the same thing or am I missing something?
They're synonyms. Most standard templates and tasks use the $(Build.SourcesDirectory), so that is what I tend to use.
They often result in the same but not necessarily. As described in the docs:
If you check out multiple repositories, the behavior is as follows (and might differ from the value of the Build.SourcesDirectory variable):
The description for Build.SourcesDirectory on the same page contains a similar note.
Basically if you want to define a custom path for the self checkout and still not need to specify the extra dir, you specifically need Build.Repository.LocalPath.
For clarity, you can still use Build.SourcesDirectory to resolve to the full path if you have the usual
- checkout: self
path: s
and I'd recommend using it whenever possible if so. If you have something like
- checkout: self
path: main_project
then you'd need $(Agent.BuildDirectory)/main_project to reach the same.

TFS source control - prevent a specific line from merging

I have a Dev and a Main branch of a project. They are staged at different URLs and I hold a reference to this URL in my project in a static class:
public static class Constants
{
public const string Url = "http://staging.myurl.com";
}
Now the URL will be different in each branch, but I don't want the URLs overwriting each-other whenever I merge Dev->Main, or Main->Dev.
Is there a way of telling TFS that I don't want the line to be merged, or must this be done at file level instead?
Does anyone have any suggestions of how I can maintain independent URLs in each branch? I don't want to use a database or a config file if I can help it. Is there a simple mechanism to facilitate this in TFS?
I have thought about wrapping the line in a pre-compile #if statement and checking for a specific build configuration, but I'm curious to know if there is a better way?
As it stands, you're hard-coding infrastructure concerns directly into your application, which is bad. Your application code should be environment-agnostic.
This should be managed via a configuration file; it's one of the canonical use-cases for it. The configuration file can either be transformed into an environment-specific version at build time (via web.config transforms), or ideally, at the time of deployment, via your deployment scripts.
There's no way to ignore specific lines. You can ignore specific files (via .tfignore for TFVC, or via .gitignore for Git), but you can't just tell version control to not version control a specific line of a file.

Grails: Using "external configuration" to get a plugin's data source

I'm building a plugin that will contain sharable code and configuration for several applications. One things that I'm trying to share is the data source information. Basically I need the application to not have to define it's own data source and instead use the plugin's data source. The best way that I can think of doing this is to take advantage of the external configuration functionality that's available in Grails (http://grails.org/doc/latest/guide/conf.html#3.4%20Externalized%20Configuration). However, I'm not exactly sure how to do this. All the examples I can find online show you how to do this when using an external file on the file system somewhere. I want to use configuration files from the plugin.
According to the documentation linked to above you can specify a "config script" class to use like this:
grails.config.locations = [com.my.app.MyConfig]
This would probably work, however, I can't find documentation on what a "config script" class actually is and how to create one.
By default, the DataSource file of your plugin will not be used (it's ignored in the package stage) but you can create another file that ends with "DataSource" (eg MyPluginDataSource). This is also true for BootStrap and Config.
You will probably need to leave the application DataSource file empty.

How to configure db-reverse-engineer plugin

I am a total Grails noob trying to configure the db-reverse-engineer plugin for my first project. Documentation for the plugin indicates that I need to configure it, but I don't see where I am supposed to edit configuration.
Is there a configuration file in my project I need to edit? I have searched through the ./grails-app/conf folder for grails.plugin (the prefix for this plugin's configuration) and found nothing. An SO or Google search for how to configure grails plugins also returns void. I know this is a lame question, but how do I configure this plugin? Is there a UI I need to use, or are there files somewhere to edit?
You need to configure your database in grails-app/conf/DataSource.groovy. In particular, you'll need to provide the JDBC URL, the database dialect and the databases's username and password.
You'll also have to add some extra db-reverse-engineer configuration to grails-app/conf/Config.groovy. This file will already exist. Just append the new properties at the end.
Finally, run the reverse engineer script to generate your domain classes:
grails db-reverse-engineer
The right place for that would be the file grails-app/conf/Config.groovy.
Just add what you need at the bottom.

Access to war file name from Config.groovy and Datasource.groovy

I want to deploy my war file under several names, just renaming it seems to work fine on tomcat. This obviously then gives me different URLs. I have used request.contextPath to find my own URL within the application while it is running, but if I want e.g. to name the database file after the war file in Datasource.groovy, then there is no request object for me to look at and I am out of luck. How do I do this?
How about if you configure separate config files for each deploy using Externalized configuration
Only the values that are different for each deploy need be in these files. Then every time you create a new war, you also create a new config file for this deploy.
(of course you need to manually create it every time, but i figure you could write a script for that or use a find/replace)

Resources