/** * *************************************************************************** * Copyright (c) 2010 Qcadoo Limited * Project: Qcadoo MES * Version: 1.4 * * This file is part of Qcadoo. * * Qcadoo is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation; either version 3 of the License, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *************************************************************************** */ package com.qcadoo.mes.states.service.client; import static com.qcadoo.mes.states.messages.util.MessagesUtil.*; import static org.springframework.context.i18n.LocaleContextHolder.getLocale; import java.util.List; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.qcadoo.localization.api.TranslationService; import com.qcadoo.mes.states.StateChangeContext; import com.qcadoo.mes.states.StateChangeEntityDescriber; import com.qcadoo.mes.states.constants.StateChangeStatus; import com.qcadoo.mes.states.exception.StateChangeException; import com.qcadoo.mes.states.messages.util.MessagesUtil; import com.qcadoo.mes.states.service.StateChangeContextBuilder; import com.qcadoo.mes.states.service.StateChangeService; import com.qcadoo.mes.states.service.StateChangeServiceResolver; import com.qcadoo.model.api.Entity; @Service public class StateChangeSamplesClientImpl implements StateChangeSamplesClient { @Autowired private StateChangeServiceResolver stateChangeServiceResolver; @Autowired private StateChangeContextBuilder stateChangeContextBuilder; @Autowired private TranslationService translationService; private static final Logger LOGGER = LoggerFactory.getLogger(StateChangeSamplesClient.class); @Override public Entity changeState(final Entity entity, final String targetState) { Entity resultEntity = null; final StateChangeService stateChangeService = stateChangeServiceResolver.get(entity.getDataDefinition()); if (stateChangeService == null) { resultEntity = performDummyChange(entity, targetState); } else { resultEntity = performChange(stateChangeService, entity, targetState); } return resultEntity; } @Override public void resumeStateChange(final Entity entity, final Entity stateChangeEntity) { entity.getDataDefinition().save(entity); final StateChangeService stateChangeService = stateChangeServiceResolver.get(entity.getDataDefinition()); if (stateChangeService != null) { final StateChangeEntityDescriber describer = stateChangeService.getChangeEntityDescriber(); final StateChangeContext stateChangeContext = stateChangeContextBuilder.build(describer, stateChangeEntity); stateChangeContext.setStatus(StateChangeStatus.IN_PROGRESS); stateChangeService.changeState(stateChangeContext); checkResults(stateChangeContext); } } private Entity performChange(final StateChangeService stateChangeService, final Entity entity, final String targetState) { final StateChangeEntityDescriber describer = stateChangeService.getChangeEntityDescriber(); final StateChangeContext stateChangeContext = stateChangeContextBuilder.build(describer, entity, targetState); stateChangeService.changeState(stateChangeContext); checkResults(stateChangeContext); Entity resultEntity = null; if (entity.getId() == null) { resultEntity = entity.getDataDefinition().save(entity); } else { resultEntity = entity.getDataDefinition().get(entity.getId()); } return resultEntity; } private Entity performDummyChange(final Entity entity, final String targetState) { // fire onUpdate hooks entity.getDataDefinition().save(entity); entity.setField("state", targetState); return entity.getDataDefinition().save(entity); } private void checkResults(final StateChangeContext stateChangeContext) { checkValidationErrors(stateChangeContext); if (StateChangeStatus.FAILURE.equals(stateChangeContext.getStatus())) { throw new StateChangeException("State change failed"); } } private void checkValidationErrors(final StateChangeContext stateChangeContext) { final List<Entity> messages = stateChangeContext.getAllMessages(); if (!MessagesUtil.hasValidationErrorMessages(messages)) { return; } if (LOGGER.isErrorEnabled()) { logValidationMessages(messages); } throw new StateChangeException("Entity has validation errors."); } private void logValidationMessages(final List<Entity> messages) { final StringBuilder logMessage = new StringBuilder(); logMessage.append("State change failed due to validation errors:\n"); for (Entity message : messages) { logMessage.append("\t- "); final String correspondingFieldName = getCorrespondFieldName(message); if (!StringUtils.isBlank(correspondingFieldName)) { logMessage.append(correspondingFieldName); logMessage.append(": "); } logMessage.append(translationService.translate(getKey(message), getLocale(), getArgs(message))); logMessage.append("\n"); } LOGGER.error(logMessage.toString()); } }