/* * 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.term_parser.states; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import net.sf.etl.parsers.PhraseParser; import net.sf.etl.parsers.TermContext; import net.sf.etl.parsers.internal.term_parser.AbstractPeer; import net.sf.etl.parsers.internal.term_parser.DefaultTermParser; import net.sf.etl.parsers.internal.term_parser.PeerFactory; /** * This is a peer factory for state machine peers. * * @author const */ // NOTE POST 0.2: make this class serializable. So it will be possible to read // it again // and execute it. This would require some indirection interface // NOTE POST 0.2: implement compilation to Java bytecode and test performance. public class StateMachinePeerFactory implements PeerFactory { /** * This suffix is added to context name to get a name of activation for * statement sequence associated with context. */ public final static String STATEMENT_SEQUENCE_ACTIVATION_SUFFIX = "-statements"; /** * This suffix is added to context name to get a name of activation for * specific operator level associated with context. Clients should also add * specific level number to get a full name of activation factory. */ public final static String EXPRESSION_LEVEL_ACTIVATION_SUFFIX = "-level-"; /** Map from context name to operation level to expression activation */ private final Map<String, TreeMap<Integer, ActivationFactoryImpl>> contextToLevelToFactory = new HashMap<String, TreeMap<Integer, ActivationFactoryImpl>>(); /** Map from context name to operation level to statements activation */ private final Map<String, ActivationFactoryImpl> contextToStatementsFactory = new HashMap<String, ActivationFactoryImpl>(); /** Map from activation factory name to activation factory */ private final Map<String, ActivationFactoryImpl> nameToFactory = new HashMap<String, ActivationFactoryImpl>(); /** default term context */ TermContext defaultTermContext; /** a set of system identifiers that were used to build this grammar */ private Set<String> grammarDependencies; /** * A constructor */ public StateMachinePeerFactory() { super(); } /** * Get numbers associated with operator levels in the grammar * * @param contextName * a name of context * @return a sorted map of operator levels or null if there are no * expressions associated with context. */ SortedMap<Integer, ActivationFactoryImpl> operatorLevels(String contextName) { final SortedMap<Integer, ActivationFactoryImpl> levelsToFactory = contextToLevelToFactory .get(contextName); if (levelsToFactory == null) { return null; } return Collections .<Integer, ActivationFactoryImpl> unmodifiableSortedMap(levelsToFactory); } /** * {@inheritDoc} */ public AbstractPeer createPeer(DefaultTermParser termParser, PhraseParser phraseParser) { return new StateMachinePeer(this, termParser, phraseParser); } /** * {@inheritDoc} */ public String defaultContext() { return defaultTermContext.context(); } /** * Set default term context * * @param context * a default context */ public void setDefaultContext(TermContext context) { defaultTermContext = context; } /** * Register activation in the peer factory * * @param context * a name of context * @param impl * an activation implementation */ public void registerSegmentSequenceActivation(TermContext context, ActivationFactoryImpl impl) { assert !contextToStatementsFactory.containsKey(context.context()) : "There should be only one statement activation for context " + context; contextToStatementsFactory.put(context.context(), impl); nameToFactory.put(impl.name(), impl); } /** * Register activation in the peer factory * * @param context * a name of context * @param priority * an operator level with which this activation is associated * @param impl * an activation implementation */ public void registerExpressionActivation(TermContext context, int priority, ActivationFactoryImpl impl) { TreeMap<Integer, ActivationFactoryImpl> map = contextToLevelToFactory .get(context.context()); if (map == null) { map = new TreeMap<Integer, ActivationFactoryImpl>(); contextToLevelToFactory.put(context.context(), map); } final Integer key = new Integer(priority); assert !map.containsKey(key) : "The activation for level " + priority + " should be registered only once for context " + context; map.put(key, impl); nameToFactory.put(impl.name(), impl); } /** * This method returns either factory itself if it belongs to this state * machine or proxy activation factory. * * @param activationFactory * a statement sequence * @return an activation or activate proxy */ public ActivationFactory getActivationFactoryReference( ActivationFactoryImpl activationFactory) { // NOTE POST 0.2: support proxy references. return activationFactory; } /** * Get segment sequence activation factory by context name * * @param grammarContext * a grammar context name * @return activation factory or null */ public ActivationFactory getSegmentSequenceProduction(String grammarContext) { return contextToStatementsFactory.get(grammarContext); } /** * {@inheritDoc} */ public boolean supportsStartContext(String contextName) { if (contextName == null) { contextName = defaultContext(); } return getSegmentSequenceProduction(contextName) != null; } /** * {@inheritDoc} */ public Collection<String> usedGrammars() { return grammarDependencies; } /** * Set dependencies for this peer. * * @param deps * a dependency set */ public void setDependencies(Set<String> deps) { this.grammarDependencies = deps; } }