1 51 package org.apache.fop.apps; 52 53 import java.io.OutputStream ; 54 import java.io.IOException ; 55 import java.util.ArrayList ; 56 import java.util.Iterator ; 57 58 import org.xml.sax.SAXException ; 59 60 import org.apache.fop.datatypes.IDReferences; 61 import org.apache.fop.extensions.ExtensionObj; 62 import org.apache.fop.fo.flow.Marker; 63 import org.apache.fop.fo.pagination.PageSequence; 64 import org.apache.fop.layout.AreaTree; 65 import org.apache.fop.layout.FontInfo; 66 import org.apache.fop.layout.Page; 67 import org.apache.fop.render.Renderer; 68 69 import org.apache.avalon.framework.logger.Logger; 70 71 82 public class StreamRenderer { 83 private static final boolean MEM_PROFILE_WITH_GC = false; 84 85 88 private Runtime runtime = Runtime.getRuntime(); 89 90 93 int pageCount = 0; 94 95 99 private long initialMemory; 100 101 104 private long startTime; 105 106 112 private OutputStream outputStream; 113 114 117 private Renderer renderer; 118 119 122 private FormattingResults results = new FormattingResults(); 123 124 127 private FontInfo fontInfo = new FontInfo(); 128 129 132 private ArrayList renderQueue = new ArrayList (); 133 134 139 private IDReferences idReferences = new IDReferences(); 140 141 144 private ArrayList extensions = new ArrayList (); 145 146 149 private ArrayList documentMarkers; 150 private ArrayList currentPageSequenceMarkers; 151 private PageSequence currentPageSequence; 152 153 private Logger log; 154 155 public StreamRenderer(OutputStream outputStream, Renderer renderer) { 156 this.outputStream = outputStream; 157 this.renderer = renderer; 158 } 159 160 public void setLogger(Logger logger) { 161 log = logger; 162 } 163 164 public IDReferences getIDReferences() { 165 return idReferences; 166 } 167 168 public FormattingResults getResults() { 169 return this.results; 170 } 171 172 public void addExtension(ExtensionObj ext) { 173 extensions.add(ext); 174 } 175 176 public void startRenderer() 177 throws SAXException { 178 pageCount = 0; 179 180 if (MEM_PROFILE_WITH_GC) 181 System.gc(); 183 initialMemory = runtime.totalMemory() - runtime.freeMemory(); 184 startTime = System.currentTimeMillis(); 185 186 try { 187 renderer.setupFontInfo(fontInfo); 188 renderer.startRenderer(outputStream); 189 } catch (FOPException fe) { 190 throw new SAXException (fe); 191 } catch (IOException e) { 192 throw new SAXException (e); 193 } 194 } 195 196 public void stopRenderer() 197 throws SAXException { 198 202 try { 203 processQueue(true); 204 renderer.stopRenderer(outputStream); 205 } catch (FOPException e) { 206 throw new SAXException (e); 207 } 208 catch (IOException e) { 209 throw new SAXException (e); 210 } 211 212 if (MEM_PROFILE_WITH_GC) 213 System.gc(); 215 long memoryNow = runtime.totalMemory() - runtime.freeMemory(); 216 long memoryUsed = (memoryNow - initialMemory) / 1024L; 217 218 log.debug("Initial heap size: " + (initialMemory/1024L) + "Kb"); 219 log.debug("Current heap size: " + (memoryNow/1024L) + "Kb"); 220 log.debug("Total memory used: " + memoryUsed + "Kb"); 221 222 if (!MEM_PROFILE_WITH_GC) { 223 log.debug(" Memory use is indicative; no GC was performed"); 224 log.debug(" These figures should not be used comparatively"); 225 } 226 227 long timeUsed = System.currentTimeMillis() - startTime; 228 229 log.debug("Total time used: " + timeUsed + "ms"); 230 log.debug("Pages rendered: " + pageCount); 231 if (pageCount != 0) { 232 log.debug("Avg render time: " + (timeUsed / pageCount) + "ms/page"); 233 } 234 } 235 236 247 public void render(PageSequence pageSequence) 248 throws SAXException { 249 AreaTree a = new AreaTree(this); 250 a.setFontInfo(fontInfo); 251 252 for(int i = 0; i < extensions.size(); i++ ) { 253 ExtensionObj ext = (ExtensionObj)extensions.get(i); 254 try { 255 ext.format(a); 256 } catch (FOPException fope) { 257 throw new SAXException (fope); 258 } 259 } 260 261 try { 262 pageSequence.format(a); 263 } catch (FOPException e) { 264 throw new SAXException (e); 265 } 266 this.results.haveFormattedPageSequence(pageSequence); 267 log.debug("Last page-sequence produced "+pageSequence.getPageCount()+" pages."); 268 } 269 270 public synchronized void queuePage(Page page) 271 throws FOPException, IOException { 272 273 PageSequence pageSequence = page.getPageSequence(); 275 if (pageSequence != currentPageSequence) { 276 currentPageSequence = pageSequence; 277 currentPageSequenceMarkers = null; 278 } 279 ArrayList markers = page.getMarkers(); 280 if (markers != null) { 281 if (documentMarkers == null) { 282 documentMarkers = new ArrayList (); 283 } 284 if (currentPageSequenceMarkers == null) { 285 currentPageSequenceMarkers = new ArrayList (); 286 } 287 for (int i=0;i<markers.size();i++) { 288 Marker marker = (Marker)markers.get(i); 289 marker.releaseRegistryArea(); 290 currentPageSequenceMarkers.add(marker); 291 documentMarkers.add(marker); 292 } 293 } 294 295 301 if ((renderQueue.size() == 0) && idReferences.isEveryIdValid()) { 302 renderer.render(page, outputStream); 303 } else { 304 RenderQueueEntry entry = new RenderQueueEntry(page); 305 renderQueue.add(entry); 306 311 processQueue(false); 312 } 313 pageCount++; 314 } 315 316 321 private synchronized void processQueue(boolean force) 322 throws FOPException, IOException { 323 while (renderQueue.size() > 0) { 324 RenderQueueEntry entry = (RenderQueueEntry) renderQueue.get(0); 325 if ((!force) && (!entry.isResolved())) 326 break; 327 328 renderer.render(entry.getPage(), outputStream); 329 renderQueue.remove(0); 330 } 331 } 332 333 338 class RenderQueueEntry { 339 342 private Page page; 343 344 347 private ArrayList unresolvedIdReferences = new ArrayList (); 348 349 public RenderQueueEntry(Page page) { 350 this.page = page; 351 352 Iterator e = idReferences.getInvalidElements(); 353 while (e.hasNext()) 354 unresolvedIdReferences.add(e.next()); 355 } 356 357 public Page getPage() { 358 return page; 359 } 360 361 365 public boolean isResolved() { 366 if ((unresolvedIdReferences.size() == 0) || idReferences.isEveryIdValid()) 367 return true; 368 369 for (int i = 0; i< unresolvedIdReferences.size(); i++) 373 if (!idReferences.doesIDExist((String )unresolvedIdReferences.get(i))) 374 return false; 375 376 unresolvedIdReferences.clear(); 377 return true; 378 } 379 } 380 381 public ArrayList getDocumentMarkers() { 383 return documentMarkers; 384 } 385 386 public PageSequence getCurrentPageSequence() { 388 return currentPageSequence; 389 } 390 391 public ArrayList getCurrentPageSequenceMarkers() { 393 return currentPageSequenceMarkers; 394 } 395 } 396 | Popular Tags |