/*
* Copyright (c) 2005-2011 Grameen Foundation USA
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* See also http://www.apache.org/licenses/LICENSE-2.0.html for an
* explanation of the license and how it is applied.
*/
package org.mifos.application.messagecustomizer;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import org.mifos.application.admin.servicefacade.CustomizedTextDto;
import org.mifos.application.admin.servicefacade.CustomizedTextServiceFacade;
import org.mifos.core.MifosRuntimeException;
import org.mifos.framework.components.mifosmenu.MenuRepository;
import org.mifos.framework.hibernate.helper.HibernateTransactionHelper;
import org.mifos.framework.hibernate.helper.HibernateTransactionHelperForStaticHibernateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
public class CustomizedTextServiceFacadeWebTier implements CustomizedTextServiceFacade {
@Autowired
private CustomizedTextDao customizedTextDao;
@Autowired
private MessageSource messageSource;
// for testing purposes, allow these legacy objects to be injected
private HibernateTransactionHelper transactionHelper;
private MenuRepository menuRepository;
@Autowired
public CustomizedTextServiceFacadeWebTier(CustomizedTextDao customizedTextDao, MessageSource messageSource) {
super();
this.customizedTextDao = customizedTextDao;
this.messageSource = messageSource;
transactionHelper = new HibernateTransactionHelperForStaticHibernateUtil();
}
protected void setTransactionHelper(HibernateTransactionHelper hibernateTransactionHelper) {
this.transactionHelper = hibernateTransactionHelper;
}
protected MenuRepository getMenuRepository() {
if (menuRepository == null) {
menuRepository = MenuRepository.getInstance();
}
return menuRepository;
}
protected void setMenuRepository(MenuRepository menuRepository) {
this.menuRepository = menuRepository;
}
private void updateLegacyCaches() {
// legacy menu code caches strings, so force the menus to rebuild after a change
getMenuRepository().removeMenuForAllLocale();
}
@Override
public void addOrUpdateCustomizedText(String originalText, String customText) {
try {
this.transactionHelper.startTransaction();
customizedTextDao.addOrUpdateCustomizedText(originalText, customText);
this.transactionHelper.commitTransaction();
} catch (Exception e) {
this.transactionHelper.rollbackTransaction();
throw new MifosRuntimeException(e);
} finally {
this.transactionHelper.closeSession();
}
updateLegacyCaches();
}
@Override
public void removeCustomizedText(String originalText) {
try {
this.transactionHelper.startTransaction();
customizedTextDao.removeCustomizedText(originalText);
this.transactionHelper.commitTransaction();
} catch (Exception e) {
this.transactionHelper.rollbackTransaction();
throw new MifosRuntimeException(e);
} finally {
this.transactionHelper.closeSession();
}
updateLegacyCaches();
}
@Override
public Map<String, String> retrieveCustomizedText() {
return customizedTextDao.getCustomizedText();
}
/**
* Take an input message and replace any instances of customized text strings that are found in the message. If
* there end up being any performance issues around this method (for example, if the logic for this method needs to
* be more complex --regular expressions, etc.) then this method is a good candidate for using the Spring @Cacheable
* annotation mechanism
*
* @see org.mifos.application.admin.servicefacade.CustomizedTextServiceFacade#replaceSubstitutions(java.lang.String)
*/
@Override
public String replaceSubstitutions(String message) {
if (message == null)
return message;
String newMessage = message;
Map<String, String> messageFilterMap = customizedTextDao.getCustomizedText();
for (Map.Entry<String, String> entry : messageFilterMap.entrySet()) {
newMessage = newMessage.replace(entry.getKey(), entry.getValue());
}
return newMessage;
}
@Override
public CustomizedTextDto getCustomizedTextDto(String originalText) {
CustomizedText customizedText = customizedTextDao.findCustomizedTextByOriginalText(originalText);
return new CustomizedTextDto(customizedText.getOriginalText(), customizedText.getCustomText());
}
/**
* This method is used as the second step in migrating legacy customized labels to the new customized text
* mechanism. Changeset MIFOS-4633_2 copies existing custom labels to the new customized_text table with the
* original_text field as the entity name + ".Label". This was needed since the Liquibase conversion doesn't know
* what the configured locale is for Mifos or how to lookup properties values.
*
* An example of possible resulting migrated data would be: original_text: Client.Label custom_text: Borrower
*
* So we know that the "Client" entity label was customized. The method below will check for original_text entries
* that have been migrated (ie. end in ".Label" and lookup the localized text that was the default label for that
* entity. It replaces the migrated original_text with the localized text.
*
* Finally it checks to see if there are cases where original_text maps to custom_text where both are the same (this
* would happen if in the original
*/
@Override
public void convertMigratedLabelKeysToLocalizedText(Locale locale) {
Map<String, String> messageMap = retrieveCustomizedText();
for (Entry<String, String> entry : messageMap.entrySet()) {
if (entry.getKey().endsWith(".Label")) {
// create a new entry with the localized string for the label
String localizedMessageKey = messageSource.getMessage(entry.getKey(), null, locale);
addOrUpdateCustomizedText(localizedMessageKey, entry.getValue());
removeCustomizedText(entry.getKey());
}
}
messageMap = retrieveCustomizedText();
// remove any entries where the old and new messages are exactly the same
for (Entry<String, String> entry : messageMap.entrySet()) {
if (entry.getKey().equals(entry.getValue())) {
removeCustomizedText(entry.getKey());
}
}
}
}