MobileTerminalModelToEntityMapper.java
/*
Developed with the contribution of the European Commission - Directorate General for Maritime Affairs and Fisheries
© European Union, 2015-2016.
This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The IFDM Suite is free software: you can
redistribute it and/or modify it under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or any later version. The IFDM Suite 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 General Public License along with the IFDM Suite. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.europa.ec.fisheries.uvms.mobileterminal.mapper;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import eu.europa.ec.fisheries.schema.mobileterminal.types.v1.ComChannelAttribute;
import eu.europa.ec.fisheries.schema.mobileterminal.types.v1.ComChannelCapability;
import eu.europa.ec.fisheries.schema.mobileterminal.types.v1.ComChannelType;
import eu.europa.ec.fisheries.schema.mobileterminal.types.v1.MobileTerminalAttribute;
import eu.europa.ec.fisheries.schema.mobileterminal.types.v1.MobileTerminalSource;
import eu.europa.ec.fisheries.schema.mobileterminal.types.v1.MobileTerminalType;
import eu.europa.ec.fisheries.uvms.common.DateUtils;
import eu.europa.ec.fisheries.uvms.mobileterminal.constant.MobileTerminalConstants;
import eu.europa.ec.fisheries.uvms.mobileterminal.dao.exception.EnumException;
import eu.europa.ec.fisheries.uvms.mobileterminal.entity.Channel;
import eu.europa.ec.fisheries.uvms.mobileterminal.entity.ChannelHistory;
import eu.europa.ec.fisheries.uvms.mobileterminal.entity.MobileTerminal;
import eu.europa.ec.fisheries.uvms.mobileterminal.entity.MobileTerminalEvent;
import eu.europa.ec.fisheries.uvms.mobileterminal.entity.MobileTerminalPlugin;
import eu.europa.ec.fisheries.uvms.mobileterminal.entity.types.EventCodeEnum;
import eu.europa.ec.fisheries.uvms.mobileterminal.entity.types.MobileTerminalSourceEnum;
import eu.europa.ec.fisheries.uvms.mobileterminal.entity.types.MobileTerminalTypeEnum;
import eu.europa.ec.fisheries.uvms.mobileterminal.model.exception.MobileTerminalModelMapperException;
public class MobileTerminalModelToEntityMapper {
private static Logger LOG = LoggerFactory.getLogger(MobileTerminalModelToEntityMapper.class);
public static MobileTerminal mapMobileTerminalEntity(MobileTerminal entity, MobileTerminalType model, String serialNumber, MobileTerminalPlugin plugin, String username, String comment, EventCodeEnum event) throws MobileTerminalModelMapperException {
if (model == null) throw new MobileTerminalModelMapperException("No mobile terminal to map");
if (entity.getGuid() == null) {
entity.setGuid(UUID.randomUUID().toString());
}
entity.setArchived(model.isArchived());
entity.setInactivated(model.isInactive());
entity.setPlugin(plugin);
entity.setSerialNo(serialNumber);
try {
entity.setSource(getSourceTypeFromModel(model.getSource()));
} catch (EnumException e) {
LOG.error("[ Error when getting terminal source enum from source.] ", e.getMessage());
throw new MobileTerminalModelMapperException(e.getMessage());
}
MobileTerminalTypeEnum type = MobileTerminalTypeEnum.getType(model.getType());
if (type == null) throw new MobileTerminalModelMapperException("Non valid mobile terminal type when mapping");
entity.setMobileTerminalType(type);
entity.setUpdateTime(DateUtils.getNowDateUTC());
entity.setUpdatedBy(username);
try {
mapHistoryAttributes(entity, model, username, comment, event);
} catch (EnumException e) {
LOG.error("[ Error when mapping attribute types ]");
throw new MobileTerminalModelMapperException(e.getMessage());
}
// Channels can only change for these events
if (event == EventCodeEnum.MODIFY || event == EventCodeEnum.CREATE) {
try {
mapChannels(entity, model, username);
} catch (EnumException e) {
LOG.error("[ Error when mapping channel field types ]");
throw new MobileTerminalModelMapperException(e.getMessage());
}
}
entity.setUpdateTime(DateUtils.getNowDateUTC());
entity.setUpdatedBy(username);
return entity;
}
public static MobileTerminal mapNewMobileTerminalEntity(MobileTerminalType model, String serialNumber, MobileTerminalPlugin plugin, String username) throws MobileTerminalModelMapperException {
if (model == null) throw new MobileTerminalModelMapperException("No mobile terminal to map");
return mapMobileTerminalEntity(new MobileTerminal(), model, serialNumber, plugin, username, MobileTerminalConstants.CREATE_COMMENT, EventCodeEnum.CREATE);
}
private static void mapChannels(MobileTerminal entity, MobileTerminalType model, String username) throws EnumException, MobileTerminalModelMapperException {
List<ComChannelType> modelChannels = model.getChannels();
Set<Channel> channels = new HashSet<>();
for (ComChannelType channelType : modelChannels) {
Channel channel = null;
if (entity != null) {
for (Channel c : entity.getChannels()) {
if (c.getGuid().equals(channelType.getGuid())) {
channel = c;
break;
}
}
}
if (channel == null) {
channel = new Channel();
channel.setGuid(UUID.randomUUID().toString());
}
channel.setMobileTerminal(entity);
channel.setUpdateTime(DateUtils.getNowDateUTC());
channel.setUpdateUser(username);
channel.setArchived(false);
ChannelHistory history = new ChannelHistory();
history.setChannel(channel);
history.setUpdateTime(DateUtils.getNowDateUTC());
history.setName(channelType.getName());
history.setActive(true);
history.setUpdatedBy(username);
history.setMobileTerminalEvent(entity.getCurrentEvent());
String attributes = mapComChannelAttributes(channelType.getAttributes());
history.setAttributes(attributes);
if (channel.getHistories().size() == 0) {
history.setEventCodeType(EventCodeEnum.CREATE);
} else {
history.setEventCodeType(EventCodeEnum.MODIFY);
}
for (ComChannelCapability capability : channelType.getCapabilities()) {
if (MobileTerminalConstants.CAPABILITY_CONFIGURABLE.equalsIgnoreCase(capability.getType()) && capability.isValue()) {
entity.getCurrentEvent().setConfigChannel(channel);
history.setConfigChannel(capability.isValue());
}
if (MobileTerminalConstants.CAPABILITY_DEFAULT_REPORTING.equalsIgnoreCase(capability.getType()) && capability.isValue()) {
entity.getCurrentEvent().setDefaultChannel(channel);
history.setDefaultChannel(capability.isValue());
}
if (MobileTerminalConstants.CAPABILITY_POLLABLE.equalsIgnoreCase(capability.getType()) && capability.isValue()) {
entity.getCurrentEvent().setPollChannel(channel);
history.setPollChannel(capability.isValue());
}
}
// No changes to channel means no new history
ChannelHistory channelHistory = channel.getCurrentHistory();
if (channelHistory != null) {
if (channelHistory.equals(history)) {
channels.add(channel);
continue;
} else {
for (ChannelHistory ch : channel.getHistories()) {
ch.setActive(false);
channels.add(channel);
}
}
}
for (ChannelHistory ch : channel.getHistories()) {
ch.setActive(false);
}
channel.getHistories().add(history);
channels.add(channel);
}
for (Channel channel : entity.getChannels()) {
if (!channels.contains(channel)) {
channel.setArchived(true);
ChannelHistory current = channel.getCurrentHistory();
current.setActive(false);
ChannelHistory archive = new ChannelHistory();
archive.setEventCodeType(EventCodeEnum.ARCHIVE);
archive.setName(current.getName());
archive.setMobileTerminalEvent(entity.getCurrentEvent());
archive.setActive(true);
archive.setAttributes(current.getAttributes());
archive.setChannel(channel);
archive.setUpdatedBy(username);
archive.setUpdateTime(DateUtils.getNowDateUTC());
channel.getHistories().add(archive);
}
}
entity.setChannels(channels);
}
private static void mapHistoryAttributes(MobileTerminal entity, MobileTerminalType model, String username, String comment, EventCodeEnum eventCode) throws EnumException, MobileTerminalModelMapperException {
List<MobileTerminalAttribute> modelAttributes = model.getAttributes();
MobileTerminalEvent current = entity.getCurrentEvent();
MobileTerminalEvent history = new MobileTerminalEvent();
history.setActive(true);
history.setUpdateTime(DateUtils.getNowDateUTC());
history.setUpdatedBy(username);
history.setMobileTerminal(entity);
history.setComment(comment);
history.setEventCodeType(eventCode);
if (current != null && model.getConnectId() == null && eventCode != EventCodeEnum.UNLINK) {
history.setConnectId(current.getConnectId());
} else {
history.setConnectId(model.getConnectId());
}
history.setAttributes(mapHistoryAttributes(modelAttributes));
for (MobileTerminalEvent event : entity.getMobileTerminalEvents()) {
event.setActive(false);
}
entity.getMobileTerminalEvents().add(history);
}
private static String mapHistoryAttributes(List<MobileTerminalAttribute> modelAttributes) {
StringBuffer sb = new StringBuffer();
for (MobileTerminalAttribute attr : modelAttributes) {
sb.append(attr.getType()).append("=");
sb.append(attr.getValue()).append(";");
}
return sb.toString();
}
private static String mapComChannelAttributes(List<ComChannelAttribute> modelAttributes) {
StringBuffer sb = new StringBuffer();
for (ComChannelAttribute attr : modelAttributes) {
sb.append(attr.getType()).append("=");
sb.append(attr.getValue()).append(";");
}
return sb.toString();
}
private static MobileTerminalSourceEnum getSourceTypeFromModel(MobileTerminalSource model) throws EnumException {
if (model != null) {
switch (model) {
case INTERNAL:
return MobileTerminalSourceEnum.INTERNAL;
case NATIONAL:
return MobileTerminalSourceEnum.NATIONAL;
}
}
throw new EnumException("Couldn't map enum (from model) in " + MobileTerminalSourceEnum.class.getName());
}
}