Java tutorial
/* * 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 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; 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.EntryInfo; import org.noorganization.instalist.server.support.CommonEntity; import org.noorganization.instalist.server.TokenSecured; import org.noorganization.instalist.server.controller.IEntryController; import org.noorganization.instalist.server.controller.impl.ControllerFactory; import org.noorganization.instalist.comm.message.Error; import org.noorganization.instalist.server.model.*; 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; /** * Collection of available listEntries. * */ @Path("/groups/{groupid}/listentries") public class EntryResource { /** * Get a list of listEntries. * @param _groupId The id of the group containing various list-entries. * @param _changedSince Limits the result to elements that changed since the given date. ISO * 8601 time e.g. 2016-01-19T11:54:07+0100 */ @GET @TokenSecured @Produces({ "application/json" }) public Response getEntries(@PathParam("groupid") int _groupId, @QueryParam("changedsince") String _changedSince) throws Exception { List<ListEntry> foundEntries; List<DeletedObject> foundDeleted; EntityManager manager = DatabaseHelper.getInstance().getManager(); DeviceGroup group = manager.find(DeviceGroup.class, _groupId); if (_changedSince != null) { Instant changedSince; try { changedSince = ISO8601Utils.parse(_changedSince, new ParsePosition(0)).toInstant(); } catch (ParseException _e) { manager.close(); return ResponseFactory.generateBadRequest(CommonEntity.INVALID_CHANGEDATE); } TypedQuery<ListEntry> foundEntriesQuery = manager.createQuery( "select le from " + "ListEntry le where le.group = :group and le.updated > :updated", ListEntry.class); foundEntriesQuery.setParameter("group", group); foundEntriesQuery.setParameter("updated", changedSince); foundEntries = foundEntriesQuery.getResultList(); TypedQuery<DeletedObject> foundDeletedEntriesQuery = manager.createQuery( "select do " + "from DeletedObject do where do.group = :group and do.updated > :updated and " + "do.type = :type", DeletedObject.class); foundDeletedEntriesQuery.setParameter("group", group); foundDeletedEntriesQuery.setParameter("updated", changedSince); foundDeletedEntriesQuery.setParameter("type", DeletedObject.Type.LISTENTRY); foundDeleted = foundDeletedEntriesQuery.getResultList(); } else { foundEntries = new ArrayList<ListEntry>(group.getListEntries()); TypedQuery<DeletedObject> deletedEntriesQuery = manager.createQuery( "select do from " + "DeletedObject do where do.group = :group and do.type = :type", DeletedObject.class); deletedEntriesQuery.setParameter("group", group); deletedEntriesQuery.setParameter("type", DeletedObject.Type.LISTENTRY); foundDeleted = deletedEntriesQuery.getResultList(); } manager.close(); ArrayList<EntryInfo> rtn = new ArrayList<EntryInfo>(foundEntries.size() + foundDeleted.size()); for (ListEntry current : foundEntries) { EntryInfo toAdd = new EntryInfo().withDeleted(false); toAdd.setUUID(current.getUUID()); toAdd.setProductUUID(current.getProduct().getUUID()); toAdd.setListUUID(current.getList().getUUID()); toAdd.setAmount(current.getAmount()); toAdd.setPriority(current.getPriority()); toAdd.setStruck(current.getStruck()); toAdd.setLastChanged(Date.from(current.getUpdated())); rtn.add(toAdd); } for (DeletedObject current : foundDeleted) { EntryInfo toAdd = new EntryInfo(); toAdd.setUUID(current.getUUID()); toAdd.setLastChanged(Date.from(current.getUpdated())); toAdd.setDeleted(true); rtn.add(toAdd); } return ResponseFactory.generateOK(rtn); } /** * Returns a single list-entry. * @param _groupId The id of the group containing the entry. * @param _entryUUID The uuid of the entry itself. */ @GET @TokenSecured @Path("{entryuuid}") @Produces({ "application/json" }) public Response getEntry(@PathParam("groupid") int _groupId, @PathParam("entryuuid") String _entryUUID) throws Exception { UUID toFind; try { toFind = UUID.fromString(_entryUUID); } catch (IllegalArgumentException _e) { return ResponseFactory.generateBadRequest(CommonEntity.INVALID_UUID); } EntityManager manager = DatabaseHelper.getInstance().getManager(); DeviceGroup group = manager.find(DeviceGroup.class, _groupId); IEntryController entryController = ControllerFactory.getEntryController(manager); ListEntry foundEntry = entryController.findByGroupAndUUID(group, toFind); if (foundEntry == null) { if (entryController.findDeletedByGroupAndUUID(group, toFind) != null) { manager.close(); return ResponseFactory .generateGone(new Error().withMessage("The requested " + "listentry has been deleted.")); } manager.close(); return ResponseFactory .generateNotFound(new Error().withMessage("The requested " + "listentry was not found.")); } manager.close(); EntryInfo rtn = new EntryInfo().withDeleted(false); rtn.setUUID(foundEntry.getUUID()); rtn.setProductUUID(foundEntry.getProduct().getUUID()); rtn.setListUUID(foundEntry.getList().getUUID()); rtn.setAmount(foundEntry.getAmount()); rtn.setPriority(foundEntry.getPriority()); rtn.setStruck(foundEntry.getStruck()); rtn.setLastChanged(Date.from(foundEntry.getUpdated())); return ResponseFactory.generateOK(rtn); } /** * Updates an entry. * @param _groupId The id of the group containing the entry. * @param _entryUUID The uuid of the entry itself. * @param _entity Data for updating the entry. */ @PUT @TokenSecured @Path("{entryuuid}") @Consumes("application/json") @Produces({ "application/json" }) public Response putEntry(@PathParam("groupid") int _groupId, @PathParam("entryuuid") String _entryUUID, EntryInfo _entity) throws Exception { if ((_entity.getUUID() != null && !_entity.getUUID().equals(_entryUUID)) || (_entity.getDeleted() != null && _entity.getDeleted()) || (_entity.getAmount() != null && _entity.getAmount() < 0.001f)) return ResponseFactory.generateBadRequest(CommonEntity.INVALID_DATA); UUID toUpdate; UUID productUUID = null; UUID listUUID = null; try { toUpdate = UUID.fromString(_entryUUID); if (_entity.getProductUUID() != null) productUUID = UUID.fromString(_entity.getProductUUID()); if (_entity.getListUUID() != null) listUUID = UUID.fromString(_entity.getListUUID()); } catch (IllegalArgumentException _e) { return ResponseFactory.generateBadRequest(CommonEntity.INVALID_UUID); } Instant updated; if (_entity.getLastChanged() != null) { updated = _entity.getLastChanged().toInstant(); if (Instant.now().isBefore(updated)) return ResponseFactory.generateBadRequest(CommonEntity.INVALID_CHANGEDATE); } else updated = Instant.now(); EntityManager manager = DatabaseHelper.getInstance().getManager(); IEntryController entryController = ControllerFactory.getEntryController(manager); try { entryController.update(_groupId, toUpdate, productUUID, listUUID, _entity.getAmount(), _entity.getPriority(), _entity.getStruck(), updated); } catch (NotFoundException _e) { return ResponseFactory.generateNotFound(new Error().withMessage("The entry was not " + "found.")); } catch (GoneException _e) { return ResponseFactory.generateGone(new Error().withMessage("The entry has been " + "deleted.")); } catch (ConflictException _e) { return ResponseFactory.generateConflict( new Error().withMessage("The sent data would " + "conflict with saved list entry.")); } catch (BadRequestException _e) { return ResponseFactory.generateBadRequest( new Error().withMessage("The referenced " + "product or list was not found.")); } finally { manager.close(); } return ResponseFactory.generateOK(null); } /** * Creates the listEntry. * @param _groupId The id of the group containing the entry. * @param _entity Data for created the entry. */ @POST @TokenSecured @Consumes("application/json") @Produces({ "application/json" }) public Response postEntry(@PathParam("groupid") int _groupId, EntryInfo _entity) throws Exception { if (_entity.getUUID() == null || _entity.getListUUID() == null || _entity.getProductUUID() == null || (_entity.getDeleted() != null && _entity.getDeleted()) || (_entity.getAmount() != null && _entity.getAmount() < 0.001f)) return ResponseFactory.generateBadRequest(CommonEntity.INVALID_DATA); UUID toCreate; UUID productUUID; UUID listUUID; try { toCreate = UUID.fromString(_entity.getUUID()); productUUID = UUID.fromString(_entity.getProductUUID()); listUUID = UUID.fromString(_entity.getListUUID()); } catch (IllegalArgumentException _e) { return ResponseFactory.generateBadRequest(CommonEntity.INVALID_UUID); } Instant created; if (_entity.getLastChanged() != null) { created = _entity.getLastChanged().toInstant(); if (Instant.now().isBefore(created)) return ResponseFactory.generateBadRequest(CommonEntity.INVALID_CHANGEDATE); } else created = Instant.now(); float amount = (_entity.getAmount() != null ? _entity.getAmount() : 1f); int priority = (_entity.getPriority() != null ? _entity.getPriority() : 0); boolean struck = (_entity.getStruck() != null ? _entity.getStruck() : false); EntityManager manager = DatabaseHelper.getInstance().getManager(); IEntryController entryController = ControllerFactory.getEntryController(manager); try { entryController.add(_groupId, toCreate, productUUID, listUUID, amount, priority, struck, created); } catch (ConflictException _e) { return ResponseFactory.generateConflict( new Error().withMessage("The sent data would " + "conflict with saved list entry.")); } catch (BadRequestException _e) { return ResponseFactory.generateBadRequest( new Error().withMessage("The referenced " + "product or list was not found.")); } finally { manager.close(); } return ResponseFactory.generateCreated(null); } /** * Deletes the entry. * @param _groupId The id of the group containing the entry. * @param _entryUUID The uuid of the entry itself. */ @DELETE @TokenSecured @Path("{entryuuid}") @Produces({ "application/json" }) public Response deleteListEntryById(@PathParam("groupid") int _groupId, @PathParam("entryuuid") String _entryUUID) throws Exception { UUID toDelete; try { toDelete = UUID.fromString(_entryUUID); } catch (IllegalArgumentException _e) { return ResponseFactory.generateBadRequest(CommonEntity.INVALID_UUID); } EntityManager manager = DatabaseHelper.getInstance().getManager(); IEntryController entryController = ControllerFactory.getEntryController(manager); try { entryController.delete(_groupId, toDelete); } catch (NotFoundException _e) { return ResponseFactory.generateNotFound(new Error().withMessage("The entry was not " + "found.")); } catch (GoneException _e) { return ResponseFactory.generateGone(new Error().withMessage("The entry has been " + "deleted.")); } finally { manager.close(); } return ResponseFactory.generateOK(null); } }