/* Copyright 2011-2014 Red Hat, Inc This file is part of PressGang CCMS. PressGang CCMS is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. PressGang CCMS 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with PressGang CCMS. If not, see <http://www.gnu.org/licenses/>. */ package org.jboss.pressgang.ccms.server.rest.v1; import javax.enterprise.context.RequestScoped; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import org.jboss.pressgang.ccms.model.base.PressGangEntity; import org.jboss.pressgang.ccms.rest.v1.entities.base.RESTBaseEntityV1; import org.jboss.pressgang.ccms.utils.structures.Pair; @RequestScoped public class EntityCache { private static final Integer NEW_STATE = 0; private static final Integer UPDATED_STATE = 1; private final AtomicInteger counter = new AtomicInteger(-10000); private Map<RESTBaseEntityV1, Pair<PressGangEntity, Integer>> entities = new HashMap<RESTBaseEntityV1, Pair<PressGangEntity, Integer>>(); public <U extends PressGangEntity> void addNew(RESTBaseEntityV1 restEntity, U dbEntity) { if (restEntity.getId() == null) { restEntity.setId(getNextId()); } entities.put(restEntity, new Pair<PressGangEntity, Integer>(dbEntity, NEW_STATE)); } public void addUpdated(RESTBaseEntityV1 restEntity, PressGangEntity dbEntity) { entities.put(restEntity, new Pair<PressGangEntity, Integer>(dbEntity, UPDATED_STATE)); } public void remove(RESTBaseEntityV1 restEntity) { entities.remove(restEntity); } public <T> boolean containsRESTEntity(final RESTBaseEntityV1 restEntity) { return entities.containsKey(restEntity); } public PressGangEntity get(final RESTBaseEntityV1 restEntity) { final Pair<PressGangEntity, Integer> entity = entities.get(restEntity); return entity == null ? null : entity.getFirst(); } public <U> List<U> getNewEntities(final Class<U> clazz) { return getEntitiesWithState(clazz, NEW_STATE); } public <U> List<U> getUpdatedEntities(final Class<U> clazz) { return getEntitiesWithState(clazz, UPDATED_STATE); } public <U> List<U> getEntities(final Class<U> clazz) { final List<U> entities = new ArrayList<U>(); for (final Map.Entry<RESTBaseEntityV1, Pair<PressGangEntity, Integer>> entry : this.entities.entrySet()) { if (entry.getValue().getFirst().getClass().equals(clazz)) { entities.add((U) entry.getValue().getFirst()); } } return entities; } public List<PressGangEntity> getAllEntities() { final List<PressGangEntity> entities = new ArrayList<PressGangEntity>(); for (final Map.Entry<RESTBaseEntityV1, Pair<PressGangEntity, Integer>> entry : this.entities.entrySet()) { entities.add(entry.getValue().getFirst()); } return entities; } protected <U> List<U> getEntitiesWithState(final Class<U> clazz, final Integer state) { final List<U> entities = new ArrayList<U>(); for (final Map.Entry<RESTBaseEntityV1, Pair<PressGangEntity, Integer>> entry : this.entities.entrySet()) { if (entry.getValue().getSecond().equals(state) && entry.getValue().getFirst().getClass().equals(clazz)) { entities.add((U) entry.getValue().getFirst()); } } return entities; } public int size() { return entities.size(); } protected synchronized Integer getNextId() { Integer count = counter.get(); if (count == Integer.MIN_VALUE) { counter.set(-10000); return -10000; } else { return counter.getAndDecrement(); } } }