суббота, 28 мая 2011 г.

How it was at the first week of coding

Hi there,

Finally, I began to write a code, and as funny sounds, but I really wanted to do it starting from the day, when I was accepted to GSoC! And now, I'm very happy, becuse I have a lot of work, interesting work!

So, what did I do during this week? There were two points on which I was working.
First one of my tasks was creating and testing custom localization tool for a project. In my previous post I sad that custom localization tool is a central (in both meaning of this word) component of the project structure. All magic will be around this component. It accesses resources bundles and obtains messages therein.
So, lets start from fact that I have created this tool. And it was very interesting, as for me, to accomplsih it. So, I'll tell you how to do it.
So, first, that we need, is to extend generic velocity's ResourceTool class. We are doing that to have an opportunity to load resources outside from class path (from /WEB-INF directory, for example). In generic class,  the Object get(Object k, String baseName, Object l) method is responsible for loading resources, and we simply should override him. And everything will be ok. But how to override it method, you can ask me? And I say you, that it's simply! We only should to take care about using of ourappropriate resource loader class instead of default. We just calling:

      getResourceLoader().getFileSystemResource(resourceLocation, baseName, locale);

and passing in the path, where our messages resource for specified locale is situated. It returns ResourceBundle with translated messages for that locale therein.
And, I guess, that it is all that i needed for writting our custom localization tool. All the rest behavior inherit from velocity Resource tool. But it's not enought for using such kind of velocity tool. As you know, for standalone using of any velocity tool we need to configure toolbox, that will contain all tools.
For configuring of such toolbox I used ToolManager and Factory configuration classes. The result of configurstion was velocity tool context, which can be used (merged) with standard velocity context. The code, which configures velocity toolbox is shown below:
        // creating of a manager and factory configuration
        ToolManager velocityToolManager = new ToolManager();
        FactoryConfiguration factoryConfig = new FactoryConfiguration();
       
        ToolboxConfiguration toolbox = new ToolboxConfiguration();

        // we are setting scope for this toolbox as application
        // because we wanna use it for each request
        toolbox.setScope(Scope.APPLICATION);
        // we should configure our custom tool before

        // setting it into toolbox
        ToolConfiguration localizationTool = new ToolConfiguration();
        localizationTool.setClassname(LocalizationTool.class.getName());
       
        localizationTool.setKey("l10n");
        localizationTool.setProperty("locale", new Locale(locale));
        localizationTool.setProperty("bundles", "messages");
        localizationTool.setProperty("resourceLocation", getResourceLocation(locale));
       
        toolbox.addTool(localizationTool);
        // and now we can configure toolbox
        factoryConfig.addToolbox(toolbox);
        velocityToolManager.configure(factoryConfig);
        toolContext = velocityToolManager.createContext();


And further, I've "merged" this toolConext with velocity context, which had allowed us to use configured tool directly within our templates:

        VelocityContext velocityContext = new VelocityContext(toolContext );

