View Javadoc
1   /*
2    * #%L
3    * JRst :: Api
4    * %%
5    * Copyright (C) 2004 - 2012 CodeLutin
6    * %%
7    * This program is free software: you can redistribute it and/or modify
8    * it under the terms of the GNU Lesser General Public License as 
9    * published by the Free Software Foundation, either version 3 of the 
10   * License, or (at your option) any later version.
11   * 
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Lesser Public License for more details.
16   * 
17   * You should have received a copy of the GNU General Lesser Public 
18   * License along with this program.  If not, see
19   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
20   * #L%
21   */
22  package org.nuiton.jrst;
23  
24  import java.io.File;
25  import java.net.MalformedURLException;
26  import java.net.URI;
27  import java.net.URL;
28  
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  import org.xhtmlrenderer.extend.UserAgentCallback;
32  import org.xhtmlrenderer.layout.SharedContext;
33  import org.xhtmlrenderer.pdf.ITextFSImage;
34  import org.xhtmlrenderer.resource.CSSResource;
35  import org.xhtmlrenderer.resource.ImageResource;
36  import org.xhtmlrenderer.resource.XMLResource;
37  import org.xhtmlrenderer.swing.NaiveUserAgent;
38  
39  import com.itextpdf.text.Image;
40  
41  /**
42   * Class used to resolv images path for JRST documents for itext PDF generation
43   *
44   * @author jerome pages <jpages@codelutin.com>
45   * @since 1.6
46   */
47  public class JRSTUserAgent implements UserAgentCallback {
48  
49      /** to use log facility, just put in your code: log.info("..."); */
50      protected static Log log = LogFactory.getLog(JRSTUserAgent.class);
51  
52      protected NaiveUserAgent delegate;
53  
54      // Resources path
55      protected String path;
56  
57      private SharedContext sharedContext;
58  
59      public JRSTUserAgent(String path) {
60          this.path = path;
61          this.delegate = new NaiveUserAgent();
62      }
63  
64  
65      @Override
66      public CSSResource getCSSResource(String uri) {
67          return delegate.getCSSResource(uri);
68      }
69  
70      @Override
71      public ImageResource getImageResource(String uri) {
72          uri = resolveURI(uri);
73          return createImageResource(uri);
74      }
75  
76      protected ImageResource createImageResource(String uri) {
77          ImageResource imageResource = null;
78  
79          try {
80              // Gets the image with its url
81              URL source = new URI(uri).toURL();
82              Image image = Image.getInstance(source);
83  
84              // Sets the scale of the image
85              scaleToOutputResolution(image);
86  
87              // Creation of the image for IText
88              ITextFSImage iTextFSImage = new ITextFSImage(image);
89              imageResource = new ImageResource(uri, iTextFSImage);
90          } catch (Exception eee) {
91              log.error("Failed to create image resource", eee);
92          }
93  
94          return imageResource;
95      }
96  
97      @Override
98      public XMLResource getXMLResource(String uri) {
99          return delegate.getXMLResource(uri);
100     }
101 
102     @Override
103     public byte[] getBinaryResource(String uri) {
104         return delegate.getBinaryResource(uri);
105     }
106 
107     @Override
108     public boolean isVisited(String uri) {
109         return delegate.isVisited(uri);
110     }
111 
112     @Override
113     public void setBaseURL(String url) {
114         delegate.setBaseURL(url);
115     }
116 
117     @Override
118     public String getBaseURL() {
119         return delegate.getBaseURL();
120     }
121 
122     public String resolveURI(String uri) {
123         if (uri == null) return null;
124         String ret = null;
125         // If path is null, we try to set the baseURL with the uri, or if it doesn't work, with the current path
126         if (path == null) {
127             try {
128                 URL result = new URL(uri);
129                 setBaseURL(result.toExternalForm());
130             } catch (MalformedURLException e) {
131                 try {
132                     // Sets the current file for the base url
133                     setBaseURL(new File(".").toURI().toURL().toExternalForm());
134                 } catch (Exception e1) {
135                     log.info("The default NaiveUserAgent doesn't know how to resolve the base URL for " + uri);
136                     return null;
137                 }
138             }
139         }
140 
141         try {
142             // If the URI is absolute, we return the string of the url
143             return new URL(uri).toString();
144         } catch (MalformedURLException e) {
145             // If we are here, the uri is relative so we must build the absolute link with the path
146             try {
147                 File filePath = new File(path);
148                 URI resourcePath = filePath.toURI();
149                 resourcePath = resourcePath.resolve(uri);
150 
151                 // Builds the full resource path
152                 URL result = resourcePath.toURL();
153                 ret = result.toURI().toString();
154             } catch (Exception e1) {
155                 log.error("The default NaiveUserAgent cannot resolve the URL " + uri + " with base URL " + path, e1);
156             }
157         }
158         return ret;
159     }
160 
161     private void scaleToOutputResolution(Image image) {
162         float factor = this.sharedContext.getDotsPerPixel();
163         image.scaleAbsolute(image.getPlainWidth() * factor, image.getPlainHeight() * factor);
164     }
165 
166     public SharedContext getSharedContext() {
167         return this.sharedContext;
168     }
169 
170     public void setSharedContext(SharedContext sharedContext) {
171         this.sharedContext = sharedContext;
172     }
173 }