1 package org.splat.service;
3 import java.awt.Graphics2D;
5 import java.io.FileNotFoundException;
6 import java.io.FileOutputStream;
7 import java.util.ArrayList;
8 import java.util.HashMap;
9 import java.util.Iterator;
10 import java.util.List;
12 import java.util.Scanner;
14 import org.hibernate.Hibernate;
15 import org.hibernate.criterion.Restrictions;
16 import org.hibernate.proxy.HibernateProxy;
17 import org.jfree.chart.ChartFactory;
18 import org.jfree.chart.JFreeChart;
19 import org.jfree.chart.plot.PlotOrientation;
20 import org.jfree.data.xy.XYSeries;
21 import org.jfree.data.xy.XYSeriesCollection;
22 import org.splat.common.properties.MessageKeyEnum;
23 import org.splat.dal.bo.kernel.User;
24 import org.splat.dal.bo.som.ProjectElement;
25 import org.splat.dal.bo.som.Publication;
26 import org.splat.dal.bo.som.Scenario;
27 import org.splat.dal.bo.som.Study;
28 import org.splat.dal.bo.som.Visibility;
29 import org.splat.dal.dao.som.PublicationDAO;
30 import org.splat.exception.IncompatibleDataException;
31 import org.splat.kernel.MismatchException;
32 import org.splat.log.AppLogger;
33 import org.splat.service.dto.DocToCompareDTO;
34 import org.splat.service.dto.DocumentDTO;
35 import org.splat.service.dto.Proxy;
36 import org.splat.service.dto.StudyFacadeDTO;
37 import org.splat.service.dto.StudySearchFilterDTO;
38 import org.splat.service.technical.ProjectSettingsService;
39 import org.splat.service.technical.ProjectSettingsService.Step;
40 import org.springframework.transaction.annotation.Transactional;
42 import com.lowagie.text.Document;
43 import com.lowagie.text.DocumentException;
44 import com.lowagie.text.Rectangle;
45 import com.lowagie.text.pdf.DefaultFontMapper;
46 import com.lowagie.text.pdf.PdfContentByte;
47 import com.lowagie.text.pdf.PdfTemplate;
48 import com.lowagie.text.pdf.PdfWriter;
50 public class StudyComparisonServiceImpl implements StudyComparisonService {
53 * logger for the service.
55 public final static AppLogger LOG = AppLogger
56 .getLogger(StudyServiceImpl.class);
59 * Injected project service.
61 private ProjectSettingsService _projectSettings;
64 * Injected publication DAO.
66 private PublicationDAO _publicationDAO;
69 * Injected user service.
71 private UserService _userService;
74 * Injected search service.
76 private SearchService _searchService;
81 * @see org.splat.service.StudyComparisonService#getComparableStudies(long)
83 @Transactional(readOnly = true)
84 public List<StudyFacadeDTO> getComparableStudies(final long userId)
85 throws MismatchException {
86 // retrieve the number of the "Analyze the results" step
87 List<Step> allSteps = _projectSettings.getAllSteps();
88 Step theAnalyzeStep = null;
89 for (Step step : allSteps) {
90 if (step.getKey().equals("postprocessing")) {
91 theAnalyzeStep = step;
94 if (theAnalyzeStep == null) { // TODO: throw some other exception
95 throw new MismatchException(
96 "no step with key 'postprocessing' found."
97 + "Probably, customization settings have been changed.");
100 List<Publication> publications = _publicationDAO.getFilteredList(
101 "mydoc", Restrictions.eq("step", Integer.valueOf(theAnalyzeStep
104 // split retrieved publications into groups by studies and scenarios
105 Map<Study, List<ProjectElement>> studyMap = new HashMap<Study, List<ProjectElement>>();
106 Map<ProjectElement, List<Publication>> scenarioMap = new HashMap<ProjectElement, List<Publication>>();
108 // Get visible studies
109 StudySearchFilterDTO filter = new StudySearchFilterDTO();
110 User user = (_userService.selectUser(userId));
112 filter.setConnectedUserId(userId);
114 List<Proxy> vizibleStudies = _searchService.selectStudiesWhere(filter);
116 for (Publication publication : publications) {
117 // filter out publications corresponding to a document of given step which is not a _result_ document
118 if (!publication.value().getType().isResultOf(theAnalyzeStep)
119 || !"srd".equals(publication.getSourceFile().getFormat())) {
123 // check the study visibility to the user
124 if (!isStaffedBy(publication.getOwnerStudy(), _userService
126 && Visibility.PUBLIC.equals(publication.getOwnerStudy()
131 Study study = publication.getOwnerStudy();
132 ProjectElement scenario = publication.getOwner();
134 // check the study visibility to the user
135 boolean contains = false;
136 for(Proxy aStudy : vizibleStudies) {
137 if(aStudy.getIndex().longValue() == study.getIndex()) {
141 if(!contains && !Visibility.PUBLIC.equals(publication.getOwnerStudy().getVisibility())) {
145 Hibernate.initialize(scenario);
146 if (scenario instanceof HibernateProxy) {
147 scenario = (ProjectElement) ((HibernateProxy) scenario)
148 .getHibernateLazyInitializer().getImplementation();
151 if (!(scenario instanceof Scenario)) {
152 throw new MismatchException(
153 "publications from postprocessing step are supposed to have owner scenario");
156 if (!studyMap.containsKey(study)) {
157 studyMap.put(study, new ArrayList<ProjectElement>());
160 if (!studyMap.get(study).contains(scenario)) {
161 studyMap.get(study).add(scenario);
164 if (!scenarioMap.containsKey(scenario)) {
165 scenarioMap.put(scenario, new ArrayList<Publication>());
167 scenarioMap.get(scenario).add(publication);
170 // Create the result DTOs
171 List<StudyFacadeDTO> result = new ArrayList<StudyFacadeDTO>();
172 for (Study study : studyMap.keySet()) {
174 StudyFacadeDTO studyDTO = new StudyFacadeDTO();
175 studyDTO.setName(study.getTitle());
176 studyDTO.setScenarios(new ArrayList<StudyFacadeDTO.ScenarioDTO>());
177 result.add(studyDTO);
179 for (ProjectElement scenario : studyMap.get(study)) {
181 StudyFacadeDTO.ScenarioDTO scenarioDTO = new StudyFacadeDTO.ScenarioDTO();
182 scenarioDTO.setName(scenario.getTitle());
183 scenarioDTO.setDocs(new ArrayList<DocumentDTO>());
184 studyDTO.getScenarios().add(scenarioDTO);
186 for (Publication publication : scenarioMap.get(scenario)) {
188 DocumentDTO documentDTO = new DocumentDTO();
189 documentDTO.setId(publication.getIndex());
190 documentDTO.setTitle(publication.value().getTitle());
192 scenarioDTO.getDocs().add(documentDTO);
201 * @see org.splat.service.StudyComparisonService#compare(java.util.List, java.lang.String)
204 public String compare(final List<DocToCompareDTO> docsList,
205 final String userName) throws IncompatibleDataException {
207 String axis1Name = "";
208 String axis2Name = "";
209 String chartTitle = "";
210 String resultPath = "";
212 XYSeriesCollection dataset = new XYSeriesCollection();
214 Iterator<DocToCompareDTO> docListIter = docsList.iterator();
216 for (; docListIter.hasNext();) {
218 DocToCompareDTO docDTO = docListIter.next();
219 String pathToFile = docDTO.getPathToFile();
220 File compDocFile = new File(pathToFile);
222 resultPath = pathToFile.substring(0, pathToFile.indexOf("vault"))
223 + "downloads" + File.separator + userName + File.separator
224 + "ComparisonResult.pdf";
226 XYSeries series = new XYSeries("Study: " + docDTO.getStudyTitle()
227 + " Scenario: " + docDTO.getScenarioTitle() + " Document: "
228 + docDTO.getDocumentTitle());
230 // read the file and get points information.
232 Scanner input = new Scanner(compDocFile);
234 // get the title of the chart.
235 if (input.hasNext()) {
236 chartTitle = input.nextLine();
239 // get the name of the axis.
240 if (input.hasNext()) {
241 String[] tokens = input.nextLine().split(",");
243 if (tokens.length < 2) {
244 throw new IncompatibleDataException(
245 MessageKeyEnum.IDT_000001.toString());
248 if ("".equals(axis1Name)) {
249 axis1Name = tokens[0];
250 } else if (!axis1Name.equals(tokens[0])) {
251 LOG.debug("Axis must be the same for all documents");
252 throw new IncompatibleDataException(
253 MessageKeyEnum.IDT_000001.toString());
256 if ("".equals(axis2Name)) {
257 axis2Name = tokens[1];
258 } else if (!axis2Name.equals(tokens[1])) {
259 LOG.debug("Axis must be the same for all documents");
260 throw new IncompatibleDataException(
261 MessageKeyEnum.IDT_000001.toString());
265 // Get the XY points series.
266 while (input.hasNext()) {
268 String currentString = input.nextLine();
270 if (!("".equals(currentString))) {
271 String[] tokens = currentString.split(" ");
272 series.add(Double.valueOf(tokens[0]), Double
273 .valueOf(tokens[1]));
278 dataset.addSeries(series);
280 } catch (FileNotFoundException e) {
281 LOG.error("Sorry, the file is not found.", e);
285 JFreeChart chart = ChartFactory.createXYLineChart(chartTitle, // Title
286 axis1Name, // x-axis Label
287 axis2Name, // y-axis Label
289 PlotOrientation.VERTICAL, // Plot Orientation
291 true, // Use tooltips
292 false // Configure chart to generate URLs?
295 // export to PDF - file.
298 Rectangle pagesize = new Rectangle(x, y);
299 Document document = new Document(pagesize, 50, 50, 50, 50);
302 File resFile = new File(resultPath);
303 File resFolder = new File(resultPath.substring(0, resultPath
304 .lastIndexOf(File.separator)));
306 writer = PdfWriter.getInstance(document, new FileOutputStream(
310 PdfContentByte cb = writer.getDirectContent();
311 PdfTemplate tp = cb.createTemplate(x, y);
312 Graphics2D g2 = tp.createGraphics(x, y, new DefaultFontMapper());
313 chart.draw(g2, new java.awt.Rectangle(x, y));
315 cb.addTemplate(tp, 0, 0);
318 } catch (FileNotFoundException e) {
319 LOG.error("Sorry, the file is not found.", e);
320 } catch (DocumentException e) {
321 LOG.error("Sorry, the DocumentException is thrown.", e);
329 * Get the projectSettings.
330 * @return the projectSettings
332 public ProjectSettingsService getProjectSettings() {
333 return _projectSettings;
338 * Set the projectSettings.
339 * @param projectSettings the projectSettings to set
341 public void setProjectSettings(final ProjectSettingsService projectSettings) {
342 _projectSettings = projectSettings;
347 * Get the publicationDAO.
348 * @return the publicationDAO
350 public PublicationDAO getPublicationDAO() {
351 return _publicationDAO;
356 * Set the publicationDAO.
357 * @param publicationDAO the publicationDAO to set
359 public void setPublicationDAO(final PublicationDAO publicationDAO) {
360 _publicationDAO = publicationDAO;
365 * Get the userService.
366 * @return the userService
368 public UserService getUserService() {
374 * Set the userService.
375 * @param userService the userService to set
377 public void setUserService(final UserService userService) {
378 _userService = userService;
383 * Get the searchService.
384 * @return the searchService
386 public SearchService getSearchService() {
387 return _searchService;
392 * Set the searchService.
393 * @param searchService the searchService to set
395 public void setSearchService(final SearchService searchService) {
396 _searchService = searchService;