org.noorganization.instalist.server.api.UnitResource.java Source code

Java tutorial

Introduction

Here is the source code for org.noorganization.instalist.server.api.UnitResource.java

Source

/*
 * Copyright 2016 Tino Siegmund, Michael Wodniok
 *
 * 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 org.noorganization.instalist.server.api;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;

import com.fasterxml.jackson.databind.util.ISO8601Utils;
import org.noorganization.instalist.comm.message.UnitInfo;
import org.noorganization.instalist.server.support.CommonEntity;
import org.noorganization.instalist.server.TokenSecured;
import org.noorganization.instalist.server.controller.IUnitController;
import org.noorganization.instalist.server.controller.impl.ControllerFactory;
import org.noorganization.instalist.comm.message.Error;
import org.noorganization.instalist.server.model.DeletedObject;
import org.noorganization.instalist.server.model.DeviceGroup;
import org.noorganization.instalist.server.model.Unit;
import org.noorganization.instalist.server.support.DatabaseHelper;
import org.noorganization.instalist.server.support.ResponseFactory;
import org.noorganization.instalist.server.support.exceptions.ConflictException;
import org.noorganization.instalist.server.support.exceptions.GoneException;

import java.text.ParseException;
import java.text.ParsePosition;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * Collection of available units.
 * 
 */
@Path("/groups/{groupid}/units")
public class UnitResource {

    /**
     * Get a list of units.
     * @param _groupId The id of the group containing the requested units.
     * @param _changedSince Requests only the elements that changed since the given date. ISO
     *                     8601 time e.g. 2016-01-19T11:54:07+01:00
     */
    @GET
    @TokenSecured
    @Produces({ "application/json" })
    public Response getUnits(@PathParam("groupid") int _groupId, @QueryParam("changedsince") String _changedSince)
            throws Exception {
        Instant changedSince = null;
        try {
            if (_changedSince != null)
                changedSince = ISO8601Utils.parse(_changedSince, new ParsePosition(0)).toInstant();
        } catch (ParseException _e) {
            return ResponseFactory.generateBadRequest(CommonEntity.INVALID_CHANGEDATE);
        }

        EntityManager manager = DatabaseHelper.getInstance().getManager();
        DeviceGroup group = manager.find(DeviceGroup.class, _groupId);
        List<Unit> resultUnits;
        List<DeletedObject> resultDeletedUnits;

        if (changedSince == null) {
            resultUnits = new ArrayList<Unit>(group.getUnits());
            TypedQuery<DeletedObject> deletedUnitsQuery = manager.createQuery(
                    "select do from " + "DeletedObject do where do.group = :group and do.type = :type",
                    DeletedObject.class);
            deletedUnitsQuery.setParameter("group", group);
            deletedUnitsQuery.setParameter("type", DeletedObject.Type.UNIT);
            resultDeletedUnits = deletedUnitsQuery.getResultList();
        } else {
            TypedQuery<Unit> unitsQuery = manager.createQuery(
                    "select u from Unit u where " + "u.group = :group and u.updated > :updated", Unit.class);
            unitsQuery.setParameter("group", group);
            unitsQuery.setParameter("updated", changedSince);
            resultUnits = unitsQuery.getResultList();

            TypedQuery<DeletedObject> deletedUnitsQuery = manager.createQuery("select do from "
                    + "DeletedObject do where do.group = :group and do.type = :type and " + "do.updated > :updated",
                    DeletedObject.class);
            deletedUnitsQuery.setParameter("group", group);
            deletedUnitsQuery.setParameter("type", DeletedObject.Type.UNIT);
            deletedUnitsQuery.setParameter("updated", changedSince);
            resultDeletedUnits = deletedUnitsQuery.getResultList();
        }
        manager.close();

        List<UnitInfo> rtn = new ArrayList<UnitInfo>(resultUnits.size() + resultDeletedUnits.size());
        for (Unit current : resultUnits) {
            UnitInfo info = new UnitInfo().withDeleted(false);
            info.setName(current.getName());
            info.setUUID(current.getUUID());
            info.setLastChanged(Date.from(current.getUpdated()));
            rtn.add(info);
        }
        for (DeletedObject current : resultDeletedUnits) {
            UnitInfo info = new UnitInfo().withDeleted(true);
            info.setUUID(current.getUUID());
            info.setLastChanged(Date.from(current.getUpdated()));
            rtn.add(info);
        }

        return ResponseFactory.generateOK(rtn);
    }

    /**
     * Returns the unit.
     * @param _groupId The croup containing the requested unit.
     * @param _unitUUID The uuid of the requested unit.
     */
    @GET
    @TokenSecured
    @Path("{unituuid}")
    @Produces({ "application/json" })
    public Response getUnit(@PathParam("groupid") int _groupId, @PathParam("unituuid") String _unitUUID)
            throws Exception {
        try {

            UUID toFind;
            try {
                toFind = UUID.fromString(_unitUUID);
            } catch (IllegalArgumentException _e) {
                return ResponseFactory.generateBadRequest(CommonEntity.INVALID_UUID);
            }

            EntityManager manager = DatabaseHelper.getInstance().getManager();
            IUnitController unitController = ControllerFactory.getUnitController(manager);
            DeviceGroup group = manager.find(DeviceGroup.class, _groupId);

            Unit resultUnit = unitController.findByGroupAndUUID(group, toFind);
            if (resultUnit == null) {
                if (unitController.findDeletedByGroupAndUUID(group, toFind) == null) {
                    manager.close();
                    return ResponseFactory
                            .generateNotFound(new Error().withMessage("The requested " + "unit was not found."));
                }
                manager.close();
                return ResponseFactory
                        .generateGone(new Error().withMessage("The requested unit has " + "been deleted."));
            }
            manager.close();

            UnitInfo rtn = new UnitInfo().withDeleted(false);
            rtn.setName(resultUnit.getName());
            rtn.setUUID(resultUnit.getUUID());
            rtn.setLastChanged(Date.from(resultUnit.getUpdated()));

            return ResponseFactory.generateOK(rtn);
        } catch (Exception _e) {
            _e.printStackTrace();
            throw _e;
        }
    }

