/* * Reference ETL Parser for Java * Copyright (c) 2000-2009 Constantine A Plotnikov * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sf.etl.parsers.internal.phrase_parser; import java.io.Reader; import net.sf.etl.parsers.Lexer; import net.sf.etl.parsers.LexerFactory; import net.sf.etl.parsers.LexerStates; import net.sf.etl.parsers.PhraseParser; import net.sf.etl.parsers.PhraseToken; import net.sf.etl.parsers.PhraseTokens; import net.sf.etl.parsers.TextPos; import net.sf.etl.parsers.Tokens; import net.sf.etl.parsers.internal.AbstractParserImpl; import org.xml.sax.InputSource; /** * A default implementation of phrase parser. */ public final class DefaultPhraseParser extends AbstractParserImpl<PhraseToken> implements PhraseParser { /** * current token */ PhraseToken currentToken; /** * special not started state */ private static final PhraseToken NOT_STARTED = null; /** * a lexer */ Lexer lexer; /** * current parsing state */ ParsingState state; /** a system identifier */ String systemId; /** * If true, the partial tokens are reported */ private boolean reportPartialTokens = false; /** * {@inheritDoc} */ public boolean arePartialTokensReported() { return reportPartialTokens; } /** * {@inheritDoc} */ public void setPartialTokensReported(boolean value) { reportPartialTokens = value; if (lexer != null) { lexer.setPartialTokensReported(value); } } /** * start parsing * * @param systemId * a system identifier * @param lexer * an lexer */ private void parse(String systemId, Lexer lexer) { this.lexer = lexer; this.lexer.setPartialTokensReported(reportPartialTokens); this.systemId = systemId; new SegmentSequenceState(this, false); } /** * {@inheritDoc} */ public void close() { checkClosed(); isClosed = true; lexer.close(); } /** * {@inheritDoc} */ @Override public String toString() { return "PhraseParser[token=" + currentToken + ",lexer=" + lexer + "]"; } /** * {@inheritDoc} */ public PhraseToken current() { checkValid(); if (currentToken == null) { throw new IllegalStateException("Parsing has not yet started."); } return currentToken; } /** * {@inheritDoc} */ public boolean advance() { checkValid(); try { if (currentToken != null && currentToken.kind() == PhraseTokens.EOF) { return false; } if (currentToken == NOT_STARTED || currentToken.hasToken()) { lexer.advance(); } while (state != null) { if (state.parse()) { return true; } } if (lexer.current().kind() == Tokens.EOF) { currentToken = new PhraseToken(PhraseTokens.EOF, lexer .current()); } else { throw new RuntimeException( "segment parser should not call this. there is possibly an error."); } return true; } catch (final RuntimeException ex) { invalidate(); throw ex; } catch (final Error ex) { invalidate(); throw ex; } } /** * {@inheritDoc} */ public void parse(InputSource source) { try { lexer = LexerFactory.newInstance().newLexer(); lexer.setEntityResolver(getEntityResolver()); lexer.parse(source); parse(lexer.getSystemId(), lexer); } catch (final RuntimeException ex) { invalidate(); throw ex; } catch (final Error ex) { invalidate(); throw ex; } } /** * {@inheritDoc} */ public void reparse(String systemId, Reader r, TextPos start) { try { lexer = LexerFactory.newInstance().newLexer(); lexer.reparse(systemId, r, start, LexerStates.DEFAULT_STATE); parse(systemId, lexer); } catch (final RuntimeException ex) { invalidate(); throw ex; } catch (final Error ex) { invalidate(); throw ex; } } /** * {@inheritDoc} */ public String getSystemId() { return systemId; } }