You can also to argue to me, "why aren't you using toolbox.xml file for configuring tool?" for example. Relax. Using of such approach in this case isn't acceptable, because we are targeted to the best performance, and using additional servlet and one more xml file on  file system isn't good for it. With using java code to configure toolbox we are pretty flexible and fast. Moreover, in our case (we are tied to servlet's filters) we can use only standalone variant of velocity toolbox (without VelocityViewServlet, which, nevertheless, great simplifies using of toolbox).
Well now, this is just enough for creating custom localization tool. What was the second of my tasks for this week? It was creating of new page for selecting preferred language as first step of setup wizard.


This page should be as much as simply. So, I added only few components onto it (i.e. selection list for choosing language, checkbox for indicationg that it's need to remeber user's choise and button for continue as next arrow).  But anyway it looks good and has enough functionality, as other suchlike pages.

I think, that is enough for this time, if anybody has a question, I'm ready to tell you what you want,

With best wishes, Taras Chorny!




воскресенье, 22 мая 2011 г.

Design review of project's structure

Hi all,
It was really hard-working week, so I'm writting my post not as usual. But, anyway, I'm going to tell you, my dear reader, about work on design of project's structural and behavioural aspects.
So, after I have made an overview of subject domain (i.e. localization tools) I started phase of project's design. On this pahase I was focused on developing robust and flexible model of project's structure. I tried to figure out the project's structure for few times, and each next time I was so far to right decision. But something was bugging me, each of next decision seemed to me frightfull, and I was starting everything over again. 


Nevertheless, I found the way, so I'm going to slightly open the curtain, wich is covered over this.

Initially, the project structure can be represented as a set of interrelated components. Links between these components may be different. Also, components themselves, might be devided on two groups: inner and outer.

Inner components, which is represents the core of project. They should be developed from scratch. Together, these components will work as some kind of localization tool. The main function of that tool will be obtaining  localized GUI messages, which is stored in resource files and providing an easy way for accessing them directly  from velocity templates. Also, it would be great to have such tool as flexible as possible, in fact, that tool should support an easy way of changing its configuration by other components.

And, in turn, outer components represents an existing servlets filters (into which will be integrated functionality of configuring inner localization tool) and message resource files (which will be accessed through localization tool). I can say, that project components structure was designed to provide the easiest way of integrating localization tool into initial setup and update wizards. Next figure shows as diagram which describes project structure:
Lets make a review of this diagram starting from outer components ('cause, I suggest that most of you have a questions about it). Outer components are:
  • UpdateFilter and InitializationFilter;
  •  messages.properties* files.
As we can see at picture above, UpdateFilter and InitializationFilter are the components which are representing an appropriate existing servlet filters. Basically, these filters are used for managing the general work flow of both wizards, they control navigation between pages within wizards, they create and render velocoty templates for wirads pages and do job of preparing installation/update process, execute these processes.

Next outer components are named as messages.properties*. These are text files which will contain localized messages for both wizards. Those files are located under /WEB-INF directory of OpenMRS web app (see Analyze of existing L10n tools for velocity templates). Example of their content is shown on related text notes on diagram above.
 So, I think that everything so far is clear. And I can begin description of such "lovely" thing as inner components, they are:
  • custom localization tool;
  • filter utility.

As you might guess from component's layout the key component of structure is custom localization tool. This is a central (in both meaning of this word) component of the project structure. All magic will be around this component. It accesses resources bundles and obtains messages therein.

Such component will be implemented as sub-class of velocity’s ResourceTool class. Creating of sub-class, instead of using standard tool can be explained with need to load resources outside the web-app classpath. For achieve this we will simply override get(Key) method, that is responsible for loading the resources. When we will implement this method ,we should take care about loading messages.properties* from file system by specified path.

Using of this approach will allow as to type $locale.install.method instead of $l10n.get(‘locale.install.method '), for showing localized content.

Also component will contain map with resources bundles for each locale. Moreover,  it should be configurable. This means that this component should provide opportunity to easily change its parameters in run-time.

 And the last important inner component is filter utility. This component should manage locales parameters. It will check whether need to save user’s selected language, will retrieve it locale from http session if need, and will store it into DB as admin’s user property. Also it will try to retrieve that persisted language in case of DB update wizard running.

Since we will use custom velocity resource tool we will need to configure appropriate toolbox.  Admittedly, this component will manage configuring of localization tool by using java API. For this we will use EasyFactoryConfiguration class from velocity framework. Filter utility will be implemented as java class (or set of classes under the same package). Access to localization tool component will be provided through this one.


That is all for now. I think, that we have reviewed all bottlenecks within project structure, 'cause it is very important to begin coding on projec, while investing as much as possible time to design.


With best wishes, Taras Chorny.


среда, 11 мая 2011 г.

Review of project requirements

Hi everyone! 

Today, after all discussions is over, I'd like to reveal the curtain over such very important aspect of my GSoC project as project requirements. Yes, we have discussed it hard with my mentor. I have made a lot of corrections, brought a lot of changes into initial version of corresponding document. But now, I expand all the project objectives and requirements on the clearly sort through.

So, the main aim of current project is to provide opportunity for users to run the setup and update wizards in their selected language. Yes, and this is very clear, I suppose that anybody doesn't have any questions about that. And we can continue. We won't going deep into details

Following to most commonly used practice, we have highlighted non functional and functional groups of requirements. I'd like to clarify that those requiremnts are described with the developer's perspective, and more closely reflect understanding of the technical details. Lets begin from functional requirements.

Functional requirements:
  •  Appropriate page should be shown for user at first step of the setup wizard (see fig. 1);
 Anyway, you must not be surprised. As the localization style of web app must be alike desktop's app, and if we wont have suchlike page, our project goal will be unreached fundamentally.

  • That page should contain selection list with all possible languages, checkbox for indicate that selected language should be persisted after wizard’s finish and navigation element (next arrow) for continue;
  • Selection list should be dynamically filled with languages basing on existing web app's message resource files;
  • The user should be able to move back and forth through the each wizard's pages by using appropriate navigation elements (arrows are preferred in case when the text displayed is in a language they don't understand so well or if they selected a wrong language by mistake);
  • When user is moving through the initial setup wizard's pages, language should not be changed until user will return to 1st page and change it;
  • Selected by user language should be saved into cookie (or as http session's attribute) during wizard’s work and (if user have marked checkbox), it should be persisted into DB as admin’s property;
  • When user is running the database update wizard, all pages should be displayed in previously persisted language or in English by default;
All functional requirements to the system can be formalized by using following use case diagram:
As you can see we have defined precisely such requirements, without which the project will not work at all or will work not as excepted. Next group is non-functional requirements.
Non-functional requirements:
  • Support for new languages should not require recompilation;
  • Access translated text with resource bundles;
  • Resource bundles should be loaded as fast as possible (on web app startup or at first request).
  • Textual elements, such as status messages and the GUI component labels of both wizards should be completely translated into most of supported languages (Italian, Spanish, French and Portuguese);
  • Employ the use of arrows as navigation elements instead of buttons with text;
  • Only Unicode encoding characters should be used for translation;
Admittedly, that without providing of these requirements, project won't be broken, but  a great usability damage will be made

So, I think that this is complete list of requirements and it will help me to do my further work as well as possible.

I will wait exactly for your comments! 

With best wishes, Taras Chorny!


 

вторник, 3 мая 2011 г.

My first steps on open source way


Hi, everyone!

At beginning of last week my proposal was accepted to GSoC 2011. I was so impressed, but today I`m not worrying so much now I see there are a lot of work, interesting work and I like this! So, now I`d like to tell you about beginning of my open source way.

Once my friend had showed me the post about announcement of GSoC program. I’ve read this post and began to move on open source way. I began to move step-by-step. I've read a lot of information about GSoC, met with guys who have participated in this program last years, asked them a lot of questions, they have answered and gave me a lot of useful advices.

I went through list of participating last year organizations. There were a lot of exciting communities and it were even greater number of interesting projects. So, I was waited impatiently for announcing this year list of participating organizations. And immediately after the announcement I began to find the most suitable community for me. Truth, there were a lot of really good candidates, and it was very difficult to me to make a decision. Eventually, I did my choice. It was OpenMRS community. And still I have no regrets about this, because it's really good community with great amount of clear documentation and excellent organization of work.

So, after choosing community and slightly later, after I’ve read introductory guides for developers and have familiarized with conventions, I found their trac with introductory tickets and began to work. And it`s great, because I began to understand what is open source!

When it was the time for sending proposal I knew, that I will make an application only exactly for one organization and for one project, and that organization will be only OpenMRS! So, I did it and was sure that I will be accepted. 

So, now I'm a participant of this program, I've already did "first" steps for accepted students and I'm beginning to speed up myself for coding.

With best wishes, Taras!