Java tutorial
/** * Copyright 2015 Fondazione Bruno Kessler - Trento RISE * * 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. */ package eu.trentorise.game.managers; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.apache.log4j.LogManager; import org.perf4j.StopWatch; import org.perf4j.log4j.Log4JStopWatch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.mongodb.core.FindAndModifyOptions; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.stereotype.Component; import eu.trentorise.game.model.CustomData; import eu.trentorise.game.model.Game; import eu.trentorise.game.model.PlayerState; import eu.trentorise.game.model.TeamState; import eu.trentorise.game.model.core.GameConcept; import eu.trentorise.game.repo.GenericObjectPersistence; import eu.trentorise.game.repo.PlayerRepo; import eu.trentorise.game.repo.StatePersistence; import eu.trentorise.game.repo.TeamPersistence; import eu.trentorise.game.services.GameService; import eu.trentorise.game.services.PlayerService; @Component public class DBPlayerManager implements PlayerService { private final Logger logger = LoggerFactory.getLogger(DBPlayerManager.class); @Autowired private PlayerRepo playerRepo; @Autowired private MongoTemplate mongoTemplate; @Autowired private GameService gameSrv; public PlayerState loadState(String gameId, String playerId, boolean upsert) { eu.trentorise.game.repo.StatePersistence state = playerRepo.findByGameIdAndPlayerId(gameId, playerId); PlayerState res = state == null ? (upsert ? new PlayerState(gameId, playerId) : null) : isTeam(state) ? new TeamState(state) : new PlayerState(state); return initConceptsStructure(res, gameId); } public PlayerState saveState(PlayerState state) { PlayerState saved = null; if (state != null) { StatePersistence toSave = null; if (state instanceof TeamState) { toSave = new TeamPersistence((TeamState) state); saved = new TeamState(persist(toSave)); } else { toSave = new StatePersistence(state); saved = new PlayerState(persist(toSave)); } } return saved; } private boolean isTeam(StatePersistence state) { return state != null && state.getMetadata().get(TeamState.NAME_METADATA) != null && state.getMetadata().get(TeamState.MEMBERS_METADATA) != null; } private StatePersistence persist(StatePersistence state) { return persist(state.getGameId(), state.getPlayerId(), state.getConcepts(), state.getCustomData(), state.getMetadata()); } private StatePersistence persistConcepts(String gameId, String playerId, List<GenericObjectPersistence> concepts) { return persist(gameId, playerId, concepts, null, null); } private StatePersistence persistCustomData(String gameId, String playerId, CustomData data) { return persist(gameId, playerId, null, data, null); } private StatePersistence persistCustomData(String gameId, String playerId, Map<String, Object> customData) { CustomData c = new CustomData(); c.putAll(customData); return persist(gameId, playerId, null, c, null); } private StatePersistence persistMetadata(String gameId, String playerId, Map<String, Object> metadata) { return persist(gameId, playerId, null, null, metadata); } private StatePersistence persist(String gameId, String playerId, List<GenericObjectPersistence> concepts, CustomData customData, Map<String, Object> metadata) { if (StringUtils.isBlank(gameId) || StringUtils.isBlank(playerId)) { throw new IllegalArgumentException("field gameId and playerId of PlayerState MUST be set"); } Criteria criteria = new Criteria(); criteria = criteria.and("gameId").is(gameId).and("playerId").is(playerId); Query query = new Query(criteria); Update update = new Update(); if (concepts != null) { update.set("concepts", concepts); } if (customData != null) { update.set("customData", customData); } if (metadata != null) { update.set("metadata", metadata); } FindAndModifyOptions options = new FindAndModifyOptions(); options.upsert(true); options.returnNew(true); return mongoTemplate.findAndModify(query, update, options, StatePersistence.class); } public List<String> readPlayers(String gameId) { List<StatePersistence> states = playerRepo.findByGameId(gameId); List<String> result = new ArrayList<String>(); for (StatePersistence state : states) { result.add(state.getPlayerId()); } return result; } @Override public Page<String> readPlayers(String gameId, Pageable pageable) { Page<StatePersistence> states = playerRepo.findByGameId(gameId, pageable); List<String> result = new ArrayList<String>(); for (StatePersistence state : states) { result.add(state.getPlayerId()); } PageImpl<String> res = new PageImpl<String>(result, pageable, states.getTotalElements()); return res; } public Page<PlayerState> loadStates(String gameId, Pageable pageable) { StopWatch stopWatch = LogManager.getLogger(StopWatch.DEFAULT_LOGGER_NAME).getAppender("perf-file") != null ? new Log4JStopWatch() : null; if (stopWatch != null) { stopWatch.start("loadStates"); } Page<StatePersistence> states = playerRepo.findByGameId(gameId, pageable); List<PlayerState> result = new ArrayList<PlayerState>(); for (StatePersistence state : states) { result.add(initConceptsStructure(new PlayerState(state), gameId)); } PageImpl<PlayerState> res = new PageImpl<PlayerState>(result, pageable, states.getTotalElements()); if (stopWatch != null) { stopWatch.stop("loadStates", "Loaded states of game " + gameId); } return res; } @Override public List<PlayerState> loadStates(String gameId) { List<StatePersistence> states = playerRepo.findByGameId(gameId); List<PlayerState> result = new ArrayList<PlayerState>(); for (StatePersistence state : states) { result.add(initConceptsStructure(new PlayerState(state), gameId)); } return result; } @Override public Page<PlayerState> loadStates(String gameId, String playerId, Pageable pageable) { Page<StatePersistence> states = playerRepo.findByGameIdAndPlayerIdLike(gameId, playerId, pageable); List<PlayerState> result = new ArrayList<PlayerState>(); for (StatePersistence state : states) { result.add(initConceptsStructure(new PlayerState(state), gameId)); } PageImpl<PlayerState> res = new PageImpl<PlayerState>(result, pageable, states.getTotalElements()); return res; } @Override public List<PlayerState> loadStates(String gameId, String playerId) { List<StatePersistence> states = playerRepo.findByGameIdAndPlayerIdLike(gameId, playerId); List<PlayerState> result = new ArrayList<PlayerState>(); for (StatePersistence state : states) { result.add(initConceptsStructure(new PlayerState(state), gameId)); } return result; } private PlayerState initConceptsStructure(PlayerState ps, String gameId) { if (ps != null) { Game g = gameSrv.loadGameDefinitionById(gameId); if (ps.getState() == null) { ps.setState(new HashSet<GameConcept>()); } if (g != null) { List<GameConcept> toAppend = new ArrayList<GameConcept>(); if (g.getConcepts() != null) { for (GameConcept gc : g.getConcepts()) { boolean found = false; for (GameConcept pgc : ps.getState()) { found = gc.getName().equals(pgc.getName()) && gc.getClass().equals(pgc.getClass()); if (found) { break; } } if (!found) { toAppend.add(gc); } } } ps.getState().addAll(toAppend); } } return ps; } @Override public TeamState saveTeam(TeamState team) { return (TeamState) saveState(team); } @Override public List<TeamState> readTeams(String gameId) { List<StatePersistence> result = playerRepo.findTeamsByGameId(gameId); List<TeamState> converted = new ArrayList<>(); for (StatePersistence sp : result) { converted.add(new TeamState(sp)); } return converted; } @Override public void deleteState(String gameId, String playerId) { playerRepo.deleteByGameIdAndPlayerId(gameId, playerId); } @Override public List<TeamState> readTeams(String gameId, String playerId) { List<StatePersistence> result = playerRepo.findTeamByMemberId(gameId, playerId); List<TeamState> converted = new ArrayList<>(); for (StatePersistence sp : result) { converted.add(new TeamState(sp)); } return converted; } @Override public TeamState addToTeam(String gameId, String teamId, String playerId) { StatePersistence state = playerRepo.findByGameIdAndPlayerId(gameId, teamId); if (state != null) { List<String> members = (List<String>) state.getMetadata().get(TeamState.MEMBERS_METADATA); if (members != null) { members.add(playerId); state.getMetadata().put(TeamState.MEMBERS_METADATA, members); playerRepo.save(state); } return new TeamState(state); } return null; } @Override public TeamState removeFromTeam(String gameId, String teamId, String playerId) { StatePersistence state = playerRepo.findByGameIdAndPlayerId(gameId, teamId); if (state != null) { List<String> members = (List<String>) state.getMetadata().get(TeamState.MEMBERS_METADATA); if (members != null) { members.remove(playerId); state.getMetadata().put(TeamState.MEMBERS_METADATA, members); playerRepo.save(state); } } return new TeamState(state); } @Override public TeamState readTeam(String gameId, String teamId) { return (TeamState) loadState(gameId, teamId, false); } @Override public PlayerState updateCustomData(String gameId, String playerId, Map<String, Object> data) { // findAndModify only customdata to avoid concurrent accesses on same // data StatePersistence state = persistCustomData(gameId, playerId, data); return new PlayerState(state); } }