/**
* Licensed to Cloudera, Inc. under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. Cloudera, Inc. licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cloudera.flume.conf;
import static com.cloudera.flume.conf.PatternMatch.kind;
import static com.cloudera.flume.conf.PatternMatch.or;
import static com.cloudera.flume.conf.PatternMatch.recursive;
import static com.cloudera.flume.conf.PatternMatch.tuple;
import static com.cloudera.flume.conf.PatternMatch.var;
import java.util.Map;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.tree.CommonTree;
/**
* This creates patterns for flume-specific ast pattern matching.
*/
public class FlumePatterns {
/**
* Matches if current ast node is a source of kind kind.
*/
public static PatternMatch source(String k) {
return kind("SOURCE").child(kind(k));
}
/**
* Matches if current ast node is a sink (not a deco) of kind kind.
*/
public static PatternMatch sinkOnly(String k) {
return kind("SINK").child(kind(k));
}
/**
* Matches if the current ast node is a deco (not a sink) of kind kind.
*/
public static PatternMatch deco(String k) {
// Example Deco ASTs:
// (DECO (SINK k xxx) ( DECO xxx xxx ) )
// (DECO (SINK k ) ( MULTI xxx xxx ) )
// (DECO (SINK k xxx) ( MULTI xxx xxx ) )
return tuple(kind("DECO"), kind("SINK").child(kind(k)), var(k + "Child",
or(kind("SINK"), kind("DECO"), kind("MULTI"), kind("BACKUP"),
kind("LET"), kind("ROLL"), kind("FAILCHAIN"))));
}
/**
* Matches if the current as node is a sink or deco of kind kind.
*/
public static PatternMatch sink(String kind) {
return or(sinkOnly(kind), deco(kind));
}
/**
* Recursively finds a sink (only) of kind k.
*
* TODO(jon) this is not completely strict but will work fine from parser
* generated ASTs.
*/
public static CommonTree findSink(String sink, String k)
throws RecognitionException {
CommonTree lsnkTree = FlumeBuilder.parseSink(sink);
PatternMatch p = recursive(var("lsnk", kind("SINK").child(
kind("logicalSink"))));
Map<String, CommonTree> matches = p.match(lsnkTree);
if (matches == null) {
// do nothing,
return lsnkTree;
}
return matches.get("lsnk");
}
/**
* Recursively finds a sink of kind kind.
*
* TODO(jon) currently we do not have source decorators, so it is not really
* necessary for this to be recursive.
*/
public static CommonTree findSource(String src, String kind)
throws RecognitionException {
PatternMatch p = recursive(var("src", source(kind)));
CommonTree ctsrc = FlumeBuilder.parseSource(src);
Map<String, CommonTree> matches = p.match(ctsrc);
if (matches == null)
return null;
return matches.get("src");
}
}