PageRenderTime 86ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/components/forks/poi/src/loci/poi/hssf/eventusermodel/HSSFEventFactory.java

http://github.com/openmicroscopy/bioformats
Java | 259 lines | 106 code | 30 blank | 123 comment | 28 complexity | 880394f1b0f8ed8b4183af136268bc56 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, Apache-2.0, BSD-2-Clause, MPL-2.0-no-copyleft-exception
  1. /*
  2. * #%L
  3. * Fork of Apache Jakarta POI.
  4. * %%
  5. * Copyright (C) 2008 - 2013 Open Microscopy Environment:
  6. * - Board of Regents of the University of Wisconsin-Madison
  7. * - Glencoe Software, Inc.
  8. * - University of Dundee
  9. * %%
  10. * Licensed under the Apache License, Version 2.0 (the "License");
  11. * you may not use this file except in compliance with the License.
  12. * You may obtain a copy of the License at
  13. *
  14. * http://www.apache.org/licenses/LICENSE-2.0
  15. *
  16. * Unless required by applicable law or agreed to in writing, software
  17. * distributed under the License is distributed on an "AS IS" BASIS,
  18. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19. * See the License for the specific language governing permissions and
  20. * limitations under the License.
  21. * #L%
  22. */
  23. /* ====================================================================
  24. Licensed to the Apache Software Foundation (ASF) under one or more
  25. contributor license agreements. See the NOTICE file distributed with
  26. this work for additional information regarding copyright ownership.
  27. The ASF licenses this file to You under the Apache License, Version 2.0
  28. (the "License"); you may not use this file except in compliance with
  29. the License. You may obtain a copy of the License at
  30. http://www.apache.org/licenses/LICENSE-2.0
  31. Unless required by applicable law or agreed to in writing, software
  32. distributed under the License is distributed on an "AS IS" BASIS,
  33. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  34. See the License for the specific language governing permissions and
  35. limitations under the License.
  36. ==================================================================== */
  37. package loci.poi.hssf.eventusermodel;
  38. import java.io.InputStream;
  39. import java.io.IOException;
  40. import loci.poi.hssf.eventusermodel.HSSFUserException;
  41. import loci.poi.hssf.record.*;
  42. import loci.poi.poifs.filesystem.POIFSFileSystem;
  43. /**
  44. * Low level event based HSSF reader. Pass either a DocumentInputStream to
  45. * process events along with a request object or pass a POIFS POIFSFileSystem to
  46. * processWorkbookEvents along with a request.
  47. *
  48. * This will cause your file to be processed a record at a time. Each record with
  49. * a static id matching one that you have registed in your HSSFRequest will be passed
  50. * to your associated HSSFListener.
  51. *
  52. * @see loci.poi.hssf.dev.EFHSSF
  53. *
  54. * @author Andrew C. Oliver (acoliver at apache dot org)
  55. * @author Carey Sublette (careysub@earthling.net)
  56. */
  57. public class HSSFEventFactory
  58. {
  59. /** Creates a new instance of HSSFEventFactory */
  60. public HSSFEventFactory()
  61. {
  62. }
  63. /**
  64. * Processes a file into essentially record events.
  65. *
  66. * @param req an Instance of HSSFRequest which has your registered listeners
  67. * @param fs a POIFS filesystem containing your workbook
  68. */
  69. public void processWorkbookEvents(HSSFRequest req, POIFSFileSystem fs)
  70. throws IOException
  71. {
  72. InputStream in = fs.createDocumentInputStream("Workbook");
  73. processEvents(req, in);
  74. }
  75. /**
  76. * Processes a file into essentially record events.
  77. *
  78. * @param req an Instance of HSSFRequest which has your registered listeners
  79. * @param fs a POIFS filesystem containing your workbook
  80. * @return numeric user-specified result code.
  81. */
  82. public short abortableProcessWorkbookEvents(HSSFRequest req, POIFSFileSystem fs)
  83. throws IOException, HSSFUserException
  84. {
  85. InputStream in = fs.createDocumentInputStream("Workbook");
  86. return abortableProcessEvents(req, in);
  87. }
  88. /**
  89. * Processes a DocumentInputStream into essentially Record events.
  90. *
  91. * If an <code>AbortableHSSFListener</code> causes a halt to processing during this call
  92. * the method will return just as with <code>abortableProcessEvents</code>, but no
  93. * user code or <code>HSSFUserException</code> will be passed back.
  94. *
  95. * @see loci.poi.poifs.filesystem.POIFSFileSystem#createDocumentInputStream(String)
  96. * @param req an Instance of HSSFRequest which has your registered listeners
  97. * @param in a DocumentInputStream obtained from POIFS's POIFSFileSystem object
  98. */
  99. public void processEvents(HSSFRequest req, InputStream in)
  100. throws IOException
  101. {
  102. try
  103. {
  104. genericProcessEvents(req, new RecordInputStream(in));
  105. }
  106. catch (HSSFUserException hue)
  107. {/*If an HSSFUserException user exception is thrown, ignore it.*/ }
  108. }
  109. /**
  110. * Processes a DocumentInputStream into essentially Record events.
  111. *
  112. * @see loci.poi.poifs.filesystem.POIFSFileSystem#createDocumentInputStream(String)
  113. * @param req an Instance of HSSFRequest which has your registered listeners
  114. * @param in a DocumentInputStream obtained from POIFS's POIFSFileSystem object
  115. * @return numeric user-specified result code.
  116. */
  117. public short abortableProcessEvents(HSSFRequest req, InputStream in)
  118. throws IOException, HSSFUserException
  119. {
  120. return genericProcessEvents(req, new RecordInputStream(in));
  121. }
  122. /**
  123. * Processes a DocumentInputStream into essentially Record events.
  124. *
  125. * @see loci.poi.poifs.filesystem.POIFSFileSystem#createDocumentInputStream(String)
  126. * @param req an Instance of HSSFRequest which has your registered listeners
  127. * @param in a DocumentInputStream obtained from POIFS's POIFSFileSystem object
  128. * @return numeric user-specified result code.
  129. */
  130. protected short genericProcessEvents(HSSFRequest req, RecordInputStream in)
  131. throws IOException, HSSFUserException
  132. {
  133. short userCode = 0;
  134. short sid = 0;
  135. process:
  136. {
  137. Record rec = null;
  138. Record lastRec = null;
  139. DrawingRecord lastDrawingRecord = new DrawingRecord();
  140. while (in.hasNextRecord())
  141. {
  142. in.nextRecord();
  143. sid = in.getSid();;
  144. //
  145. // for some reasons we have to make the workbook to be at least 4096 bytes
  146. // but if we have such workbook we fill the end of it with zeros (many zeros)
  147. //
  148. // it is not good:
  149. // if the length( all zero records ) % 4 = 1
  150. // e.g.: any zero record would be readed as 4 bytes at once ( 2 - id and 2 - size ).
  151. // And the last 1 byte will be readed WRONG ( the id must be 2 bytes )
  152. //
  153. // So we should better to check if the sid is zero and not to read more data
  154. // The zero sid shows us that rest of the stream data is a fake to make workbook
  155. // certain size
  156. //
  157. if ( sid == 0 )
  158. break;
  159. if ((rec != null) && (sid != ContinueRecord.sid))
  160. {
  161. userCode = req.processRecord(rec);
  162. if (userCode != 0) break process;
  163. }
  164. if (sid != ContinueRecord.sid)
  165. {
  166. //System.out.println("creating "+sid);
  167. Record[] recs = RecordFactory.createRecord(in);
  168. if (recs.length > 1)
  169. { // we know that the multiple
  170. for (int k = 0; k < (recs.length - 1); k++)
  171. { // record situations do not
  172. userCode = req.processRecord(
  173. recs[ k ]); // contain continue records
  174. if (userCode != 0) break process;
  175. }
  176. }
  177. rec = recs[ recs.length - 1 ]; // regardless we'll process
  178. // the last record as though
  179. // it might be continued
  180. // if there is only one
  181. // records, it will go here too.
  182. }
  183. else {
  184. // Normally, ContinueRecords are handled internally
  185. // However, in a few cases, there is a gap between a record at
  186. // its Continue, so we have to handle them specially
  187. // This logic is much like in RecordFactory.createRecords()
  188. Record[] recs = RecordFactory.createRecord(in);
  189. ContinueRecord crec = (ContinueRecord)recs[0];
  190. if((lastRec instanceof ObjRecord) || (lastRec instanceof TextObjectRecord)) {
  191. // You can have Obj records between a DrawingRecord
  192. // and its continue!
  193. lastDrawingRecord.processContinueRecord( crec.getData() );
  194. // Trigger them on the drawing record, now it's complete
  195. rec = lastDrawingRecord;
  196. }
  197. else if((lastRec instanceof DrawingGroupRecord)) {
  198. ((DrawingGroupRecord)lastRec).processContinueRecord(crec.getData());
  199. // Trigger them on the drawing record, now it's complete
  200. rec = lastRec;
  201. }
  202. else {
  203. if (rec instanceof UnknownRecord) {
  204. ;//silently skip records we don't know about
  205. } else {
  206. throw new RecordFormatException("Records should handle ContinueRecord internally. Should not see this exception");
  207. }
  208. }
  209. }
  210. // Update our tracking of the last record
  211. lastRec = rec;
  212. if(rec instanceof DrawingRecord) {
  213. lastDrawingRecord = (DrawingRecord)rec;
  214. }
  215. }
  216. if (rec != null)
  217. {
  218. userCode = req.processRecord(rec);
  219. if (userCode != 0) break process;
  220. }
  221. }
  222. return userCode;
  223. // Record[] retval = new Record[ records.size() ];
  224. // retval = ( Record [] ) records.toArray(retval);
  225. // return null;
  226. }
  227. }