TransitionList PolicyDocumentClass::getTransitions(const QString& patternName) const { TransitionList list; // get DOM node of the given pattern // QDomNode patternNode = getPatternNode(patternName); // check for each child: if it is a transition -> add to list // QDomNode node = patternNode.firstChild(); while(!node.isNull()) { // if tagName == "transition" -> add a transition object to the list // if (node.toElement().tagName() == XML_TAG_TRANSITION) { QString message = node.toElement().attribute("message"); QString target = node.toElement().attribute("target"); Transition transition(message, target); list.push_back(transition); } node = node.nextSibling(); } return list; }
TransitionList AnnotationMatcher::buildTransitions( const text::Node & node, const Context & context ) const { TransitionList transitions; for ( uint i = 0, sz = node.getTransitions().size(); i < sz; ++ i ) if ( matchTransition( *node.getTransition( i ), context ) ) transitions.push_back( node.getTransition( i ) ); return transitions; }
static void processCompoundPattern( const PatternMatchState & state, TransitionList & newTransitions ) { const Node & currentNode = state.getCurrentNode(); if ( state.isComplete() ) { // Сопоставление завершено Match::AttributesMap attributes; state.context.addAttributes( attributes, state.getAlternative().getBindings() ); // Строим набор аттрибутов for ( uint i = 0; i < newTransitions.size(); ++ i ) { Match & match = static_cast<Match&>( *newTransitions[i] ); if ( match.equals( state.getAlternative().getPattern(), state.startNode, currentNode, attributes ) ) { match.addVariant( state.releaseVariant() ); return; // Если сопоставление уже было найдено } } newTransitions.push_back( new Match( state.startNode, currentNode, state.getAlternative().getPattern(), state.releaseVariant(), attributes ) ); // TODO Optimize return; } ChainList chains; if ( const AnnotationMatcher * curMatcher = dynamic_cast<const AnnotationMatcher *>( &state.getCurrentMatcher() ) ) { TransitionList nextTransitions = curMatcher->buildTransitions( currentNode, state.context ); for ( uint i = 0, sz = nextTransitions.size(); i < sz; ++ i ) { PatternMatchState temp_state( state, nextTransitions[ i ], i == sz ); processCompoundPattern( temp_state, newTransitions ); } } else { const AnnotationChainMatcher & chainMatcher = static_cast<const AnnotationChainMatcher &>( state.getCurrentMatcher() ); chains.clear(); chainMatcher.buildChains( state.getCurrentNode(), state.context, chains ); for ( uint i = 0, sz = chains.size(); i < sz; ++ i ) { PatternMatchState temp_state( state, chains[i].first, chains[i].second, i == sz - 1 ); processCompoundPattern( temp_state, newTransitions); } } }
TransitionList PatternMatcher::buildTransitions( const text::Node & node, const Context & context ) const { TransitionList newTransitions; if ( node.text.isMatchesReady( pattern ) ) { uint start = node.getTokenCount() + node.getWordCount(); uint end = node.getTransitionCount(); for ( uint i = start; i < end; ++ i ) // Перебираем все сопоставления из текущей вершины if ( matchTransition( *node.getTransition( i ), context ) ) newTransitions.push_back( node.getTransition( i ) ); } else { for ( uint i = 0; i < pattern.alternatives.size(); ++ i ) { PatternMatchState state( pattern, pattern.alternatives[i], node ); processCompoundPattern( state, newTransitions ); } } return newTransitions; }