Source code: joelib/io/types/PDF.java
1 ///////////////////////////////////////////////////////////////////////////////
2 // Filename: $RCSfile: PDF.java,v $
3 // Purpose: Reader/Writer for Undefined files.
4 // Language: Java
5 // Compiler: JDK 1.4
6 // Authors: Joerg K. Wegner
7 // Version: $Revision: 1.5 $
8 // $Date: 2003/11/03 09:21:39 $
9 // $Author: wegner $
10 //
11 // Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
12 //
13 // This program is free software; you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation version 2 of the License.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License for more details.
21 ///////////////////////////////////////////////////////////////////////////////
22 package joelib.io.types;
23
24 import joelib.data.JOEDataType;
25 import joelib.data.JOEGenericData;
26 import joelib.data.JOEPairData;
27
28 import joelib.desc.DescResult;
29 import joelib.desc.DescriptorException;
30 import joelib.desc.DescriptorHelper;
31
32 import joelib.gui.render.Mol2Image;
33 import joelib.gui.render.RenderHelper;
34 import joelib.gui.render.Renderer2D;
35 import joelib.gui.render.Renderer2DModel;
36 import joelib.gui.render.RenderingAtoms;
37
38 import joelib.io.MoleculeFileType;
39 import joelib.io.MoleculeIOException;
40 import joelib.io.PropertyWriter;
41
42 import joelib.molecule.JOEMol;
43
44 import joelib.smarts.JOESmartsPattern;
45 import joelib.util.JOEHelper;
46
47 import joelib.util.iterator.GenericDataIterator;
48
49 import wsi.ra.tool.PropertyHolder;
50
51 import java.awt.BasicStroke;
52 import java.awt.Dimension;
53 import java.awt.Graphics2D;
54
55 import java.io.IOException;
56 import java.io.InputStream;
57 import java.io.OutputStream;
58
59 import java.util.Arrays;
60 import java.util.Vector;
61
62 import org.apache.log4j.Category;
63
64 import com.lowagie.text.Chunk;
65 import com.lowagie.text.Document;
66 import com.lowagie.text.DocumentException;
67 import com.lowagie.text.Font;
68 import com.lowagie.text.Image;
69 import com.lowagie.text.pdf.BaseFont;
70 import com.lowagie.text.pdf.PdfContentByte;
71 import com.lowagie.text.pdf.PdfTemplate;
72 import com.lowagie.text.pdf.PdfWriter;
73
74
75 /*==========================================================================*
76 * CLASS DECLARATION
77 *==========================================================================*/
78
79 /**
80 * Atom representation.
81 */
82 public class PDF implements MoleculeFileType, PropertyWriter
83 {
84 //~ Static fields/initializers /////////////////////////////////////////////
85
86 /*-------------------------------------------------------------------------*
87 * private static member variables
88 *-------------------------------------------------------------------------*/
89
90 /**
91 * Obtain a suitable logger.
92 */
93 private static Category logger = Category.getInstance("joelib.io.types.PDF");
94 private static final String description = new String(
95 "Portable Adobe Document Format (PDF) image");
96 private static final String[] extensions = new String[]{"pdf"};
97 private static final int DEFAULT_FONT_SIZE = 10;
98 private static final int DEFAULT_FONT_OFFSET = 2;
99 private static final int DEFAULT_BORDER = 20;
100 private static final int WRITE_MAX_CHARACTERS = 200;
101
102 //~ Instance fields ////////////////////////////////////////////////////////
103
104 private Document document = new Document();
105 private PdfWriter writer;
106 private boolean firstMoleculeWritten = false;
107 private int fontSize = DEFAULT_FONT_SIZE;
108 private int fontSizeDelta = DEFAULT_FONT_OFFSET;
109 private int pageBorder = DEFAULT_BORDER;
110
111 //~ Methods ////////////////////////////////////////////////////////////////
112
113 /**
114 * Description of the Method
115 *
116 * @exception IOException Description of the Exception
117 */
118 public void closeReader() throws IOException
119 {
120 }
121
122 /**
123 * Description of the Method
124 *
125 * @exception IOException Description of the Exception
126 */
127 public void closeWriter() throws IOException
128 {
129 document.close();
130 }
131
132 public void initReader(InputStream is) throws IOException
133 {
134 }
135
136 /**
137 * Description of the Method
138 *
139 * @param os Description of the Parameter
140 * @exception IOException Description of the Exception
141 */
142 public void initWriter(OutputStream os) throws IOException
143 {
144 fontSize = PropertyHolder.instance().getInt(this, "fontSize",
145 DEFAULT_FONT_SIZE);
146 fontSizeDelta = PropertyHolder.instance().getInt(this, "fontOffset",
147 DEFAULT_FONT_SIZE);
148 pageBorder = PropertyHolder.instance().getInt(this, "pageBorder",
149 DEFAULT_FONT_SIZE);
150
151 try
152 {
153 writer = PdfWriter.getInstance(document, os);
154 }
155 catch (DocumentException e)
156 {
157 throw new IOException(e.getMessage());
158 }
159 }
160
161 /**
162 * Description of the Method
163 *
164 * @return Description of the Return Value
165 */
166 public String inputDescription()
167 {
168 return null;
169 }
170
171 /**
172 * Description of the Method
173 *
174 * @return Description of the Return Value
175 */
176 public String[] inputFileExtensions()
177 {
178 return null;
179 }
180
181 public String outputDescription()
182 {
183 return description;
184 }
185
186 public String[] outputFileExtensions()
187 {
188 return extensions;
189 }
190
191 /**
192 * Reads an molecule entry as (unparsed) <tt>String</tt> representation.
193 *
194 * @return <tt>null</tt> if the reader contains no more
195 * relevant data. Otherwise the <tt>String</tt> representation of the
196 * whole molecule entry is returned.
197 * @exception IOException typical IOException
198 */
199 public String read() throws IOException
200 {
201 logger.error(
202 "Reading PDF data as String representation is not implemented yet !!!");
203
204 return null;
205 }
206
207 /**
208 * Description of the Method
209 *
210 * @param mol Description of the Parameter
211 * @return Description of the Return Value
212 * @exception IOException Description of the Exception
213 * @exception MoleculeIOException Description of the Exception
214 */
215 public synchronized boolean read(JOEMol mol)
216 throws IOException, MoleculeIOException
217 {
218 return read(mol, null);
219 }
220
221 /**
222 * Loads an molecule in MDL SD-MOL format and sets the title. If <tt>title
223 * </tt> is <tt>null</tt> the title line in the molecule file is used.
224 *
225 * @param mol Description of the Parameter
226 * @param title Description of the Parameter
227 * @return Description of the Return Value
228 * @exception IOException Description of the Exception
229 * @exception MoleculeIOException Description of the Exception
230 */
231 public synchronized boolean read(JOEMol mol, String title)
232 throws IOException, MoleculeIOException
233 {
234 return (true);
235 }
236
237 public boolean readable()
238 {
239 return false;
240 }
241
242 /**
243 * Description of the Method
244 *
245 * @return Description of the Return Value
246 * @exception IOException Description of the Exception
247 */
248 public boolean skipReaderEntry() throws IOException
249 {
250 return true;
251 }
252
253 /**
254 * Description of the Method
255 *
256 * @param mol Description of the Parameter
257 * @return Description of the Return Value
258 * @exception IOException Description of the Exception
259 */
260 public boolean write(JOEMol mol) throws IOException
261 {
262 return write(mol, null);
263 }
264
265 public boolean write(JOESmartsPattern smarts,JOEMol mol) throws IOException
266 {
267 return write(mol, null, true, null, smarts);
268 }
269
270 /**
271 * Description of the Method
272 *
273 * @param mol Description of the Parameter
274 * @param title Description of the Parameter
275 * @return Description of the Return Value
276 * @exception IOException Description of the Exception
277 */
278 public boolean write(JOEMol mol, String title) throws IOException
279 {
280 return write(mol, title, true, null);
281 }
282
283 /**
284 * Writes a molecule with his <tt>JOEPairData</tt> .
285 *
286 * @param mol the molecule with additional data
287 * @param title the molecule title or <tt>null</tt> if the title
288 * from the molecule should be used
289 * @param writePairData if <tt>true</tt> then the additional molecule data
290 * is written
291 * @param attribs2write Description of the Parameter
292 * @return <tt>true</tt> if the molecule and the data has
293 * been succesfully written.
294 * @exception IOException Description of the Exception
295 */
296 public boolean write(JOEMol mol, String title, boolean writePairData,
297 Vector attribs2write) throws IOException
298 {
299 return write(mol, title, writePairData, attribs2write, null);
300 }
301
302 /**
303 * Writes a molecule with his <tt>JOEPairData</tt> .
304 *
305 * @param mol the molecule with additional data
306 * @param title the molecule title or <tt>null</tt> if the title
307 * from the molecule should be used
308 * @param writePairData if <tt>true</tt> then the additional molecule data
309 * is written
310 * @param attribs2write Description of the Parameter
311 * @return <tt>true</tt> if the molecule and the data has
312 * been succesfully written.
313 * @exception IOException Description of the Exception
314 */
315 public boolean write(JOEMol mol, String title, boolean writePairData,
316 Vector attribs2write, JOESmartsPattern smarts) throws IOException
317 {
318 if (firstMoleculeWritten == false)
319 {
320 document.open();
321 firstMoleculeWritten = true;
322 }
323
324 Dimension d = new Dimension(Mol2Image.instance().getDefaultWidth(),
325 Mol2Image.instance().getDefaultHeight());
326 RenderingAtoms container = new RenderingAtoms();
327 container.add(mol);
328
329 RenderHelper.translateAllPositive(container);
330 RenderHelper.scaleMolecule(container, d, 0.8);
331 RenderHelper.center(container, d);
332
333 Renderer2D renderer = new Renderer2D();
334
335 BaseFont helvetica = null;
336
337 try
338 {
339 helvetica = BaseFont.createFont("Helvetica", BaseFont.CP1252,
340 BaseFont.NOT_EMBEDDED);
341 }
342 catch (DocumentException e1)
343 {
344 // TODO Auto-generated catch block
345 e1.printStackTrace();
346 }
347
348 int w = d.width;
349 int h = d.height;
350 PdfContentByte cb = writer.getDirectContent();
351 PdfTemplate tp = cb.createTemplate(w, h);
352 Graphics2D g2 = tp.createGraphics(w, h);
353 g2.setStroke(new BasicStroke(0.1f));
354 tp.setWidth(w);
355 tp.setHeight(h);
356
357 g2.setColor(renderer.getRenderer2DModel().getBackColor());
358 g2.fillRect(0, 0, d.width, d.height);
359 if(smarts!=null)renderer.selectSMARTSPatterns(container,smarts);
360 renderer.paintMolecule(container, g2);
361
362 g2.dispose();
363
364 ////cb.addTemplate(tp, 72, 720 - h);
365 //cb.addTemplate(tp, 12, 720 - h);
366 cb.addTemplate(tp, 0, document.getPageSize().height() - h);
367
368 // Mol2Image.instance().mol2image(mol);
369 BaseFont bf = null;
370
371 try
372 {
373 bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252,
374 BaseFont.NOT_EMBEDDED);
375 }
376 catch (DocumentException e2)
377 {
378 // TODO Auto-generated catch block
379 e2.printStackTrace();
380 }
381
382 String string = "";
383
384 //float myBorder = DEFAULT_BORDER;
385 //float fontSize = 10;
386 //float fontSizeDelta = DEFAULT_FONT_OFFSET;
387 float hpos;
388
389 if (writePairData)
390 {
391 JOEGenericData genericData;
392 JOEPairData pairData;
393 GenericDataIterator gdit = mol.genericDataIterator();
394 int index = 0;
395 boolean firstPageWritten = false;
396
397 Vector attributesV;
398
399 if (attribs2write == null)
400 {
401 // write all descriptors
402 attributesV = new Vector();
403
404 DescResult tmpPropResult;
405
406 while (gdit.hasNext())
407 {
408 genericData = gdit.nextGenericData();
409
410 if (genericData.getDataType() == JOEDataType.JOE_PAIR_DATA)
411 {
412 pairData = (JOEPairData) genericData;
413
414 /*
415 // DOES NOT WORK CORRECTLY !!!
416 try
417 {
418 tmpPropResult = DescriptorHelper.instance()
419 .descFromMol(mol,
420 pairData.getAttribute());
421 }
422 catch (DescriptorException ex)
423 {
424 // should never occur here
425 continue;
426 }*/
427 // do not store atom and bond properties
428 //System.out.println(tmpPropResult.getClass().getName());
429 //if (!JOEHelper.hasInterface(tmpPropResult,
430 // "AtomProperties") &&
431 // !JOEHelper.hasInterface(tmpPropResult,
432 // "BondProperties"))
433 //{
434 attributesV.add(pairData.getAttribute());
435
436 //}
437 }
438 }
439 }
440 else
441 {
442 attributesV = attribs2write;
443 }
444
445 // sort descriptors by attribute name
446 String[] attributes = new String[attributesV.size()];
447
448 for (int i = 0; i < attributesV.size(); i++)
449 {
450 attributes[i] = (String) attributesV.get(i);
451 }
452
453 Arrays.sort(attributes);
454
455 // write them
456 for (int i = 0; i < attributes.length; i++)
457 {
458 genericData = mol.getData(attributes[i]);
459
460 if (genericData.getDataType() == JOEDataType.JOE_PAIR_DATA)
461 {
462 pairData = (JOEPairData) genericData;
463 string = pairData.getAttribute() + " = " +
464 pairData.toString();
465
466 // reduce too complex data
467 string = string.replace('\n', ' ');
468 string = string.substring(0,
469 Math.min(string.length(), WRITE_MAX_CHARACTERS));
470
471 tp = cb.createTemplate(document.getPageSize().width() -
472 pageBorder, fontSize + fontSizeDelta);
473 tp.setFontAndSize(bf, fontSize);
474 tp.beginText();
475 tp.setTextMatrix(0, fontSizeDelta);
476 tp.showText(string);
477 tp.endText();
478 cb.setLineWidth(1f);
479 tp.moveTo(0, 0);
480 tp.lineTo(document.getPageSize().width() -
481 (2 * pageBorder), 0);
482 tp.stroke();
483
484 if (firstPageWritten)
485 {
486 hpos = document.getPageSize().height() -
487 ((fontSize + fontSizeDelta) * (index + 1));
488 }
489 else
490 {
491 hpos = document.getPageSize().height() - h -
492 ((fontSize + fontSizeDelta) * (index + 1));
493 }
494
495 if (hpos < pageBorder)
496 {
497 index = 1;
498 firstPageWritten = true;
499 hpos = document.getPageSize().height() -
500 ((fontSize + fontSizeDelta) * (index + 1));
501
502 try
503 {
504 document.newPage();
505 }
506 catch (DocumentException e)
507 {
508 // TODO Auto-generated catch block
509 e.printStackTrace();
510 }
511 }
512
513 cb.addTemplate(tp, pageBorder, hpos);
514 }
515
516 index++;
517 }
518
519 try
520 {
521 document.newPage();
522 }
523 catch (DocumentException e)
524 {
525 // TODO Auto-generated catch block
526 e.printStackTrace();
527 }
528 }
529
530 return (true);
531 }
532
533 /**
534 * Description of the Method
535 *
536 * @return Description of the Return Value
537 */
538 public boolean writeable()
539 {
540 return true;
541 }
542 }
543 ///////////////////////////////////////////////////////////////////////////////
544 // END OF FILE.
545 ///////////////////////////////////////////////////////////////////////////////