Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package entity.service; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import document.DocumentFactory; import document.ResultExcelDocument; import document.StartlistExcelDocument; import ejb.StaticParameters; import entity.Contestant; import entity.Entry; import entity.EntryPK; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Properties; import java.util.stream.Collectors; import javax.ejb.Asynchronous; import javax.ejb.EJB; import javax.ejb.Stateless; import javax.inject.Inject; import javax.json.JsonObject; import javax.persistence.EntityManager; import javax.persistence.LockModeType; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.container.AsyncResponse; import javax.ws.rs.container.Suspended; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.PathSegment; import javax.ws.rs.core.Response; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVRecord; import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataParam; import resultevaluator.ResultEvaluator; import resultevaluator.ResultEvaluatorFactory; import resultevaluator.ResultParams; import resultevaluator.ResultType; import util.FileUtils; import util.JsonBuilder; import util.Utils; import viewmodel.EntryData; import viewmodel.ResultData; import ws.NotificationEndpoint; /** * * @author pekmil */ @Stateless @Path("entry") public class EntryFacadeREST extends AbstractFacade<Entry> { @PersistenceContext(unitName = "TriathlonManagerPU") private EntityManager em; @Inject ObjectMapper mapper; @Inject ResultEvaluatorFactory resultEvaluatorFactory; @Inject FileUtils fileUtils; @Inject Properties appParameters; @Inject DocumentFactory documentFactory; @EJB StaticParameters parameters; @EJB ClubFacadeREST clubFacade; @EJB ContestantFacadeREST contestantFacade; @EJB LicenceFacadeREST licenceFacade; private static final String[] CSV_HEADERS = new String[] { "name", "racenum", "gender", "birthyear", "category", "fromtown", "club", "licencenum", "agegroup", "paid" }; private EntryPK getPrimaryKey(PathSegment pathSegment) { /* * pathSemgent represents a URI path segment and any associated matrix parameters. * URI path part is supposed to be in form of 'somePath;raceId=raceIdValue;racenum=racenumValue'. * Here 'somePath' is a result of getPath() method invocation and * it is ignored in the following code. * Matrix parameters are used as field names to build a primary key instance. */ entity.EntryPK key = new entity.EntryPK(); javax.ws.rs.core.MultivaluedMap<String, String> map = pathSegment.getMatrixParameters(); java.util.List<String> raceId = map.get("raceId"); if (raceId != null && !raceId.isEmpty()) { key.setRaceId(new java.lang.Integer(raceId.get(0))); } java.util.List<String> racenum = map.get("racenum"); if (racenum != null && !racenum.isEmpty()) { key.setRacenum(new java.lang.String(racenum.get(0))); } return key; } public EntryFacadeREST() { super(Entry.class); } @POST @Override @Consumes({ "application/json" }) public void create(Entry entity) { super.create(entity); } @POST @Path("{raceid}") @Consumes({ "application/json" }) public void create(@PathParam("raceid") Integer raceid, EntryData data) { insertEntry(data, raceid); } @POST @Path("result/{raceid}") @Produces({ "application/json" }) public Response setRacetime(@PathParam("raceid") Integer raceid, ResultData resultData) { EntryPK key = new EntryPK(raceid, resultData.getRacenum()); Entry entry = em.find(Entry.class, key, LockModeType.PESSIMISTIC_WRITE); if (entry.getStatus().equals("CHECKED") && entry.getRacetime() == null) { entry.setFinishtime(new Date()); entry.setRacetime(resultData.getRacetime()); entry.applyResultmods(resultData, parameters.getResultmods()); entry.applyRaceadjustments(parameters.getRaceadjustmentsToRace(raceid)); entry.setStatus("FINISHED"); em.merge(entry); } else { JsonObject jsonMsg = JsonBuilder.getJsonMsg( "Az eredmny mr rgztsre kerlt vagy nem a megfelel llapotban van!", JsonBuilder.MsgType.WARNING, null); return Response.status(500).entity(jsonMsg).build(); } String msg = "Eredmny rgztve: " + entry.getContestant().getName() + " (" + entry.getKey().getRacenum() + ") - " + Utils.simpleTimeFormat.format(entry.getRacetime()); JsonObject jsonMsg = JsonBuilder.getJsonMsg(msg, JsonBuilder.MsgType.INFO, null); NotificationEndpoint.send(msg); return Response.ok(jsonMsg).build(); } @POST @Path("resultmod/{raceid}") @Produces({ "application/json" }) public Response applyResultmod(@PathParam("raceid") Integer raceid, ResultData resultData) { EntryPK key = new EntryPK(raceid, resultData.getRacenum()); Entry entry = em.find(Entry.class, key, LockModeType.PESSIMISTIC_WRITE); if (entry.getStatus().equals("FINISHED") && entry.getRacetime() != null) { entry.applyResultmods(resultData, parameters.getResultmods()); em.merge(entry); } else { JsonObject jsonMsg = JsonBuilder.getJsonMsg("Az eredmny nem a megfelel llapotban van!", JsonBuilder.MsgType.WARNING, null); return Response.status(500).entity(jsonMsg).build(); } String msg = "Eredmny mdost ttel alkalmazva: " + entry.getContestant().getName() + " (" + entry.getKey().getRacenum() + ") - " + Utils.simpleTimeFormat.format(entry.getRacetime()); JsonObject jsonMsg = JsonBuilder.getJsonMsg(msg, JsonBuilder.MsgType.INFO, null); NotificationEndpoint.send(msg); return Response.ok(jsonMsg).build(); } public Response modifyRacetime(Integer raceid, ResultData resultData) { EntryPK key = new EntryPK(raceid, resultData.getRacenum()); Entry entry = em.find(Entry.class, key, LockModeType.PESSIMISTIC_WRITE); if (entry.getStatus().equals("FINISHED") && entry.getRacetime() != null) { entry.appendRacetimeMod(resultData.getRacetimemoddesc()); entry.setRacetime(resultData.getRacetime()); em.merge(entry); } else { JsonObject jsonMsg = JsonBuilder.getJsonMsg("Az eredmny nem a megfelel llapotban van!", JsonBuilder.MsgType.WARNING, null); return Response.status(500).entity(jsonMsg).build(); } String msg = "Eredmny mdostva: " + entry.getContestant().getName() + " (" + entry.getKey().getRacenum() + ") - " + Utils.simpleTimeFormat.format(entry.getRacetime()); JsonObject jsonMsg = JsonBuilder.getJsonMsg(msg, JsonBuilder.MsgType.INFO, null); return Response.ok(jsonMsg).build(); } @GET @Path("finishedresults/{raceid}") @Produces({ "application/json" }) public List<Entry> getFinishedResults(@PathParam("raceid") Integer raceid) { List<Entry> entries = (List) em.createQuery( "SELECT e FROM Entry e WHERE e.key.raceId = :raceid AND e.status = 'FINISHED' AND e.racetime IS NOT NULL") .setParameter("raceid", raceid).getResultList(); return entries; } @POST @Path("raceresults/{raceid}/{categoryid}") @Consumes({ "application/json" }) @Produces({ "application/json" }) public Response getRaceResultsForCategory(@PathParam("raceid") Integer raceid, @PathParam("categoryid") Integer categoryid, ResultParams params) throws JsonProcessingException { Object results = getResults(raceid, categoryid, params); String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(results); return Response.ok(json).build(); } @GET @Path("getdocument/{filename}") @Produces("application/vnd.ms-excel") public Response getFile(@PathParam("filename") String filename) { if (filename.matches("(eredmenylista_|rajtlista_|invalid_licences_).*\\.(xlsx|csv)")) { return Response.ok(new File(appParameters.getProperty("documentFolder") + filename)) .header("Content-Disposition", "attachment; filename=" + filename).build(); } else { return Response.status(Response.Status.FORBIDDEN).build(); } } @POST @Path("resultlist/{raceid}/{categoryid}") @Produces({ "application/json" }) @Asynchronous public void generateResultlist(@Suspended final AsyncResponse asyncResponse, @PathParam("raceid") Integer raceid, @PathParam("categoryid") Integer categoryid, ResultParams params) { Object results = getResults(raceid, categoryid, params); ResultExcelDocument doc = documentFactory.createResultlist(params.getResultType()); String categoryName = ""; if (params.getResultType() != ResultType.FAMILY) { categoryName = parameters.getCategories().values().stream() .filter(c -> Objects.equals(c.getId(), categoryid)).collect(Collectors.toList()).get(0) .getName(); } doc.withCategoryName(categoryName).withResults(results); if (doc.generate()) { HashMap<String, Object> msgParams = new HashMap<>(); msgParams.put("filename", doc.getFileName()); JsonObject jsonMsg = JsonBuilder.getJsonMsg("Eredmnylista ellltsa sikeres!", JsonBuilder.MsgType.ERROR, msgParams); asyncResponse.resume(Response.ok(jsonMsg).build()); } else { JsonObject jsonMsg = JsonBuilder.getJsonMsg("Dokumentum generlsi hiba!", JsonBuilder.MsgType.ERROR, null); asyncResponse.resume(Response.ok(jsonMsg).status(Response.Status.INTERNAL_SERVER_ERROR).build()); } } private Object getResults(Integer raceid, Integer categoryid, ResultParams params) { String queryString = "SELECT e FROM Entry e " + "WHERE e.key.raceId = :raceid " + "AND e.status IN :statuses"; List<String> statuses = new ArrayList<>(); statuses.add("FINISHED"); if (params.getResultType() == ResultType.GROUPED) { statuses.add("NOTPRESENT"); statuses.add("DSQ"); statuses.add("DNF"); statuses.add("NOTSTARTED"); } else { queryString = queryString + " AND e.racetime IS NOT NULL"; } if (!params.isFamily()) { queryString = queryString + " AND e.category.id = :categoryid"; } if (params.isNational()) { queryString = queryString + " AND e.licencenum IS NOT NULL AND e.licencenum != ''"; } if (params.isTeam()) { queryString = queryString + " AND e.contestant.club IS NOT NULL"; } Query query = em.createQuery(queryString).setParameter("raceid", raceid); if (!params.isFamily()) query.setParameter("categoryid", categoryid); query.setParameter("statuses", statuses); List<Entry> entries = (List) query.getResultList(); ResultEvaluator results = resultEvaluatorFactory.getResultEvaluator(params.getResultType()); return results.getResults(entries, parameters.getAgegroups()); } @GET @Path("startlist/{raceid}/{categoryid}") @Produces("application/json") @Asynchronous public void generateStartlist(@Suspended final AsyncResponse asyncResponse, @PathParam("raceid") Integer raceid, @PathParam("categoryid") Integer categoryid) { List<Entry> entries = (List) em .createQuery("SELECT e " + "FROM Entry e " + "WHERE e.key.raceId = :raceid AND " + "e.status = 'CHECKED' AND " + "e.category.id = :categoryid") .setParameter("raceid", raceid).setParameter("categoryid", categoryid).getResultList(); Map<String, List<Entry>> entriesByGender = entries.stream() .sorted((e1, e2) -> e1.getKey().getRacenum().compareTo(e2.getKey().getRacenum())) .collect(Collectors.groupingBy(e -> e.getContestant().getGender())); if (!entries.isEmpty()) { String categoryName = entries.get(0).getCategoryName(); StartlistExcelDocument startDoc = documentFactory.createStartlist(); startDoc.withCategoryName(categoryName).withEntries(entriesByGender); if (startDoc.generate()) { HashMap<String, Object> msgParams = new HashMap<>(); msgParams.put("filename", startDoc.getFileName()); JsonObject jsonMsg = JsonBuilder.getJsonMsg("Dokumentum ellltsa sikeres!", JsonBuilder.MsgType.SUCCESS, msgParams); asyncResponse.resume(Response.ok(jsonMsg).build()); } else { JsonObject jsonMsg = JsonBuilder.getJsonMsg("Dokumentum generlsi hiba!", JsonBuilder.MsgType.ERROR, null); asyncResponse.resume(Response.ok(jsonMsg).status(Response.Status.INTERNAL_SERVER_ERROR).build()); } } JsonObject jsonMsg = JsonBuilder.getJsonMsg("Nincsenek nevezsek!", JsonBuilder.MsgType.ERROR, null); asyncResponse.resume(Response.ok(jsonMsg).build()); } @POST @Path("/uploadcsv") @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces("application/json; charset=UTF-8") public Response uploadCSV(@FormDataParam("uploadFile") InputStream fileInputStream, @FormDataParam("uploadFile") FormDataContentDisposition fileFormDataContentDisposition) throws IOException { return fileUtils.uploadCSV(fileInputStream, "preentries_"); } @POST @Path("/processcsv/{raceid}") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Produces("application/json; charset=UTF-8") public Response processCSV(@FormParam("filename") String fileName, @PathParam("raceid") Integer raceid) { parameters.initClubs(); List<String> invalidLicences = new ArrayList<>(); invalidLicences.add("nev;rajtszam;licensz"); try (Reader in = new InputStreamReader( new FileInputStream(appParameters.getProperty("uploadFolder") + fileName), "UTF-8")) { Iterable<CSVRecord> records = CSVFormat.EXCEL.withSkipHeaderRecord().withDelimiter(';') .withHeader(CSV_HEADERS).withNullString("").parse(in); int count = 0; for (CSVRecord record : records) { EntryData ed = new EntryData(); ed.setPreentry(true); ed.setStatus("PRE"); ed.setName(record.get("name")); ed.setRacenum(record.get("racenum")); ed.setGender(record.get("gender")); ed.setBirthYear(Short.valueOf(record.get("birthyear"))); ed.setCategory(record.get("category")); ed.setFromTown(record.get("fromtown")); ed.setClubName(record.get("club")); ed.setAgegroup(record.get("agegroup")); ed.setPaid(record.get("paid").equals("IGEN")); ed.setRemainingpayment( record.get("paid").matches("[1-9]\\d{0,10}") ? Integer.parseInt(record.get("paid")) : 0); ed.setLicencenum(record.get("licencenum")); if (ed.getLicencenum() != null && !ed.getLicencenum().isEmpty()) { if (!licenceFacade.exists(ed.getLicencenum())) { invalidLicences.add(ed.getName() + ";" + ed.getRacenum() + ";" + ed.getLicencenum()); } } insertEntry(ed, raceid); ++count; } String invalidLicencesFileName = "invalid_licences_" + fileName; Files.write(Paths.get(appParameters.getProperty("uploadFolder"), invalidLicencesFileName), invalidLicences, Charset.forName("UTF-8")); HashMap<String, Object> params = new HashMap<>(); params.put("invalidLicences", invalidLicencesFileName); JsonObject jsonMsg = JsonBuilder.getJsonMsg(count + " db elnevezs beolvasva!", JsonBuilder.MsgType.INFO, params); return Response.ok(String.valueOf(jsonMsg)).build(); } catch (FileNotFoundException ex) { HashMap<String, Object> params = new HashMap<>(); params.put("fileName", fileName); JsonObject jsonMsg = JsonBuilder.getJsonMsg("A megadott fjl nem tallhat!", JsonBuilder.MsgType.ERROR, params); return Response.status(500).entity(jsonMsg).build(); } catch (IOException ex) { HashMap<String, Object> params = new HashMap<>(); params.put("fileName", fileName); JsonObject jsonMsg = JsonBuilder.getJsonMsg("Hiba a CSV fjl beolvassa kzben!", JsonBuilder.MsgType.ERROR, params); return Response.status(500).entity(jsonMsg).build(); } } private void insertEntry(EntryData ed, Integer raceId) { Contestant c = new Contestant(); c.setBirthyear(ed.getBirthYear()); c.setFromtown(ed.getFromTown()); c.setGender(ed.getGender()); c.setName(ed.getName()); String clubName = ed.getClubName(); if (clubName != null) { if (parameters.getClub(clubName) == null) { clubFacade.insert(clubName); } c.setClub(parameters.getClub(clubName)); } contestantFacade.create(c); em.flush(); Entry e = new Entry(raceId, ed.getRacenum()); e.setContestant(c); e.setAgegroup(parameters.getAgegroup(ed.getAgegroup())); e.setCategory(parameters.getCategory(ed.getCategory())); e.setEntrytime(new Date()); e.setPreentry(ed.isPreentry()); e.setStatus(ed.getStatus()); e.setPaid(ed.isPaid()); e.setRemainingpayment(ed.getRemainingpayment()); e.setLicencenum(ed.getLicencenum()); create(e); } public int modifyEntries(int raceId, List<Integer> racenums, String dbField, Object dbValue) { StringBuilder query = new StringBuilder("UPDATE Entry e SET "); query.append("e.").append(dbField).append(" = :value ") .append("WHERE e.key.raceId = :raceid AND e.key.racenum IN :racenums"); return em.createQuery(query.toString()).setParameter("value", dbValue).setParameter("raceid", raceId) .setParameter("racenums", racenums).executeUpdate(); } @PUT @Consumes({ "application/json" }) public void updateEntry(Entry entity) { Entry entry = (Entry) em .createQuery("SELECT e FROM Entry e WHERE e.key.raceId = :raceid AND e.key.racenum = :racenum") .setParameter("raceid", entity.getKey().getRaceId()) .setParameter("racenum", entity.getKey().getRacenum()).getSingleResult(); entry.setAgegroup(entity.getAgegroup()); entry.setCategory(entity.getCategory()); entry.setLicencenum(entity.getLicencenum()); entry.setPaid(entity.isPaid()); entry.setFamilyentry(entity.getFamilyentry()); entry.setInvoice(entity.getInvoice()); entry.setStatus(entity.getStatus()); super.edit(entity); } @DELETE @Path("raceid/{raceid}/racenum/{racenum}") public void remove(@PathParam("raceid") int raceid, @PathParam("racenum") String racenum) { entity.EntryPK key = new EntryPK(raceid, racenum); super.remove(super.find(key)); } @GET @Path("raceid/{raceid}/racenum/{racenum}") @Produces({ "application/json" }) public Entry find(@PathParam("raceid") int raceid, @PathParam("racenum") String racenum) { entity.EntryPK key = new EntryPK(raceid, racenum); return super.find(key); } @GET @Path("rid/{id}") @Produces({ "application/json" }) public List<Entry> findAll(@PathParam("id") Integer id) { List<Entry> result = (List) em.createQuery("SELECT e FROM Entry e WHERE e.key.raceId = :raceid") .setParameter("raceid", id).getResultList(); return result; } @GET @Override @Produces({ "application/json" }) public List<Entry> findAll() { return super.findAll(); } @GET @Path("{from}/{to}") @Produces({ "application/json" }) public List<Entry> findRange(@PathParam("from") Integer from, @PathParam("to") Integer to) { return super.findRange(new int[] { from, to }); } @GET @Path("count") @Produces("text/plain") public String countREST() { return String.valueOf(super.count()); } @Override protected EntityManager getEntityManager() { return em; } }