From e0a3d2ae567866917371a42ee0e736541ee08f30 Mon Sep 17 00:00:00 2001 From: "Andrew C. Oliver" Date: Sat, 23 Nov 2002 18:58:18 +0000 Subject: [PATCH] model factory/event factory git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352920 13f79535-47bb-0310-9956-ffa450edef68 --- .../hssf/eventmodel/EventRecordFactory.java | 63 ++++++- .../poi/hssf/eventmodel/ModelFactory.java | 157 ++++++++++++++++++ .../hssf/eventmodel/ModelFactoryListener.java | 72 ++++++++ 3 files changed, 285 insertions(+), 7 deletions(-) create mode 100644 src/java/org/apache/poi/hssf/eventmodel/ModelFactory.java create mode 100644 src/java/org/apache/poi/hssf/eventmodel/ModelFactoryListener.java diff --git a/src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java b/src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java index 3d22913cf..182278eac 100644 --- a/src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java +++ b/src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java @@ -148,15 +148,19 @@ import org.apache.poi.util.LittleEndian; * accross the records. I throws the "lazily" one record behind * to ensure that ContinueRecords are processed first. * - * @author Andrew C. Oliver acoliver@apache.org + * @author Andrew C. Oliver (acoliver@apache.org) - probably to blame for the bugs (so yank his chain on the list) + * @author Marc Johnson (mjohnson at apache dot org) - methods taken from RecordFactory + * @author Glen Stampoultzis (glens at apache.org) - methods taken from RecordFactory */ public class EventRecordFactory { - private static int NUM_RECORDS = 10000; + + /** + * contains the classes for all the records we want to parse. + */ private static final Class[] records; static { - records = new Class[] { BOFRecord.class, InterfaceHdrRecord.class, MMSRecord.class, @@ -189,18 +193,43 @@ public class EventRecordFactory }; } + + /** + * cache of the recordsToMap(); + */ private static Map recordsMap = recordsToMap(records); + /** + * cache of the return of getAllKnownSids so that we don't have to + * expensively get them every time. + */ private static short[] sidscache; - + + /** + * List of the listners that are registred. should all be ERFListener + */ private List listeners; + /** + * instance is abortable or not + */ private boolean abortable; + /** + * Construct an abortable EventRecordFactory. + * The same as calling new EventRecordFactory(true) + * @see #EventRecordFactory(boolean) + */ public EventRecordFactory() { this(true); } + /** + * Create an EventRecordFactory + * @param abortable specifies whether the return from the listener + * handler functions are obeyed. False means they are ignored. True + * means the event loop exits on error. + */ public EventRecordFactory(boolean abortable) { this.abortable = abortable; listeners = new ArrayList(recordsMap.size()); @@ -242,12 +271,16 @@ public class EventRecordFactory */ private boolean throwRecordEvent(Record record) { + boolean result = true; Iterator i = listeners.iterator(); while (i.hasNext()) { - ((ERFListener) i.next()).processRecord(record); + result = ((ERFListener) i.next()).processRecord(record); + if (abortable == true && result == false) { + break; + } } - return false; + return result; } /** @@ -346,6 +379,10 @@ public class EventRecordFactory } + /** + * create a record, if there are MUL records than multiple records + * are returned digested into the non-mul form. + */ public static Record [] createRecord(short rectype, short size, byte [] data) { @@ -429,6 +466,9 @@ public class EventRecordFactory return realretval; } + /** + * @return an array of all the SIDS for all known records + */ public static short [] getAllKnownRecordSIDs() { short[] results = new short[ recordsMap.size() ]; @@ -444,6 +484,11 @@ public class EventRecordFactory return results; } + /** + * gets the record constructors and sticks them in the map by SID + * @return map of SIDs to short,short,byte[] constructors for Record classes + * most of org.apache.poi.hssf.record.* + */ private static Map recordsToMap(Class [] records) { Map result = new HashMap(); @@ -475,6 +520,10 @@ public class EventRecordFactory } +/** + * ListenerWrapper just wraps an ERFListener and adds support for throwing + * the event to multiple SIDs + */ class ListenerWrapper implements ERFListener { private ERFListener listener; private short[] sids; @@ -489,7 +538,7 @@ class ListenerWrapper implements ERFListener { public boolean processRecord(Record rec) { - boolean result = false; + boolean result = true; for (int k = 0; k < sids.length; k++) { if (sids[k] == rec.getSid()) { result = listener.processRecord(rec); diff --git a/src/java/org/apache/poi/hssf/eventmodel/ModelFactory.java b/src/java/org/apache/poi/hssf/eventmodel/ModelFactory.java new file mode 100644 index 000000000..bb4c59e01 --- /dev/null +++ b/src/java/org/apache/poi/hssf/eventmodel/ModelFactory.java @@ -0,0 +1,157 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache POI" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache POI", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.poi.hssf.eventmodel; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.poi.hssf.model.Model; +import org.apache.poi.hssf.model.Sheet; +import org.apache.poi.hssf.model.Workbook; +import org.apache.poi.hssf.record.BOFRecord; +import org.apache.poi.hssf.record.EOFRecord; +import org.apache.poi.hssf.record.Record; + + +/** + * ModelFactory creates workbook and sheet models based upon + * events thrown by them there events from the EventRecordFactory. + * + * @see org.apache.poi.hssf.eventmodel.EventRecordFactory + * @author Andrew C. Oliver acoliver@apache.org + */ +public class ModelFactory implements ERFListener +{ + + List listeners; + Model currentmodel; + boolean lastEOF; + + /** + * Constructor for ModelFactory. Does practically nothing. + */ + public ModelFactory() + { + super(); + listeners = new ArrayList(1); + } + + /** + * register a ModelFactoryListener so that it can receive + * Models as they are created. + */ + public void registerListener(ModelFactoryListener listener) { + listeners.add(listener); + } + + /** + * Start processing the Workbook stream into Model events. + */ + public void run(InputStream stream) { + EventRecordFactory factory = new EventRecordFactory(true); + factory.registerListener(this,null); + lastEOF = true; + factory.processRecords(stream); + } + + //ERFListener + public boolean processRecord(Record rec) + { + if (rec.getSid() == BOFRecord.sid) { + if (lastEOF != true) { + throw new RuntimeException("Not yet handled embedded models"); + } else { + BOFRecord bof = (BOFRecord)rec; + switch (bof.getType()) { + case BOFRecord.TYPE_WORKBOOK: + currentmodel = new Workbook(); + break; + case BOFRecord.TYPE_WORKSHEET: + currentmodel = new Sheet(); + break; + default: + throw new RuntimeException("Unsupported model type "+bof.getType()); + } + + } + } + + if (rec.getSid() == EOFRecord.sid) { + lastEOF = true; + throwEvent(currentmodel); + } else { + lastEOF = false; + } + + + return true; + } + + /** + * Throws the model as an event to the listeners + * @param model to be thrown + */ + private void throwEvent(Model model) + { + Iterator i = listeners.iterator(); + while (i.hasNext()) { + ModelFactoryListener mfl = (ModelFactoryListener) i.next(); + mfl.process(model); + } + } + + +} diff --git a/src/java/org/apache/poi/hssf/eventmodel/ModelFactoryListener.java b/src/java/org/apache/poi/hssf/eventmodel/ModelFactoryListener.java new file mode 100644 index 000000000..5fe7a15df --- /dev/null +++ b/src/java/org/apache/poi/hssf/eventmodel/ModelFactoryListener.java @@ -0,0 +1,72 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache POI" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache POI", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.poi.hssf.eventmodel; + +import org.apache.poi.hssf.model.Model; + +/** + * ModelFactoryListener is registered with the + * ModelFactory. It receives Models. + * + * @author Andrew C. Oliver acoliver@apache.org + */ +public interface ModelFactoryListener +{ + /** + * Process a model. Called by the ModelFactory + * @param model to be processed + * @return abortable - currently ignored (may be implemented in the future) + */ + public boolean process(Model model); +}