View Javadoc
1   package pl.matsuo.core.web.controller.print;
2   
3   import org.springframework.beans.factory.annotation.Autowired;
4   import org.springframework.transaction.annotation.Transactional;
5   import org.springframework.web.bind.annotation.PathVariable;
6   import org.springframework.web.bind.annotation.RequestMapping;
7   import org.springframework.web.bind.annotation.RequestParam;
8   import org.springframework.web.bind.annotation.RestController;
9   import pl.matsuo.core.model.print.IPrintFacade;
10  import pl.matsuo.core.model.print.KeyValuePrint;
11  import pl.matsuo.core.model.print.initializer.PrintInitializer;
12  import pl.matsuo.core.model.query.condition.QueryPart;
13  import pl.matsuo.core.model.report.IPrintsReportParams;
14  import pl.matsuo.core.service.db.Database;
15  import pl.matsuo.core.service.facade.IFacadeBuilder;
16  import pl.matsuo.core.service.print.AbstractPrintService;
17  import pl.matsuo.core.service.print.IPrintsRendererService;
18  
19  import javax.servlet.http.HttpServletResponse;
20  import java.io.IOException;
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.HashMap;
24  import java.util.List;
25  import java.util.Map;
26  
27  import static java.util.Arrays.*;
28  import static javax.servlet.http.HttpServletResponse.*;
29  import static org.apache.commons.io.IOUtils.*;
30  import static org.springframework.core.GenericTypeResolver.*;
31  import static org.springframework.http.MediaType.*;
32  import static org.springframework.util.StringUtils.*;
33  import static org.springframework.web.bind.annotation.RequestMethod.*;
34  import static pl.matsuo.core.model.query.QueryBuilder.*;
35  
36  
37  /**
38   * Kontroler generowania druków.
39   *
40   * @author Marek Romanowski
41   * @since Aug 28, 2013
42   */
43  @RestController
44  @Transactional
45  @RequestMapping("/prints")
46  public class PrintController {
47  
48  
49    @Autowired
50    protected Database database;
51    @Autowired
52    protected IPrintsRendererService printsRendererService;
53    @Autowired
54    protected IFacadeBuilder facadeBuilder;
55    Map<Class, AbstractPrintService> reportServicesMap;
56  
57  
58  //  @RequestMapping(value = "/dbGui", method = GET)
59  //  public void startDbGui() {
60  //    DatabaseManagerSwing.main(new String[]{ "--url", "jdbc:hsqldb:mem:test", "--user", "sa", "--noexit"});
61  //  }
62  
63  
64    @RequestMapping(value = "/{id}", method = GET)
65    public void generatePrint(@PathVariable("id") Integer id, HttpServletResponse response) {
66      try {
67        KeyValuePrint print = database.findById(KeyValuePrint.class, id, new PrintInitializer());
68        if (print == null) {
69          response.sendError(SC_NOT_FOUND);
70          return;
71        }
72  
73        generatePrint(print, response);
74      } catch (Exception e) {
75        throw new RuntimeException(e);
76      }
77    }
78  
79  
80    /**
81     * Metoda specjalnie nie ma RequestMapping.
82     */
83    public void generatePrint(KeyValuePrint print, HttpServletResponse response) {
84      try {
85        AbstractPrintService printService = reportServicesMap.get(print.getPrintClass());
86  
87        if (printService == null) {
88          throw new IllegalArgumentException("Unknown report " + print.getPrintClass());
89        }
90  
91        IPrintFacade printFacade = facadeBuilder.createFacade(print, print.getPrintClass());
92  
93        Map<String, Object> model = printService.buildModel(printFacade);
94        // default dla druków
95        model.put("outputFormat", "pdf");
96  
97        generatePrint(uncapitalize(print.getPrintClass().getSimpleName()) + ".ftl",
98            printService.getFileName(printFacade), model, response);
99      } catch (Exception e) {
100       throw new RuntimeException(e);
101     }
102   }
103 
104 
105   protected List<KeyValuePrint> findPrints(IPrintsReportParams params, String personProperty, QueryPart... queryParts) {
106     return database.find(query(KeyValuePrint.class, select("keyValuePrint"),
107         maybeEq(params.getIdPatient(), personProperty),
108         maybeEq(params.getIdPayer(), "keyValuePrint.fields['buyer.id']"),
109         maybe(params.getStartDate(), ge("keyValuePrint.createdTime", params.getStartDate())),
110         maybe(params.getEndDate(), le("keyValuePrint.createdTime", params.getEndDate())),
111         maybeEq(params.getPrintClass(), "keyValuePrint.printClass"))
112         .parts(queryParts).initializer(new PrintInitializer()));
113   }
114 
115 
116   @RequestMapping(method = GET)
117   public List<KeyValuePrint> list(IPrintsReportParams params) {
118     // FIXME! przemyśleć referencję do Appointment - czy to wydzielić do oddzielnego kontrolera, czy coś innego z tym zrobić?
119 //    List<KeyValuePrint> prints3 = findPrints(params, "appointment.idPatient",
120 //        new LeftJoinElement("appointment",
121 //            "pl.matsuo.clinic.model.medical.appointment.Appointment", cond("appointment.id = keyValuePrint.idEntity")));
122     // Przypadek KP
123     List<KeyValuePrint> prints2 = findPrints(params, "keyValuePrint.fields['buyer.id']", isNull("keyValuePrint.idEntity"));
124     // prints connected directly to somebody
125     List<KeyValuePrint> prints = findPrints(params, "keyValuePrint.idEntity");
126 
127     Map<Integer, KeyValuePrint> printsMap = new HashMap<>();
128     asList(prints, prints2).forEach(collection ->
129         collection.forEach(print -> printsMap.put(print.getId(), print)));
130 
131     List<KeyValuePrint> result = new ArrayList<>(printsMap.values());
132     // reversed order!
133     Collections.sort(result, (a, b) -> b.getCreatedTime().compareTo(a.getCreatedTime()));
134 
135     if (params.getLimit() != null) {
136       result = result.subList(0, params.getLimit());
137     }
138 
139     return result;
140   }
141 
142 
143   public void generatePrint(String templateName, String fileName, Object dataModel,
144                             HttpServletResponse response) {
145     byte[] pdf = printsRendererService.generatePrint(templateName, dataModel);
146     response.setContentType("application/pdf");
147     response.setContentLength(pdf.length);
148     response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
149 
150     try {
151       write(pdf, response.getOutputStream());
152     } catch (IOException e) {
153       throw new RuntimeException(e);
154     }
155   }
156 
157 
158   /**
159    * Pobiera listę druków dla przekazanych identyfikatorów wizyt.
160    */
161   @RequestMapping(value = "/list/byIdEntities", method = GET, consumes = {APPLICATION_OCTET_STREAM_VALUE})
162   public List<KeyValuePrint> listByIdEntities(@RequestParam("ids") List<Integer> ids) {
163     return database.find(query(KeyValuePrint.class, in("idEntity", ids)).initializer(new PrintInitializer()));
164   }
165 
166 
167   @Autowired(required = false)
168   public void setReportServices(AbstractPrintService[] reportServices) {
169     reportServicesMap = new HashMap<>();
170     for (AbstractPrintService reportService : reportServices) {
171       reportServicesMap.put(resolveTypeArgument(reportService.getClass(), AbstractPrintService.class), reportService);
172     }
173   }
174 }
175