/*
* #%L
* BroadleafCommerce Open Admin Platform
* %%
* Copyright (C) 2009 - 2013 Broadleaf Commerce
* %%
* 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.
* #L%
*/
package org.broadleafcommerce.openadmin.web.controller;
import org.apache.commons.lang3.StringUtils;
import org.broadleafcommerce.common.i18n.domain.TranslatedEntity;
import org.broadleafcommerce.common.i18n.domain.Translation;
import org.broadleafcommerce.common.i18n.domain.TranslationImpl;
import org.broadleafcommerce.common.i18n.service.TranslationService;
import org.broadleafcommerce.common.util.BLCMessageUtils;
import org.broadleafcommerce.common.util.StringUtil;
import org.broadleafcommerce.openadmin.dto.Entity;
import org.broadleafcommerce.openadmin.dto.SectionCrumb;
import org.broadleafcommerce.openadmin.server.security.remote.EntityOperationType;
import org.broadleafcommerce.openadmin.server.security.remote.SecurityVerifier;
import org.broadleafcommerce.openadmin.server.service.persistence.PersistenceThreadManager;
import org.broadleafcommerce.openadmin.web.controller.modal.ModalHeaderType;
import org.broadleafcommerce.openadmin.web.form.TranslationForm;
import org.broadleafcommerce.openadmin.web.form.component.ListGrid;
import org.broadleafcommerce.openadmin.web.form.entity.EntityForm;
import org.broadleafcommerce.openadmin.web.form.entity.Field;
import org.broadleafcommerce.openadmin.web.service.TranslationFormAction;
import org.broadleafcommerce.openadmin.web.service.TranslationFormBuilderService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller("blAdminTranslationController")
@RequestMapping("/translation")
public class AdminTranslationController extends AdminAbstractController {
@Resource(name = "blTranslationService")
protected TranslationService translationService;
@Resource(name = "blTranslationFormBuilderService")
protected TranslationFormBuilderService formService;
@Resource(name = "blAdminSecurityRemoteService")
protected SecurityVerifier adminRemoteSecurityService;
@Resource(name = "blAdminTranslationControllerExtensionManager")
protected AdminTranslationControllerExtensionManager extensionManager;
@Resource(name = "blPersistenceThreadManager")
protected PersistenceThreadManager persistenceThreadManager;
/**
* Invoked when the translation button is clicked on a given translatable field
*
* @param request
* @param response
* @param model
* @param form
* @param result
* @return the return view path
* @throws Exception
*/
@RequestMapping(value = "", method = RequestMethod.GET)
public String viewTranslation(HttpServletRequest request, HttpServletResponse response, Model model,
@ModelAttribute(value = "form") TranslationForm form, BindingResult result) throws Exception {
if (extensionManager != null) {
extensionManager.getProxy().applyTransformation(form);
}
adminRemoteSecurityService.securityCheck(form.getCeilingEntity(), EntityOperationType.FETCH);
List<Translation> translations =
translationService.getTranslations(form.getCeilingEntity(), form.getEntityId(), form.getPropertyName());
ListGrid lg = formService.buildListGrid(translations, form.getIsRte());
model.addAttribute("currentUrl", request.getRequestURL().toString());
model.addAttribute("form", form);
model.addAttribute("listGrid", lg);
model.addAttribute("viewType", "modal/translationListGrid");
model.addAttribute("modalHeaderType", ModalHeaderType.TRANSLATION.getType());
return "modules/modalContainer";
}
/**
* Renders a modal dialog that has a list grid of translations for the specified field
*
* @param request
* @param response
* @param model
* @param form
* @param result
* @return the return view path
* @throws Exception
*/
@RequestMapping(value = "/add", method = RequestMethod.GET)
public String showAddTranslation(HttpServletRequest request, HttpServletResponse response, Model model,
@ModelAttribute(value = "form") TranslationForm form, BindingResult result) throws Exception {
adminRemoteSecurityService.securityCheck(form.getCeilingEntity(), EntityOperationType.FETCH);
EntityForm entityForm = formService.buildTranslationForm(form, TranslationFormAction.ADD);
model.addAttribute("entityForm", entityForm);
model.addAttribute("viewType", "modal/translationAdd");
model.addAttribute("currentUrl", request.getRequestURL().toString());
model.addAttribute("modalHeaderType", ModalHeaderType.ADD_TRANSLATION.getType());
return "modules/modalContainer";
}
/**
* Saves a new translation to the database.
*
* Note that if the ceiling entity, entity id, property name, and locale code match a previously existing translation,
* this method will update that translation.
*
* @param request
* @param response
* @param model
* @param entityForm
* @param result
* @return the result of a call to {@link #viewTranslation}, which renders the list grid
* @throws Exception
*/
@RequestMapping(value = "/add", method = RequestMethod.POST)
public String addTranslation(HttpServletRequest request, HttpServletResponse response, Model model,
@ModelAttribute(value = "entityForm") EntityForm entityForm, BindingResult result) throws Exception {
final TranslationForm form = getTranslationForm(entityForm);
adminRemoteSecurityService.securityCheck(form.getCeilingEntity(), EntityOperationType.UPDATE);
SectionCrumb sectionCrumb = new SectionCrumb();
sectionCrumb.setSectionIdentifier(TranslationImpl.class.getName());
List<SectionCrumb> sectionCrumbs = Arrays.asList(sectionCrumb);
entityForm.setCeilingEntityClassname(Translation.class.getName());
entityForm.setEntityType(TranslationImpl.class.getName());
Field entityType = new Field();
entityType.setName("entityType");
String ceilingEntity = form.getCeilingEntity();
TranslatedEntity translatedEntity = TranslatedEntity.getInstance(ceilingEntity);
if (translatedEntity == null && ceilingEntity.endsWith("Impl")) {
int pos = ceilingEntity.lastIndexOf("Impl");
ceilingEntity = ceilingEntity.substring(0, pos);
translatedEntity = TranslatedEntity.getInstance(ceilingEntity);
}
entityType.setValue(translatedEntity.getFriendlyType());
Field fieldName = new Field();
fieldName.setName("fieldName");
fieldName.setValue(form.getPropertyName());
entityForm.getFields().put("entityType", entityType);
entityForm.getFields().put("fieldName", fieldName);
Entity entity = service.addEntity(entityForm, getSectionCustomCriteria(), sectionCrumbs).getEntity();
entityFormValidator.validate(entityForm, entity, result);
if (result.hasErrors()) {
entityForm.setPreventSubmit();
String jsErrorMap = resultToJS(result);
entityForm.setJsErrorMap(jsErrorMap);
model.addAttribute("entity", entity);
model.addAttribute("entityForm", entityForm);
model.addAttribute("viewType", "modal/translationAdd");
model.addAttribute("currentUrl", request.getRequestURL().toString());
model.addAttribute("modalHeaderType", ModalHeaderType.ADD_TRANSLATION.getType());
return "modules/modalContainer";
} else {
return viewTranslation(request, response, model, form, result);
}
}
/**
* analyzes the error information, and converts it into a Javascript object string, which can be passed to to the HTML form through the entityForm
* @param result
* @return
*/
private String resultToJS(BindingResult result) {
StringBuffer sb = new StringBuffer("[");
List<ObjectError> errors = result.getAllErrors();
for (ObjectError objectError : errors) {
if (objectError instanceof FieldError) {
FieldError ferr = (FieldError) objectError;
sb.append("{");
String fieldOnly = StringUtil.extractFieldNameFromExpression(ferr.getField());
sb.append("\"").append(fieldOnly).append("\":");
String localizedMessage = BLCMessageUtils.getMessage(ferr.getDefaultMessage());
sb.append("\"").append(localizedMessage).append("\"");
sb.append("},");
}
}
if (sb.length() > 1) {
sb.deleteCharAt(sb.length() - 1); //the last comma
}
sb.append("]");
return sb.toString();
}
@RequestMapping(value = "/update", method = RequestMethod.GET)
public String showUpdateTranslation(HttpServletRequest request, HttpServletResponse response, Model model,
@ModelAttribute(value = "form") TranslationForm form, BindingResult result) throws Exception {
adminRemoteSecurityService.securityCheck(form.getCeilingEntity(), EntityOperationType.FETCH);
Translation t = translationService.findTranslationById(form.getTranslationId());
form.setTranslatedValue(t.getTranslatedValue());
EntityForm entityForm = formService.buildTranslationForm(form, TranslationFormAction.UPDATE);
entityForm.setId(String.valueOf(form.getTranslationId()));
model.addAttribute("entityForm", entityForm);
model.addAttribute("viewType", "modal/translationAdd");
model.addAttribute("currentUrl", request.getRequestURL().toString());
model.addAttribute("modalHeaderType", ModalHeaderType.UPDATE_TRANSLATION.getType());
return "modules/modalContainer";
}
/**
* Updates the given translation id to the new locale code and translated value
*
* @param request
* @param response
* @param model
* @param entityForm
* @param result
* @return the result of a call to {@link #viewTranslation}, which renders the list grid
* @throws Exception
*/
@RequestMapping(value = "/update", method = RequestMethod.POST)
public String updateTranslation(HttpServletRequest request, HttpServletResponse response, Model model,
@ModelAttribute(value = "entityForm") EntityForm entityForm, BindingResult result) throws Exception {
final TranslationForm form = getTranslationForm(entityForm);
adminRemoteSecurityService.securityCheck(form.getCeilingEntity(), EntityOperationType.UPDATE);
SectionCrumb sectionCrumb = new SectionCrumb();
sectionCrumb.setSectionIdentifier(TranslationImpl.class.getName());
sectionCrumb.setSectionId(String.valueOf(form.getTranslationId()));
List<SectionCrumb> sectionCrumbs = Arrays.asList(sectionCrumb);
entityForm.setCeilingEntityClassname(Translation.class.getName());
entityForm.setEntityType(TranslationImpl.class.getName());
Field id = new Field();
id.setName("id");
id.setValue(String.valueOf(form.getTranslationId()));
entityForm.getFields().put("id", id);
entityForm.setId(String.valueOf(form.getTranslationId()));
service.updateEntity(entityForm, getSectionCustomCriteria(), sectionCrumbs).getEntity();
return viewTranslation(request, response, model, form, result);
}
/**
* Deletes the translation specified by the translation id
*
* @param request
* @param response
* @param model
* @param id
* @param form
* @param result
* @return the result of a call to {@link #viewTranslation}, which renders the list grid
* @throws Exception
*/
@RequestMapping(value = "/delete", method = RequestMethod.POST)
public String deleteTranslation(HttpServletRequest request, HttpServletResponse response, Model model,
@ModelAttribute(value = "form") final TranslationForm form, BindingResult result) throws Exception {
adminRemoteSecurityService.securityCheck(form.getCeilingEntity(), EntityOperationType.UPDATE);
SectionCrumb sectionCrumb = new SectionCrumb();
sectionCrumb.setSectionIdentifier(TranslationImpl.class.getName());
sectionCrumb.setSectionId(String.valueOf(form.getTranslationId()));
List<SectionCrumb> sectionCrumbs = Arrays.asList(sectionCrumb);
EntityForm entityForm = formService.buildTranslationForm(form, TranslationFormAction.OTHER);
entityForm.setCeilingEntityClassname(Translation.class.getName());
entityForm.setEntityType(TranslationImpl.class.getName());
Field id = new Field();
id.setName("id");
id.setValue(String.valueOf(form.getTranslationId()));
entityForm.getFields().put("id", id);
entityForm.setId(String.valueOf(form.getTranslationId()));
service.removeEntity(entityForm, getSectionCustomCriteria(), sectionCrumbs);
return viewTranslation(request, response, model, form, result);
}
/**
* Converts an EntityForm into a TranslationForm
*
* @param entityForm
* @return the converted translation form
*/
protected TranslationForm getTranslationForm(EntityForm entityForm) {
TranslationForm form = new TranslationForm();
form.setCeilingEntity(entityForm.getFields().get("ceilingEntity").getValue());
form.setEntityId(entityForm.getFields().get("entityId").getValue());
form.setLocaleCode(entityForm.getFields().get("localeCode").getValue());
form.setPropertyName(entityForm.getFields().get("propertyName").getValue());
form.setTranslatedValue(entityForm.getFields().get("translatedValue").getValue());
form.setIsRte(Boolean.valueOf(entityForm.getFields().get("isRte").getValue()));
if (StringUtils.isNotBlank(entityForm.getId())) {
form.setTranslationId(Long.parseLong(entityForm.getId()));
}
return form;
}
}