    /**
     * Updates the unit.
     * @param _groupId The id of the group containing the unit.
     * @param _unitUUID The existing Unit-UUID to update.
     * @param _entity The data for update.
     */
    @PUT
    @TokenSecured
    @Path("{unituuid}")
    @Consumes("application/json")
    @Produces({ "application/json" })
    public Response putUnit(@PathParam("groupid") int _groupId, @PathParam("unituuid") String _unitUUID,
            UnitInfo _entity) throws Exception {
        UUID toUpdate;
        try {
            toUpdate = UUID.fromString(_unitUUID);
        } catch (IllegalArgumentException _e) {
            return ResponseFactory.generateBadRequest(CommonEntity.INVALID_UUID);
        }
        Instant changeDate;
        if (_entity.getLastChanged() == null)
            changeDate = Instant.now();
        else {
            changeDate = _entity.getLastChanged().toInstant();
            if (Instant.now().isBefore(changeDate))
                return ResponseFactory.generateBadRequest(CommonEntity.INVALID_CHANGEDATE);
        }
        if ((_entity.getDeleted() != null && _entity.getDeleted())
                || (_entity.getUUID() != null && !_entity.getUUID().equals(_unitUUID)))
            return ResponseFactory.generateBadRequest(CommonEntity.INVALID_DATA);

        EntityManager manager = DatabaseHelper.getInstance().getManager();
        IUnitController unitController = ControllerFactory.getUnitController(manager);
        try {
            unitController.update(_groupId, toUpdate, _entity.getName(), changeDate);
        } catch (NotFoundException _e) {
            return ResponseFactory
                    .generateNotFound(new Error().withMessage("The unit to change " + "was not found."));
        } catch (GoneException _e) {
            return ResponseFactory.generateGone(
                    new Error().withMessage("The unit to change was " + "not found since it has been deleted."));
        } catch (ConflictException _e) {
            return ResponseFactory.generateConflict(
                    new Error().withMessage("The sent data would " + "lead to a conflict with saved unit."));
        } finally {
            manager.close();
        }

        return ResponseFactory.generateOK(null);
    }

    /**
     * Creates the unit.
     * @param _groupId The group-id the new Unit should belong to.
     * @param _entity Data of the new unit.
     */
    @POST
    @TokenSecured
    @Consumes("application/json")
    @Produces({ "application/json" })
    public Response postUnit(@PathParam("groupid") int _groupId, UnitInfo _entity) throws Exception {
        if (_entity.getUUID() == null || (_entity.getDeleted() != null && _entity.getDeleted())
                || _entity.getName() == null || _entity.getName().length() == 0)
            return ResponseFactory.generateBadRequest(CommonEntity.INVALID_DATA);

        UUID toInsert;
        try {
            toInsert = UUID.fromString(_entity.getUUID());
        } catch (IllegalArgumentException _e) {
            return ResponseFactory.generateBadRequest(CommonEntity.INVALID_UUID);
        }

        Instant insertDate;
        if (_entity.getLastChanged() == null)
            insertDate = Instant.now();
        else {
            insertDate = _entity.getLastChanged().toInstant();
            if (Instant.now().isBefore(insertDate))
                return ResponseFactory.generateBadRequest(CommonEntity.INVALID_CHANGEDATE);
        }

        EntityManager manager = DatabaseHelper.getInstance().getManager();
        IUnitController unitController = ControllerFactory.getUnitController(manager);
        try {
            unitController.add(_groupId, toInsert, _entity.getName(), insertDate);
        } catch (ConflictException _e) {
            return ResponseFactory.generateConflict(
                    new Error().withMessage("The sent data would " + "lead to a conflict with saved unit."));
        } finally {
            manager.close();
        }

        return ResponseFactory.generateCreated(null);
    }

    /**
     * Deletes the unit.
     * @param _groupId The groups id containing the existing unit.
     * @param _unitUUID The uuid of the unit to delete.
     */
    @DELETE
    @TokenSecured
    @Path("{unituuid}")
    @Produces({ "application/json" })
    public Response deleteUnit(@PathParam("groupid") int _groupId, @PathParam("unituuid") String _unitUUID)
            throws Exception {
        UUID toDelete;
        try {
            toDelete = UUID.fromString(_unitUUID);
        } catch (IllegalArgumentException _e) {
            return ResponseFactory.generateBadRequest(CommonEntity.INVALID_UUID);
        }

        EntityManager manager = DatabaseHelper.getInstance().getManager();
        IUnitController unitController = ControllerFactory.getUnitController(manager);
        try {
            unitController.delete(_groupId, toDelete);
        } catch (NotFoundException _e) {
            return ResponseFactory.generateNotFound(new Error().withMessage("The unit was not " + "found."));
        } catch (GoneException _e) {
            return ResponseFactory
                    .generateGone(new Error().withMessage("The unit has been " + "already deleted before."));
        } finally {
            manager.close();
        }

        return ResponseFactory.generateOK(null);
    }

}