package net.cloudcodex.server;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import net.cloudcodex.server.data.Data;
import net.cloudcodex.server.data.Data.Campaign;
import net.cloudcodex.server.data.Data.CharacterNote;
import net.cloudcodex.server.data.Data.Message;
import net.cloudcodex.server.data.Data.Notification;
import net.cloudcodex.server.data.Data.Scene;
import net.cloudcodex.server.data.Data.User;
import net.cloudcodex.server.data.campaign.character.CharacterDescriptionSDO;
import net.cloudcodex.server.data.campaign.character.CharacterSDO;
import net.cloudcodex.server.data.campaign.msg.SceneSDO;
import net.cloudcodex.server.data.campaign.scene.SceneToCreateSDO;
import net.cloudcodex.server.data.home.CampaignPublicSummary;
import net.cloudcodex.server.data.home.CampaignSummary;
import net.cloudcodex.server.data.home.CharacterSummary;
import net.cloudcodex.shared.MessageAction;
import net.cloudcodex.shared.MessageType;
import net.cloudcodex.shared.NotificationType;
import net.cloudcodex.shared.dto.NotificationDTO;
import net.cloudcodex.shared.dto.campaign.character.CharacterDescriptionDTO;
import net.cloudcodex.shared.dto.campaign.character.CharacterHeaderDTO;
import net.cloudcodex.shared.dto.campaign.character.CharacterNoteDTO;
import net.cloudcodex.shared.dto.home.CampaignPublicSummaryDTO;
import net.cloudcodex.shared.dto.home.CampaignSummaryDTO;
import net.cloudcodex.shared.dto.home.CharacterSummaryDTO;
import net.cloudcodex.shared.dto.msg.MessageDTO;
import net.cloudcodex.shared.dto.msg.SceneDTO;
import net.cloudcodex.shared.dto.msg.SceneToCreateDTO;
import com.google.appengine.api.datastore.Key;
/**
* Utility class to map data to DTO.
* @author Thomas
*/
public class DTOUtil {
private DTOUtil() { }
/**
* Create a {@link CharacterSummaryDTO} from {@link CharacterSummary}.
* @param summary character summary to map.
* @return character summary DTO.
*/
public static CharacterSummaryDTO mapCharacterSummary(CharacterSummary summary) {
if(summary == null) {
return null;
}
final Data.Character character = summary.getCharacter();
final CharacterSummaryDTO dto = new CharacterSummaryDTO();
dto.setId(character.getKey().getId());
dto.setCampaign(mapCampaignPublicSummary(summary.getCampaign()));
dto.setName(character.getName());
dto.setDescription(character.getDescription());
dto.setIcon(character.getIcon());
dto.setNotifications(mapNotification(
summary.getNotifications(), NotificationType.CHARACTER));
dto.setCreationDate(character.getDate());
dto.setDead(character.getDead() == null ? false : character.getDead());
dto.setLocked(character.getLocked() == null ? false : character.getLocked());
return dto;
}
/**
* Map a list of characters summary.
*/
public static List<CharacterSummaryDTO> mapCharacterSummary(
Collection<? extends CharacterSummary> summaries) {
if(summaries == null || summaries.isEmpty()) {
return null;
}
final List<CharacterSummaryDTO> dtos = new ArrayList<CharacterSummaryDTO>();
for(CharacterSummary summary : summaries) {
dtos.add(mapCharacterSummary(summary));
}
return dtos.isEmpty() ? null : dtos;
}
/**
* Map a Campaign to {@link Campaignpublic staticSummaryDTO}.
* @param campaign campaign to map.
* @return campaign summary DTO.
*/
public static CampaignPublicSummaryDTO mapCampaignPublicSummary(CampaignPublicSummary summary) {
if(summary == null) {
return null;
}
final Campaign campaign = summary.getCampaign();
final User master = summary.getMaster();
final CampaignPublicSummaryDTO dto = new CampaignPublicSummaryDTO();
dto.setId(campaign.getKey().getId());
dto.setName(campaign.getName());
dto.setIcon(campaign.getIcon());
dto.setNotifications(mapNotification(
summary.getNotifications(), NotificationType.CAMPAIGN));
dto.setCreationDate(campaign.getDate());
dto.setGameMasterNickname(master == null ? null : master.getNickname());
return dto;
}
/**
* Map a Campaign to {@link CampaignSummaryDTO}.
* @param campaign campaign to map.
* @return campaign summary DTO.
*/
public static CampaignSummaryDTO mapCampaignSummary(CampaignSummary summary) {
if(summary == null) {
return null;
}
final Campaign campaign = summary.getCampaign();
final User master = summary.getMaster();
final CampaignSummaryDTO dto = new CampaignSummaryDTO();
dto.setId(campaign.getKey().getId());
dto.setName(campaign.getName());
dto.setGame(campaign.getGame());
dto.setIcon(campaign.getIcon());
dto.setNotifications(mapNotification(
summary.getNotifications(), NotificationType.CAMPAIGN));
dto.setCreationDate(campaign.getDate());
dto.setGameMasterNickname(master == null ? null : master.getNickname());
dto.setGame(campaign.getGame());
// iterate to keep only the names.
final List<Data.Character> characters = summary.getCharacters();
if(characters != null) {
final List<String> names = new ArrayList<String>();
for(Data.Character character : characters) {
names.add(character.getName());
}
dto.setCharacters(names.isEmpty() ? null : names);
}
return dto;
}
/**
* map a list of campaign summaries.
*/
public static List<CampaignSummaryDTO> mapCampaignSummary(
Collection<? extends CampaignSummary> summaries) {
if(summaries == null || summaries.isEmpty()) {
return null;
}
final List<CampaignSummaryDTO> dtos = new ArrayList<CampaignSummaryDTO>();
for(CampaignSummary summary : summaries) {
dtos.add(mapCampaignSummary(summary));
}
return dtos.isEmpty() ? null : dtos;
}
/**
* Map a notification to its DTO.
* @param notification notification to map.
* @param type type of the notification.
* @return the notification DTO.
*/
public static NotificationDTO mapNotification(Notification notification, NotificationType type) {
if(notification == null || type == null) {
return null;
}
final NotificationDTO dto = new NotificationDTO();
dto.setId(notification.getKey().getId()); // FIXME
dto.setDate(notification.getTimestamp());
dto.setMessage(notification.getMessage());
dto.setType(type);
return dto;
}
/**
* Map a list of notifications to DTO.
*/
public static List<NotificationDTO> mapNotification(
Collection<? extends Notification> notifications, NotificationType type) {
if(notifications == null || type == null) {
return null;
}
final List<NotificationDTO> dtos = new ArrayList<NotificationDTO>();
for(Notification notification : notifications) {
final NotificationDTO dto = mapNotification(notification, type);
if(dto != null) {
dtos.add(dto);
}
}
return dtos.isEmpty() ? null : dtos;
}
/**
* Map a CharacterSDO to CharacterHeaderDTO.
* @param sdo character to map.
* @return CharacterHeaderDTO.
*/
public static CharacterHeaderDTO mapCharacterSDOToHeader(CharacterSDO sdo, Long viewCharacterKey) {
if(sdo == null) {
return null;
}
return mapCharacterToHeader(sdo.getCharacter(), null, viewCharacterKey);
}
/**
* Map a Data.Character to CharacterHeaderDTO.
* @param sdo character to map.
* @param forCharacter the character who sees the character.
* @return CharacterHeaderDTO.
*/
public static CharacterHeaderDTO mapCharacterToHeader(
Data.Character character, Scene scene,
Long viewCharacterKey) {
final CharacterHeaderDTO dto = new CharacterHeaderDTO();
dto.setId(character.getKey().getId());
dto.setIcon(character.getIcon());
dto.setDescription(character.getDescription());
dto.setProfile(Boolean.TRUE.equals(character.getProfile()));
final Key ownerKey = character.getOwner();
// character can see that a character header is itself an kwow the owner
if(viewCharacterKey == null || viewCharacterKey.equals(dto.getId())) {
dto.setOwner(ownerKey == null ? null : ownerKey.getId());
dto.setOwnerNickname(character.getOwnerNickname());
dto.setDead(character.getDead());
dto.setLocked(character.getLocked());
}
if(viewCharacterKey == null) {
dto.setName(character.getName());
if(scene != null) {
// transform aliases, but only the character aliases.
final Map<String, String> allAliases = scene.getAlias();
if(allAliases != null) {
final Map<Long, String> aliases = dto.getAliases();
final String stringId = String.valueOf(dto.getId());
final String prefix = stringId + "-";
for(Map.Entry<String, String> entry : allAliases.entrySet()) {
final String key = entry.getKey();
if(key != null) {
if(stringId.equals(key)) {
aliases.put(null, entry.getValue());
} else if(key.startsWith(prefix)) {
try {
final Long id = Long.valueOf(key.substring(prefix.length()));
aliases.put(id, entry.getValue());
} catch (NumberFormatException e) {
// nothing ...
}
}
}
}
}
}
} else {
// try to get an alias
final String alias = getCharacterAlias(dto.getId(), scene, viewCharacterKey);
if(alias != null) {
dto.setName(alias);
} else {
dto.setName(character.getName());
}
}
return dto;
}
/**
* Utility method, try to get an alias of the character for the optional
* character in the scene.
*/
public static String getCharacterAlias(
long character, Scene scene, Long viewCharacterKey) {
if(scene == null) {
return null;
}
String alias = null;
if(viewCharacterKey != null) {
// try to get a specific alias
alias = scene.getAlias(character + "-" + viewCharacterKey);
}
// try to get global alias
return alias != null ? alias : scene.getAlias(String.valueOf(character));
}
/**
* Map a list of CharacterSDO to a list of CharacterHeaderDTO.
*/
public static List<CharacterHeaderDTO> mapCharacterSDOToHeader(
Collection<? extends CharacterSDO> sdos, Long viewCharacterKey) {
if(sdos == null) {
return null;
}
final List<CharacterHeaderDTO> dtos = new ArrayList<CharacterHeaderDTO>();
for(CharacterSDO sdo : sdos) {
final CharacterHeaderDTO dto = mapCharacterSDOToHeader(sdo, viewCharacterKey);
if(dto != null) {
dtos.add(dto);
}
}
return dtos.isEmpty() ? null : dtos;
}
/**
* Map a list of CharacterSDO to a list of CharacterHeaderDTO.
*/
public static List<CharacterHeaderDTO> mapCharacterHeader(
Collection<? extends Data.Character> characters,
Scene scene, Long viewCharacterKey) {
if(characters == null) {
return null;
}
final List<CharacterHeaderDTO> dtos = new ArrayList<CharacterHeaderDTO>();
for(Data.Character character : characters) {
final CharacterHeaderDTO dto = mapCharacterToHeader(character, scene, viewCharacterKey);
if(dto != null) {
dtos.add(dto);
}
}
return dtos.isEmpty() ? null : dtos;
}
/**
* Map a CharacterDescriptionSDO to a CharacterDescriptionDTO.
* @param sdo SDO to map.
* @return the DTO version.
*/
public static CharacterDescriptionDTO mapCharacterDescription(CharacterDescriptionSDO sdo) {
if(sdo == null) {
return null;
}
final CharacterDescriptionDTO dto = new CharacterDescriptionDTO();
dto.setNotes(mapCharacterNote(sdo.getNotes()));
dto.setCampaignId(sdo.getCampaignId());
dto.setId(sdo.getCharacterId());
dto.setTimestamp(sdo.getTimestamp());
dto.setAliases(sdo.getAliases());
dto.setSheet(sdo.getSheet());
return dto;
}
/**
* Map a {@link CharacterNote} to {@link CharacterNoteDTO}.
* @param note note to map.
* @return DTO version.
*/
public static CharacterNoteDTO mapCharacterNote(Data.CharacterNote note) {
if(note == null) {
return null;
}
final CharacterNoteDTO dto = new CharacterNoteDTO();
final Key authorKey = note.getAuthor();
dto.setAuthor(authorKey == null ? null : authorKey.getId());
dto.setContent(note.getContent());
dto.setTimestamp(note.getTimestamp());
return dto;
}
/**
* Map a list of {@link CharacterNote} to a list of {@link CharacterNoteDTO}.
*/
public static List<CharacterNoteDTO> mapCharacterNote(
Collection<? extends Data.CharacterNote> sdos) {
if(sdos == null) {
return null;
}
final List<CharacterNoteDTO> dtos = new ArrayList<CharacterNoteDTO>();
for(CharacterNote sdo : sdos) {
final CharacterNoteDTO dto = mapCharacterNote(sdo);
if(dto != null) {
dtos.add(dto);
}
}
return dtos.isEmpty() ? null : dtos;
}
/**
* @return Map a Scene to a SceneDTO.
* @param scene scene to map.
* @param viewCharacterKey the character id for which return the data.
* If null then it's for GM.
*/
public static SceneDTO mapScene(
SceneSDO sdo,
Long viewCharacterKey
) {
if(sdo == null) {
return null;
}
final Scene scene = sdo.getScene();
final List<Message> messages = sdo.getMessages();
final List<Data.Character> characters = sdo.getCharacters();
final SceneDTO dto = new SceneDTO();
dto.setId(scene.getKey().getId());
dto.setCharacters(mapCharacterHeader(characters, scene, viewCharacterKey));
dto.setMessages(mapMessage(messages));
// use introduction as message
final String introduction = scene.getIntroduction();
if(introduction != null) {
if(dto.getMessages() == null) {
dto.setMessages(new ArrayList<MessageDTO>());
}
final MessageDTO messageDTO = new MessageDTO();
messageDTO.setId(null);
messageDTO.setAction(null);
messageDTO.setAuthor(null);
messageDTO.setContent(introduction);
messageDTO.setIndex(0);
messageDTO.setType(null);
dto.getMessages().add(0, messageDTO);
}
dto.setTimestamp(scene.getTimestamp());
if(viewCharacterKey != null) {
// for a character, only its own informations
final String viewCharacterKeyString = viewCharacterKey.toString();
final Key next = scene.getNext(viewCharacterKeyString);
if (next != null) {
dto.getNext().put(viewCharacterKey, next.getId());
}
final Key previous = scene.getPrevious(viewCharacterKeyString);
if (previous != null) {
dto.getPrevious().put(viewCharacterKey, previous.getId());
}
} else {
// for GM : all informations
for(Map.Entry<String, Key> entry : scene.getNext().entrySet()) {
try {
final Long id = Long.valueOf(entry.getKey());
dto.getNext().put(id, entry.getValue().getId());
} catch (NumberFormatException e) {
// ...
}
}
for(Map.Entry<String, Key> entry : scene.getPrevious().entrySet()) {
try {
final Long id = Long.valueOf(entry.getKey());
dto.getPrevious().put(id, entry.getValue().getId());
} catch (NumberFormatException e) {
// ...
}
}
}
return dto;
}
/**
* Map a list of {@link SceneSDO} to a list of {@link SceneDTO}.
*/
public static List<SceneDTO> mapScene(
Collection<? extends SceneSDO> scenes,
Long viewCharacterKey
) {
if(scenes == null) {
return null;
}
final List<SceneDTO> dtos = new ArrayList<SceneDTO>();
for(SceneSDO scene : scenes) {
final SceneDTO dto = mapScene(scene, viewCharacterKey);
if(dto != null) {
dtos.add(dto);
}
}
return dtos.isEmpty() ? null : dtos;
}
/**
* Map a {@link SceneSDO} to a {@link MessageDTO}.
*/
public static MessageDTO mapMessage(Message message) {
final MessageDTO dto = new MessageDTO();
dto.setId(message.getKey().getId());
dto.setType(MessageType.getMessageType(message.getType()));
dto.setAction(MessageAction.getMessageAction(message.getAction()));
dto.setIndex(message.getIndex() == null ? 0 : message.getIndex());
if(Boolean.TRUE.equals(message.getDeleted())) {
dto.setDeleted(true);
} else {
dto.setContent(message.getContent());
dto.setDices(message.getDices());
}
final Key author = message.getAuthor();
dto.setAuthor(author == null ? null : author.getId());
return dto;
}
/**
* Map a list of {@link SceneSDO} to a list of {@link MessageDTO}.
*/
public static List<MessageDTO> mapMessage(
Collection<? extends Data.Message> messages) {
if(messages == null) {
return null;
}
final List<MessageDTO> dtos = new ArrayList<MessageDTO>();
for(Message message : messages) {
final MessageDTO dto = mapMessage(message);
if(dto != null) {
dtos.add(dto);
}
}
return dtos.isEmpty() ? null : dtos;
}
/**
* Create a {@link SceneToCreateSDO} from {@link SceneToCreateDTO}.
*/
public static SceneToCreateSDO mapSceneToCreate(SceneToCreateDTO dto) {
if(dto == null) {
return null;
}
final SceneToCreateSDO sceneToCreate = new SceneToCreateSDO();
sceneToCreate.setCharacters(dto.getCharacters());
sceneToCreate.setIntroduction(dto.getIntroduction());
sceneToCreate.getAliases().putAll(dto.getAliases());
return sceneToCreate;
}
}