Java tutorial
/* * iteraplan is an IT Governance web application developed by iteratec, GmbH * Copyright (C) 2004 - 2014 iteratec, GmbH * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by * the Free Software Foundation with the addition of the following permission * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED * WORK IN WHICH THE COPYRIGHT IS OWNED BY ITERATEC, ITERATEC DISCLAIMS THE * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * 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 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, see http://www.gnu.org/licenses or write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA. * * You can contact iteratec GmbH headquarters at Inselkammerstr. 4 * 82008 Munich - Unterhaching, Germany, or at email address info@iteratec.de. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License * version 3, these Appropriate Legal Notices must retain the display of the * "iteraplan" logo. If the display of the logo is not reasonably * feasible for technical reasons, the Appropriate Legal Notices must display * the words "Powered by iteraplan". */ package de.iteratec.iteraplan.businesslogic.service; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; import com.google.common.collect.Lists; import de.iteratec.iteraplan.businesslogic.common.MassUpdateHelper; import de.iteratec.iteraplan.common.Logger; import de.iteratec.iteraplan.common.UserContext; import de.iteratec.iteraplan.common.error.IteraplanBusinessException; import de.iteratec.iteraplan.common.error.IteraplanErrorMessages; import de.iteratec.iteraplan.common.error.IteraplanTechnicalException; import de.iteratec.iteraplan.common.util.BigDecimalConverter; import de.iteratec.iteraplan.common.util.CollectionUtils; import de.iteratec.iteraplan.common.util.DateUtils; import de.iteratec.iteraplan.model.BuildingBlock; import de.iteratec.iteraplan.model.BusinessMapping; import de.iteratec.iteraplan.model.InformationSystemRelease; import de.iteratec.iteraplan.model.TypeOfBuildingBlock; import de.iteratec.iteraplan.model.attribute.AttributeType; import de.iteratec.iteraplan.model.attribute.AttributeTypeGroupPermissionEnum; import de.iteratec.iteraplan.model.attribute.AttributeValue; import de.iteratec.iteraplan.model.attribute.BBAttribute; import de.iteratec.iteraplan.model.attribute.DateAT; import de.iteratec.iteraplan.model.attribute.DateAV; import de.iteratec.iteraplan.model.attribute.DateInterval; import de.iteratec.iteraplan.model.attribute.EnumAT; import de.iteratec.iteraplan.model.attribute.EnumAV; import de.iteratec.iteraplan.model.attribute.NumberAT; import de.iteratec.iteraplan.model.attribute.NumberAV; import de.iteratec.iteraplan.model.attribute.ResponsibilityAT; import de.iteratec.iteraplan.model.attribute.ResponsibilityAV; import de.iteratec.iteraplan.model.attribute.TextAT; import de.iteratec.iteraplan.model.attribute.TextAV; import de.iteratec.iteraplan.model.user.TypeOfFunctionalPermission; import de.iteratec.iteraplan.presentation.dialog.MassUpdate.model.BusinessMappingCmMu; import de.iteratec.iteraplan.presentation.dialog.MassUpdate.model.InformationSystemReleaseCmMu; import de.iteratec.iteraplan.presentation.dialog.MassUpdate.model.MassUpdateAttribute; import de.iteratec.iteraplan.presentation.dialog.MassUpdate.model.MassUpdateAttributeConfig; import de.iteratec.iteraplan.presentation.dialog.MassUpdate.model.MassUpdateAttributeItem; import de.iteratec.iteraplan.presentation.dialog.MassUpdate.model.MassUpdateComponentModel; import de.iteratec.iteraplan.presentation.dialog.MassUpdate.model.MassUpdateLine; /** * A service for updating and deleting multiple Entities at the same time. */ public class MassUpdateServiceImpl implements MassUpdateService { private static final Logger LOGGER = Logger.getIteraplanLogger(MassUpdateServiceImpl.class); private AttributeTypeService attributeTypeService; private AttributeValueService attributeValueService; private DateIntervalService dateIntervalService; // BuildingBlock services needed for update private Map<TypeOfBuildingBlock, EntityService<? extends BuildingBlock, Integer>> bbtToService = CollectionUtils .hashMap(); /** {@inheritDoc} */ public void initAttributes(String selectedAttributeId, List<MassUpdateLine<? extends BuildingBlock>> lines, List<MassUpdateAttributeConfig> massUpdateAttributeConfig, int attributeIndex) { MassUpdateHelper massUpdateHelper = new MassUpdateHelper(attributeValueService); // init the attribute config (header keys, ...) AttributeType attributeType = attributeTypeService .loadObjectById(BBAttribute.getIdByStringId(selectedAttributeId)); MassUpdateAttributeConfig cfg = getInitializedAttributeConfig(selectedAttributeId, attributeIndex, attributeType); massUpdateAttributeConfig.add(cfg); // set values for each line for (MassUpdateLine<? extends BuildingBlock> line : lines) { MassUpdateAttribute attribute = new MassUpdateAttribute(attributeIndex); attribute.setType(cfg.getType()); attribute.setMassUpdateAttributeItem( new MassUpdateAttributeItem(line.getBuildingBlockToUpdate(), cfg.getAttributeTypeId())); if (BBAttribute.USERDEF_ENUM_ATTRIBUTE_TYPE.equals(cfg.getType())) { attribute.setAttributeValues(cfg.getAttributeValues()); massUpdateHelper.updateEnumAvSelectionForMassUpdateItem(attribute.getMassUpdateAttributeItem(), cfg.getAttributeTypeId(), false); } else if (BBAttribute.USERDEF_RESPONSIBILITY_ATTRIBUTE_TYPE.equals(cfg.getType())) { attribute.setAttributeValues(cfg.getAttributeValues()); massUpdateHelper.updateResponsibilityAvSelectionForMassUpdateItem( attribute.getMassUpdateAttributeItem(), cfg.getAttributeTypeId(), false); } else { if (BBAttribute.USERDEF_TEXT_ATTRIBUTE_TYPE.equals(cfg.getType())) { attribute.setAttributeValues(new ArrayList<AttributeValue>()); attribute.setMultilineInput(((TextAT) attributeType).isMultiline()); } else if (BBAttribute.USERDEF_NUMBER_ATTRIBUTE_TYPE.equals(cfg.getType())) { attribute.setAttributeValues(new ArrayList<AttributeValue>()); } else if (BBAttribute.USERDEF_DATE_ATTRIBUTE_TYPE.equals(cfg.getType())) { attribute.setAttributeValues(new ArrayList<AttributeValue>()); } else { throw new IllegalArgumentException("Massupdate for " + cfg.getType() + " not implemented!"); } massUpdateHelper.updateNumberOrTextOrDateAvFieldsForMassUpdateItem( attribute.getMassUpdateAttributeItem(), cfg.getAttributeTypeId(), false); } line.addAttribute(selectedAttributeId, attribute); } } @SuppressWarnings("unchecked") private MassUpdateAttributeConfig getInitializedAttributeConfig(String selectedAttributeId, int attributeIndex, AttributeType attributeType) { String attributeTypeString = BBAttribute.getTypeByStringId(selectedAttributeId); Integer attributeId = BBAttribute.getIdByStringId(selectedAttributeId); MassUpdateAttributeConfig cfg = new MassUpdateAttributeConfig(); cfg.setHeaderKey(attributeType.getName()); cfg.setPosition(attributeIndex); cfg.setType(attributeTypeString); cfg.setAttributeTypeId(attributeId); // stuff to be done only once if (BBAttribute.USERDEF_ENUM_ATTRIBUTE_TYPE.equals(cfg.getType())) { // the attribute is an enum type. get the possible values from the db once cfg.setAttributeValues((List<AttributeValue>) attributeValueService.getAllAVs(attributeId)); } if (BBAttribute.USERDEF_RESPONSIBILITY_ATTRIBUTE_TYPE.equals(cfg.getType())) { // the attribute is an responsibility type. get the possible values from the db once cfg.setAttributeValues((List<AttributeValue>) attributeValueService.getAllAVs(attributeId)); } if (BBAttribute.USERDEF_TEXT_ATTRIBUTE_TYPE.equals(cfg.getType())) { TextAT at = (TextAT) attributeType; if (at.isMultiline()) { cfg.setMultiline(true); } } return cfg; } /** {@inheritDoc} */ @SuppressWarnings("unchecked") public <T extends BuildingBlock> T initComponentModel(MassUpdateComponentModel<T> componentModel, T buildingBlock, List<String> properties, List<String> associations) { EntityService<BuildingBlock, Integer> entityService = getEntityService(buildingBlock); T loadedEntity = (T) entityService.loadObjectById(buildingBlock.getId()); componentModel.initializeFrom(loadedEntity, properties, associations); return loadedEntity; } @SuppressWarnings("unchecked") private <T extends BuildingBlock> EntityService<BuildingBlock, Integer> getEntityService(T buildingBlock) { TypeOfBuildingBlock tobb = buildingBlock.getTypeOfBuildingBlock(); return (EntityService<BuildingBlock, Integer>) bbtToService.get(tobb); } public void setArchitecturalDomainService(ArchitecturalDomainService architecturalDomainService) { bbtToService.put(TypeOfBuildingBlock.ARCHITECTURALDOMAIN, architecturalDomainService); } public void setAttributeTypeService(AttributeTypeService attributeTypeService) { this.attributeTypeService = attributeTypeService; } public void setAttributeValueService(AttributeValueService attributeValueService) { this.attributeValueService = attributeValueService; } public void setDateIntervalService(DateIntervalService dateIntervalService) { this.dateIntervalService = dateIntervalService; } public void setBusinessFunctionService(BusinessFunctionService businessFunctionService) { bbtToService.put(TypeOfBuildingBlock.BUSINESSFUNCTION, businessFunctionService); } public void setBusinessObjectService(BusinessObjectService businessObjectService) { bbtToService.put(TypeOfBuildingBlock.BUSINESSOBJECT, businessObjectService); } public void setBusinessProcessService(BusinessProcessService businessProcessService) { bbtToService.put(TypeOfBuildingBlock.BUSINESSPROCESS, businessProcessService); } public void setBusinessMappingService(BusinessMappingService businessMappingService) { bbtToService.put(TypeOfBuildingBlock.BUSINESSMAPPING, businessMappingService); } public void setTechnicalComponentReleaseService(TechnicalComponentReleaseService service) { bbtToService.put(TypeOfBuildingBlock.TECHNICALCOMPONENTRELEASE, service); } public void setInfrastructureElementService(InfrastructureElementService service) { bbtToService.put(TypeOfBuildingBlock.INFRASTRUCTUREELEMENT, service); } public void setInformationSystemInterfaceService(InformationSystemInterfaceService service) { bbtToService.put(TypeOfBuildingBlock.INFORMATIONSYSTEMINTERFACE, service); } public void setBusinessDomainService(BusinessDomainService businessDomainService) { bbtToService.put(TypeOfBuildingBlock.BUSINESSDOMAIN, businessDomainService); } public void setInformationSystemDomainService(InformationSystemDomainService service) { bbtToService.put(TypeOfBuildingBlock.INFORMATIONSYSTEMDOMAIN, service); } public void setInformationSystemReleaseService(InformationSystemReleaseService service) { bbtToService.put(TypeOfBuildingBlock.INFORMATIONSYSTEMRELEASE, service); } public void setProjectService(ProjectService projectService) { bbtToService.put(TypeOfBuildingBlock.PROJECT, projectService); } public void setBusinessUnitService(BusinessUnitService businessUnitService) { bbtToService.put(TypeOfBuildingBlock.BUSINESSUNIT, businessUnitService); } public void setProductService(ProductService productService) { bbtToService.put(TypeOfBuildingBlock.PRODUCT, productService); } /** {@inheritDoc} */ public <T extends BuildingBlock> boolean updateAttributes(MassUpdateLine<T> line) { BuildingBlock buildingBlockToUpdate = line.getBuildingBlockToUpdate(); EntityService<BuildingBlock, Integer> entityService = getEntityService(buildingBlockToUpdate); BuildingBlock buildingBlock = entityService.loadObjectById(buildingBlockToUpdate.getId()); MassUpdateHelper massUpdateHelper = new MassUpdateHelper(attributeValueService); validateDateIntervalPairs(line, buildingBlock); boolean updated = false; for (MassUpdateAttribute attribute : line.getAttributes()) { final MassUpdateAttributeItem massUpdateAttributeItem = attribute.getMassUpdateAttributeItem(); final Integer attributeId = massUpdateAttributeItem.getAttributeId(); if (BBAttribute.USERDEF_NUMBER_ATTRIBUTE_TYPE.equals(attribute.getType())) { this.executeMassUpdateOnNumberAttributes(buildingBlock, massUpdateAttributeItem); // update the dto to convert the number to the correct locale massUpdateHelper.updateNumberOrTextOrDateAvFieldsForMassUpdateItem(massUpdateAttributeItem, attributeId, false); updated = true; } else if (BBAttribute.USERDEF_TEXT_ATTRIBUTE_TYPE.equals(attribute.getType())) { this.executeMassUpdateOnTextAttributes(buildingBlock, massUpdateAttributeItem); // update the dto to convert the number to the correct locale massUpdateHelper.updateNumberOrTextOrDateAvFieldsForMassUpdateItem(massUpdateAttributeItem, attributeId, false); updated = true; } else if (BBAttribute.USERDEF_ENUM_ATTRIBUTE_TYPE.equals(attribute.getType())) { this.executeMassUpdateOnEnumAttributes(buildingBlock, massUpdateAttributeItem); // update the dto to convert the number to the correct locale massUpdateHelper.updateEnumAvSelectionForMassUpdateItem(massUpdateAttributeItem, attributeId, false); updated = true; } else if (BBAttribute.USERDEF_DATE_ATTRIBUTE_TYPE.equals(attribute.getType())) { this.executeMassUpdateOnDateAttributes(buildingBlock, massUpdateAttributeItem); // update the dto to convert the date to the correct locale massUpdateHelper.updateNumberOrTextOrDateAvFieldsForMassUpdateItem(massUpdateAttributeItem, attributeId, false); updated = true; } else if (BBAttribute.USERDEF_RESPONSIBILITY_ATTRIBUTE_TYPE.equals(attribute.getType())) { this.executeMassUpdateOnResponsibilityAttributes(buildingBlock, massUpdateAttributeItem); // update the dto massUpdateHelper.updateResponsibilityAvSelectionForMassUpdateItem(massUpdateAttributeItem, attributeId, false); updated = true; } } line.setBuildingBlockToUpdate(buildingBlock); return updated; } /** * Validates a whole line in the massupdate, to check if a whole Date Interval is modified * does not write any changes * @param line */ private <T extends BuildingBlock> void validateDateIntervalPairs(MassUpdateLine<T> line, BuildingBlock buildingBlock) { UserContext.getCurrentPerms().assureFunctionalPermission(TypeOfFunctionalPermission.MASSUPDATE); //Integer in map is the Id for an DateAT Map<Integer, MassUpdateAttributeItem> massUpdateAttributes = new HashMap<Integer, MassUpdateAttributeItem>(); for (MassUpdateAttribute attribute : line.getAttributes()) { if (BBAttribute.USERDEF_DATE_ATTRIBUTE_TYPE.equals(attribute.getType())) { massUpdateAttributes.put(attributeTypeService .loadObjectById(attribute.getMassUpdateAttributeItem().getAttributeId(), DateAT.class) .getId(), attribute.getMassUpdateAttributeItem()); } } if (massUpdateAttributes.isEmpty()) { return; } //get all the date intervals that contain the given dateATs Set<DateInterval> dateIntervals = dateIntervalService .findDateIntervalsByDateATs(massUpdateAttributes.keySet()); //For every found DateInterval that contains at least one DateAT check if the DateInterval is valid for (DateInterval dateInterval : dateIntervals) { /** * A complete "DateInterval" (two DateAVs that define a part of a DateInterval for a BB) is going to be updated, check if the * startDate is equal to / or before the enddate * */ if (massUpdateAttributes.get(dateInterval.getStartDate().getId()) != null && massUpdateAttributes.get(dateInterval.getEndDate().getId()) != null) { String startDate = massUpdateAttributes.get(dateInterval.getStartDate().getId()) .getNewAttributeValue(); String endDate = massUpdateAttributes.get(dateInterval.getEndDate().getId()).getNewAttributeValue(); if (StringUtils.isNotEmpty(startDate) && StringUtils.isNotEmpty(endDate)) { Date newStartDate = DateUtils.parseAsDate(startDate, UserContext.getCurrentLocale()); Date newEndDate = DateUtils.parseAsDate(endDate, UserContext.getCurrentLocale()); if (newStartDate != null && newEndDate != null && newStartDate.after(newEndDate)) { throw new IteraplanBusinessException( IteraplanErrorMessages.DATE_INTERVAL_END_DATE_BEFORE_START_DATE); } } } /** * A single date of a DateInterval is going to be updated */ else { String date; Date newDate; if (massUpdateAttributes.get(dateInterval.getStartDate().getId()).getNewAttributeValue() != null) { date = massUpdateAttributes.get(dateInterval.getStartDate().getId()).getNewAttributeValue(); newDate = DateUtils.parseAsDate(date, UserContext.getCurrentLocale()); if (((DateAV) buildingBlock.getAttributeTypeToAttributeValues() .getBucketNotNull(dateInterval.getEndDate()).iterator().next()).getValue() .before(newDate)) { throw new IteraplanBusinessException( IteraplanErrorMessages.DATE_INTERVAL_START_DATE_BEFORE_END_DATE); } } else { date = massUpdateAttributes.get(dateInterval.getEndDate().getId()).getNewAttributeValue(); newDate = DateUtils.parseAsDate(date, UserContext.getCurrentLocale()); if (((DateAV) buildingBlock.getAttributeTypeToAttributeValues() .getBucketNotNull(dateInterval.getEndDate()).iterator().next()).getValue() .after(newDate)) { throw new IteraplanBusinessException( IteraplanErrorMessages.DATE_INTERVAL_END_DATE_BEFORE_START_DATE); } } } } } /** {@inheritDoc} */ public <T extends BuildingBlock> void updateBusinessMappingLine(MassUpdateLine<T> line) { final InformationSystemRelease isRelease = (InformationSystemRelease) line.getBuildingBlockToUpdate(); final InformationSystemReleaseService isrService = (InformationSystemReleaseService) bbtToService .get(TypeOfBuildingBlock.INFORMATIONSYSTEMRELEASE); final InformationSystemRelease dbInstance = isrService.merge(isRelease); int numberOfChanges = 0; InformationSystemReleaseCmMu isReleaseComponentModel = (InformationSystemReleaseCmMu) line .getComponentModel(); Set<Integer> hashCodes = new HashSet<Integer>(); for (BusinessMappingCmMu componentModel : isReleaseComponentModel.getBusinessMappingComponentModels()) { BusinessMapping dbBizMapping = dbInstance .getBusinessMapping(componentModel.getEncapsulatedBusinessMappings().getId()); boolean changes = checkForChanges(componentModel, dbBizMapping); // check for duplicates Integer hash = componentModel.getCustomHashCode(); if (hashCodes.contains(hash)) { throw new IteraplanBusinessException(IteraplanErrorMessages.DUPLICATE_ENTRY_BM); } hashCodes.add(hash); if (changes) { saveChanges(componentModel, dbBizMapping); numberOfChanges++; } } line.setBuildingBlockToUpdate(dbInstance); if (numberOfChanges > 0) { line.getMassUpdateResult().setWasExecuted(true); } else { line.getMassUpdateResult().setWasExecuted(false); } } private boolean checkForChanges(BusinessMappingCmMu componentModel, BusinessMapping dbBizMapping) { boolean changes = false; if (!dbBizMapping.getBusinessProcess().getId().equals(componentModel.getSelectedBusinessProcessId())) { BusinessProcessService businessProcessService = (BusinessProcessService) bbtToService .get(TypeOfBuildingBlock.BUSINESSPROCESS); dbBizMapping.setBusinessProcess( businessProcessService.loadObjectById(componentModel.getSelectedBusinessProcessId())); changes = true; } if (!dbBizMapping.getBusinessUnit().getId().equals(componentModel.getSelectedBusinessUnitId())) { BusinessUnitService businessUnitService = (BusinessUnitService) bbtToService .get(TypeOfBuildingBlock.BUSINESSUNIT); dbBizMapping.setBusinessUnit( businessUnitService.loadObjectById(componentModel.getSelectedBusinessUnitId())); changes = true; } if (!dbBizMapping.getProduct().getId().equals(componentModel.getSelectedProductId())) { ProductService productService = (ProductService) bbtToService.get(TypeOfBuildingBlock.PRODUCT); dbBizMapping.setProduct(productService.loadObjectById(componentModel.getSelectedProductId())); changes = true; } return changes; } private void saveChanges(BusinessMappingCmMu componentModel, BusinessMapping dbBizMapping) { if (LOGGER.isDebugEnabled()) { StringBuilder sb = new StringBuilder(); sb.append("\nMassupdating business mapping:\n "); sb.append(" old BP ID: "); sb.append(componentModel.getEncapsulatedBusinessMappings().getBusinessProcess().getId()); sb.append("\n"); sb.append(" new BP ID: ").append(dbBizMapping.getBusinessProcess().getId()).append("\n"); sb.append(" old BU ID: "); sb.append(componentModel.getEncapsulatedBusinessMappings().getBusinessUnit().getId()); sb.append("\n"); sb.append(" new BU ID: ").append(dbBizMapping.getBusinessUnit().getId()).append("\n"); sb.append(" old PR ID: "); sb.append(componentModel.getEncapsulatedBusinessMappings().getProduct().getId()); sb.append("\n"); sb.append(" new PR ID: ").append(dbBizMapping.getProduct().getId()); sb.append("\n"); LOGGER.debug(sb.toString()); } final InformationSystemReleaseService isrService = (InformationSystemReleaseService) bbtToService .get(TypeOfBuildingBlock.INFORMATIONSYSTEMRELEASE); isrService.saveOrUpdate(dbBizMapping.getInformationSystemRelease()); componentModel.setEncapsulatedBusinessMapping(dbBizMapping); } /** {@inheritDoc} */ @SuppressWarnings("unchecked") public <T extends BuildingBlock> void updateLine(MassUpdateLine<T> line) { T buildingBlock = line.getBuildingBlockToUpdate(); EntityService<BuildingBlock, Integer> entityService = getEntityService(buildingBlock); final T mergedBuildingBlock = (T) entityService.merge(buildingBlock); UserContext.getCurrentPerms().assureBbUpdatePermission(mergedBuildingBlock); line.getComponentModel().configure(mergedBuildingBlock); BuildingBlock updatedBuildingBlock = updateBuildingBlock(mergedBuildingBlock); line.setBuildingBlockToUpdate(updatedBuildingBlock); } /** {@inheritDoc} */ public void deleteBuildingBlock(BuildingBlock buildingBlock) { TypeOfBuildingBlock tobb = buildingBlock.getTypeOfBuildingBlock(); if (!bbtToService.containsKey(tobb)) { LOGGER.error("Could not delete building block " + buildingBlock); throw new IteraplanTechnicalException(IteraplanErrorMessages.INTERNAL_ERROR); } @SuppressWarnings("unchecked") EntityService<BuildingBlock, Integer> service = (EntityService<BuildingBlock, Integer>) bbtToService .get(tobb); //eagerly loaded in order to avoid LazyInitException when executing bulk delete BuildingBlock loadedBB = service.loadObjectByIdIfExists(buildingBlock.getId()); if (loadedBB != null) { service.deleteEntity(loadedBB); } } /** {@inheritDoc} */ public void subscribeBuildingBlock(BuildingBlock buildingBlock, boolean subscribe) { TypeOfBuildingBlock tobb = buildingBlock.getTypeOfBuildingBlock(); if (!bbtToService.containsKey(tobb) || TypeOfBuildingBlock.BUSINESSMAPPING.equals(tobb)) { LOGGER.error("Could not subscribe building block " + buildingBlock); throw new IteraplanTechnicalException(IteraplanErrorMessages.INTERNAL_ERROR); } SubscribeService service = (SubscribeService) bbtToService.get(tobb); service.subscribe(buildingBlock.getId(), subscribe); } /** * Performs an update of a {@link DateAV}. * * @param buildingBlock The {@link BuildingBlock} the attribute value is assigned to. * @param dto The data transfer object for mass updates on attribute types. */ private void executeMassUpdateOnDateAttributes(BuildingBlock buildingBlock, MassUpdateAttributeItem dto) { LOGGER.debug("Performing mass update on date attribute value."); UserContext.getCurrentPerms().assureFunctionalPermission(TypeOfFunctionalPermission.MASSUPDATE); DateAT at = attributeTypeService.loadObjectById(dto.getAttributeId(), DateAT.class); UserContext.getCurrentPerms().assureAttrTypeGroupPermission(at.getAttributeTypeGroup(), AttributeTypeGroupPermissionEnum.READ_WRITE); // Add new attribute value. String newValue = dto.getNewAttributeValue(); if (StringUtils.isNotEmpty(newValue)) { DateAV av = new DateAV(); Date newDate = DateUtils.parseAsDate(newValue, UserContext.getCurrentLocale()); if (newDate != null) { av.setValue(newDate); av.setAttributeType(at); // Setting this side of the association suffices. } attributeValueService.setValue(buildingBlock, av, at); } else { attributeValueService.setValue(buildingBlock, null, at); } attributeValueService.saveOrUpdateAttributeValues(buildingBlock); EntityService<BuildingBlock, Integer> entityService = getEntityService(buildingBlock); entityService.saveOrUpdate(buildingBlock); } /** * Performs an update of a {@link EnumAV}. * * @param buildingBlock * The {@link BuildingBlock} the attribute value is assigned to. * @param dto * The data transfer object for mass updates on attribute types. */ private void executeMassUpdateOnEnumAttributes(BuildingBlock buildingBlock, MassUpdateAttributeItem dto) { LOGGER.debug("Performing mass update on enumeration attribute value."); UserContext.getCurrentPerms().assureFunctionalPermission(TypeOfFunctionalPermission.MASSUPDATE); EnumAT at = attributeTypeService.loadObjectById(dto.getAttributeId(), EnumAT.class); List<Integer> selectedIDs = dto.getSelectedAttributeValueIds(); // Check permission for the attribute type group. UserContext.getCurrentPerms().assureAttrTypeGroupPermission(at.getAttributeTypeGroup(), AttributeTypeGroupPermissionEnum.READ_WRITE); // Check if only single values are updated for single valued attribute types. if (!at.isMultiassignmenttype() && (selectedIDs.size() >= 2)) { throw new IteraplanBusinessException(IteraplanErrorMessages.ILLEGAL_MULTIVALUE_ATTRIBUTE_ASSIGNMENT); } List<AttributeValue> avs = Lists.newArrayList(); for (Integer id : selectedIDs) { EnumAV av = attributeValueService.loadObjectById(id, EnumAV.class); avs.add(av); } attributeValueService.setReferenceValues(buildingBlock, avs, at.getId()); attributeValueService.saveOrUpdateAttributeValues(buildingBlock); EntityService<BuildingBlock, Integer> entityService = getEntityService(buildingBlock); entityService.saveOrUpdate(buildingBlock); } /** * Performs an update of a {@link NumberAV}. * * @param buildingBlock * The {@link BuildingBlock} the attribute value is assigned to. * @param dto * The data transfer object for mass updates on attribute types. */ private void executeMassUpdateOnNumberAttributes(BuildingBlock buildingBlock, MassUpdateAttributeItem dto) { LOGGER.debug("Performing mass update on text attribute value."); UserContext.getCurrentPerms().assureFunctionalPermission(TypeOfFunctionalPermission.MASSUPDATE); NumberAT at = attributeTypeService.loadObjectById(dto.getAttributeId(), NumberAT.class); // Check permission for the attribute type group. UserContext.getCurrentPerms().assureAttrTypeGroupPermission(at.getAttributeTypeGroup(), AttributeTypeGroupPermissionEnum.READ_WRITE); // Add new attribute value. String newValue = dto.getNewAttributeValue(); if (StringUtils.isNotEmpty(newValue)) { NumberAV av = new NumberAV(); BigDecimal newNumber = BigDecimalConverter.parse(newValue, true, UserContext.getCurrentLocale()); av.setValue(newNumber); av.setAttributeType(at); // Setting this side of the association suffices. attributeValueService.setValue(buildingBlock, av, at); } else { attributeValueService.setValue(buildingBlock, null, at); } attributeValueService.saveOrUpdateAttributeValues(buildingBlock); EntityService<BuildingBlock, Integer> entityService = getEntityService(buildingBlock); entityService.saveOrUpdate(buildingBlock); } /** * Performs an update of a {@link de.iteratec.iteraplan.model.attribute.ResponsibilityAV}. * * @param buildingBlock * The {@link BuildingBlock} the text attribute value is assigned to. * @param dto * The data transfer object for mass updates on attribute types. */ private void executeMassUpdateOnResponsibilityAttributes(BuildingBlock buildingBlock, MassUpdateAttributeItem dto) { LOGGER.debug("Performing mass update on enumeration attribute value."); UserContext.getCurrentPerms().assureFunctionalPermission(TypeOfFunctionalPermission.MASSUPDATE); ResponsibilityAT at = attributeTypeService.loadObjectById(dto.getAttributeId(), ResponsibilityAT.class); List<Integer> selectedIDs = dto.getSelectedAttributeValueIds(); // Check permission for the attribute type group. UserContext.getCurrentPerms().assureAttrTypeGroupPermission(at.getAttributeTypeGroup(), AttributeTypeGroupPermissionEnum.READ_WRITE); // Check if only single values are updated for single valued attribute types. if (!at.isMultiassignmenttype() && (selectedIDs.size() >= 2)) { throw new IteraplanBusinessException(IteraplanErrorMessages.ILLEGAL_MULTIVALUE_ATTRIBUTE_ASSIGNMENT); } List<AttributeValue> avs = Lists.newArrayList(); for (Integer id : selectedIDs) { ResponsibilityAV av = attributeValueService.loadObjectById(id, ResponsibilityAV.class); avs.add(av); } attributeValueService.setReferenceValues(buildingBlock, avs, at.getId()); attributeValueService.saveOrUpdateAttributeValues(buildingBlock); EntityService<BuildingBlock, Integer> entityService = getEntityService(buildingBlock); entityService.saveOrUpdate(buildingBlock); } /** * Performs an update of a {@link TextAV}. * * @param buildingBlock * The {@link BuildingBlock} the text attribute value is assigned to. * @param dto * The data transfer object for mass updates on attribute types. */ private void executeMassUpdateOnTextAttributes(BuildingBlock buildingBlock, MassUpdateAttributeItem dto) { LOGGER.debug("Performing mass update on text attribute value."); UserContext.getCurrentPerms().assureFunctionalPermission(TypeOfFunctionalPermission.MASSUPDATE); TextAT at = attributeTypeService.loadObjectById(dto.getAttributeId(), TextAT.class); // Check permission for the attribute type group. UserContext.getCurrentPerms().assureAttrTypeGroupPermission(at.getAttributeTypeGroup(), AttributeTypeGroupPermissionEnum.READ_WRITE); // Add new attribute value. String newValue = dto.getNewAttributeValue(); if (StringUtils.isNotEmpty(newValue)) { TextAV av = new TextAV(); av.setValue(newValue); av.setAttributeType(at); // Setting this side of the association suffices. attributeValueService.setValue(buildingBlock, av, at); } else { attributeValueService.setValue(buildingBlock, null, at); } attributeValueService.saveOrUpdateAttributeValues(buildingBlock); EntityService<BuildingBlock, Integer> entityService = getEntityService(buildingBlock); entityService.saveOrUpdate(buildingBlock); } /** * Calls the update method of the service responsible for managing the buildingBlock instance that * is passed in as parameter. IMPORTANT: This updates Properties and Associations, but ignores the * attributes. * * @param buildingBlock * The {@link BuildingBlock} to update. Represents a dbInstance that has been updated by * some component model during the mass update * @return The updated and persisted entity */ @SuppressWarnings("unchecked") private BuildingBlock updateBuildingBlock(BuildingBlock buildingBlock) { TypeOfBuildingBlock tobb = buildingBlock.getTypeOfBuildingBlock(); if (!bbtToService.containsKey(tobb)) { throw new IllegalArgumentException( "MassUpdateLine for generic BuildingBlock not available. MassUpdateLine for " + buildingBlock.getClass() + " has to be configured in MassUpdateServiceImpl.class"); } EntityService<BuildingBlock, Integer> service = (EntityService<BuildingBlock, Integer>) bbtToService .get(tobb); return service.saveOrUpdate(buildingBlock); } }