001/** 002 * BioJava development code This code may be freely distributed and modified 003 * under the terms of the GNU Lesser General Public Licence. This should be 004 * distributed with the code. If you do not have a copy, see: 005 * http://www.gnu.org/copyleft/lesser.html Copyright for this code is held 006 * jointly by the individual authors. These should be listed in 007 * 008 *@author doc comments. For more information on the BioJava project and its 009 * aims, or to join the biojava-l mailing list, visit the home page at: 010 * http://www.biojava.org/ 011 */ 012 013package org.biojava.bio.seq.io.game12; 014 015import java.util.ArrayList; 016import java.util.List; 017 018import org.biojava.bio.seq.io.SeqIOListener; 019import org.biojava.bio.seq.io.game.ElementRecognizer; 020import org.biojava.utils.stax.DelegationManager; 021import org.biojava.utils.stax.StAXContentHandler; 022import org.biojava.utils.stax.StAXContentHandlerBase; 023import org.xml.sax.Attributes; 024import org.xml.sax.SAXException; 025 026/** 027 * StAX handler shamelessly ripped off from Thomas Down's XFFFeatureSetHandler. 028 * It was modified for greater generality. <strong>NOTE</strong> This class is 029 * not thread-safe -- it must only be used for one parse at any time. 030 * 031 * @author Thomas Down 032 * @author David Huen 033 * @since 1.2 034 */ 035 036public class StAXFeatureHandler extends StAXContentHandlerBase { 037 // class variables 038 /** 039 * the SeqIOListener for this object 040 */ 041 SeqIOListener listener; 042 043 /** 044 * Nesting class that provides callback interfaces to nested class 045 */ 046 public StAXFeatureHandler staxenv; 047 /** 048 * handler list for delegation 049 */ 050 private List handlers; 051 052 /** 053 * These switches control functionality * 054 */ 055 /** 056 * are we in delegation from current object or is this pass my own? 057 */ 058 private int level = 0; 059 060 /** 061 * This base class defines default behaviour for a StAX handler including 062 * delegation. 063 */ 064 /** 065 * the version of constructor called depends on whether there is an 066 * explicit super(...) in the constructor of the derived class. If there 067 * is, that specific constructor will be called. If not, the parameterless 068 * will is called. 069 */ 070 071 StAXFeatureHandler() { 072// System.out.println("entering anonymous constructor"); 073 handlers = new ArrayList(); 074 } 075 076 077 /** 078 * Constructor for the StAXFeatureHandler object 079 * 080 *@param staxenv Description of the Parameter 081 */ 082 StAXFeatureHandler(StAXFeatureHandler staxenv) { 083 handlers = new ArrayList(); 084 this.staxenv = staxenv; 085 this.listener = staxenv.listener; 086 } 087 088 // Class to implement bindings 089 /** 090 * Description of the Class 091 * 092 *@author david 093 *@created 19 January 2002 094 */ 095 class Binding { 096 final ElementRecognizer recognizer; 097 final StAXHandlerFactory handlerFactory; 098 099 100 /** 101 * Constructor for the Binding object 102 * 103 *@param er Description of the Parameter 104 *@param hf Description of the Parameter 105 */ 106 Binding(ElementRecognizer er, StAXHandlerFactory hf) { 107 recognizer = er; 108 handlerFactory = hf; 109 } 110 } 111 112 // method to add a handler 113 // we do not distinguish whither it is a feature or property 114 // handler. The factory method creates the right type subclassed 115 // from the correct type of handler 116 /** 117 * Adds a feature to the Handler attribute of the StAXFeatureHandler object 118 * 119 *@param rec The feature to be added to the Handler attribute 120 *@param handler The feature to be added to the Handler attribute 121 */ 122 protected void addHandler( 123 ElementRecognizer rec, 124 StAXHandlerFactory handler) { 125 handlers.add(new Binding(rec, handler)); 126 } 127 128 /** provides a standardised way of returning an 129 * object that represents the result of parsing the 130 * child element 131 */ 132 public void returnData(Object o) 133 { 134 } 135 136 /** 137 * get the SeqIOListener for this parser 138 */ 139// public SeqIOListener getListener() 140// { 141// return staxenv.listener; 142// } 143 144 /** 145 * Element-specific handler. Subclass this to do something useful! 146 * 147 *@param nsURI Description of the Parameter 148 *@param localName Description of the Parameter 149 *@param qName Description of the Parameter 150 *@param attrs Description of the Parameter 151 *@exception SAXException Description of the Exception 152 */ 153 public void startElementHandler( 154 String nsURI, 155 String localName, 156 String qName, 157 Attributes attrs) 158 throws SAXException { } 159 160 /** 161 * Handles basic entry processing for all feature handlers. 162 * 163 *@param nsURI Description of the Parameter 164 *@param localName Description of the Parameter 165 *@param qName Description of the Parameter 166 *@param attrs Description of the Parameter 167 *@param dm Description of the Parameter 168 *@exception SAXException Description of the Exception 169 */ 170 public void startElement( 171 String nsURI, 172 String localName, 173 String qName, 174 Attributes attrs, 175 DelegationManager dm) 176 throws SAXException { 177 level++; 178 179 // perform delegation 180 // we must delegate only on features that are directly attached. 181 // if I do not check that that's so, any element of a kind I delegate 182 // on will be detected any depth within unrecognized tags. 183 if (level == 2) { 184// System.out.println("StaxFeaturehandler.startElement starting. localName: " + localName + " " + level); 185 for (int i = handlers.size() - 1; i >= 0; --i) { 186 Binding b = (Binding) handlers.get(i); 187 if (b.recognizer.filterStartElement(nsURI, localName, qName, attrs)) { 188 dm.delegate(b.handlerFactory.getHandler(this)); 189 return; 190 } 191 } 192 } 193 194 // call the element specific handler now. 195 // remember that if we we have a delegation failure we pass here too! 196 if (level == 1) { 197 startElementHandler(nsURI, localName, qName, attrs); 198 } 199 } 200 201 /** 202 * Element specific exit handler Subclass to do anything useful. 203 * 204 *@param nsURI Description of the Parameter 205 *@param localName Description of the Parameter 206 *@param qName Description of the Parameter 207 *@param handler Description of the Parameter 208 *@exception SAXException Description of the Exception 209 */ 210 public void endElementHandler( 211 String nsURI, 212 String localName, 213 String qName, 214 StAXContentHandler handler) 215 throws SAXException { } 216 217 218 /** 219 * Handles basic exit processing. 220 * 221 *@param nsURI Description of the Parameter 222 *@param localName Description of the Parameter 223 *@param qName Description of the Parameter 224 *@param handler Description of the Parameter 225 *@exception SAXException Description of the Exception 226 */ 227 public void endElement( 228 String nsURI, 229 String localName, 230 String qName, 231 StAXContentHandler handler) 232 throws SAXException { 233// System.out.println("StAXFeatureHandler endElement called, localName, level: " + localName + " " + stackLevel); 234 if ((--level) == 0) { 235 endElementHandler(nsURI, localName, qName, handler); 236 } 237 } 238} 239