co.cask.wrangler.api.RecipeSymbol Maven / Gradle / Ivy
/*
* Copyright © 2017 Cask Data, Inc.
*
* Licensed 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 co.cask.wrangler.api;
import co.cask.wrangler.api.annotations.PublicEvolving;
import co.cask.wrangler.api.parser.Token;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
/**
* This object RecipeSymbol
stores information about all the
* TokenGroup
( TokenGroup represents a collection of tokens
* generated from parsing a single directive). The object also contains
* information about the directives (or plugins) that need to be loaded
* at the startup time.
*
* This class provides some useful methods for accessing the list of
* directives or plugins that need to be loaded, the token groups for
* all the directives tokenized and parsed.
*
* This class exposes a builder pattern for constructing the object.
* in the RecipeVisitor
. The RecipeVisitor
* constructs RecipeSymbol
using the RecipeSymbol.Builder
*/
@PublicEvolving
public final class RecipeSymbol {
/**
* Version if specified, else defaults to 1.0
*/
private String version;
/**
* Set of directives or plugins that have to loaded
* during the configuration phase of RecipePipeline.
*/
private Set loadableDirectives = new TreeSet<>();
/**
* This maintains a list of tokens for each directive parsed.
*/
private final List tokens;
private RecipeSymbol(String version, Set loadableDirectives, List tokens) {
this.version = version;
this.loadableDirectives = loadableDirectives;
this.tokens = tokens;
}
/**
* Returns a set of dynamically loaded directives as plugins. These are
* the set of plugins or directives that are in the recipe, but are provided
* as the user plugins.
*
* If there are no directives specified in the recipe, then there would
* be no plugins to be loaded.
*
* @return An empty set if there are not directives to be loaded dynamically,
* else the list of directives as specified in the recipe.
*/
public Set getLoadableDirectives() {
return loadableDirectives;
}
/**
* Returns the version of the grammar as specified in the recipe. The
* version is the one extracted from Pragma. It's specified as follows
* #pragma version 2.0;
*
* @return version of the grammar used in the recipe.
*/
public String getVersion() {
return version;
}
/**
* Returns number of groups tokenized and parsed. The number returned will
* less than or equal to the number of directives specified in the recipe.
*
* Fewer than number of directives is because of the '#pragma' directives
* @return
*/
public int size() {
return tokens.size();
}
/**
* Returns an iterator to the list of token groups maintained by this object.
*
* @return iterator to the list of tokens maintained.
*/
public Iterator iterator() {
return tokens.iterator();
}
/**
* Static method for creating an instance of the {@code RecipeSymbol.Builder}.
*
* @return a instance of builder.
*/
public static RecipeSymbol.Builder builder() {
return new RecipeSymbol.Builder();
}
/**
* This method toJson
returns the JsonElement
object
* representation of this object.
*
* @return An instance of JsonElement
representing this object.
*/
public JsonElement toJson() {
JsonObject output = new JsonObject();
output.addProperty("class", this.getClass().getSimpleName());
output.addProperty("count", tokens.size());
JsonArray array = new JsonArray();
Iterator iterator = tokens.iterator();
while(iterator.hasNext()) {
JsonArray darray = new JsonArray();
Iterator it = iterator.next().iterator();
while(it.hasNext()) {
Token tok = it.next();
JsonObject object = new JsonObject();
object.addProperty("token", tok.type().toString());
object.addProperty("value", tok.value().toString());
darray.add(object);
}
array.add(darray);
}
output.add("value", array);
return output;
}
/**
* This inner class provides a builder pattern for building
* the RecipeSymbol
object. In order to create the
* this builder, one has to use the static method defined in
* RecipeSymbol
.
*
* Following is an example of how this can be done.
*
*
* RecipeSymbol.Builder builder = RecipeSymbol.builder();
* builder.createTokenGroup(...);
* builder.addToken(...);
* builder.addVersion(...);
* builder.addLoadableDirective(...);
* RecipeSymbol compiled = builder.build();
*
*/
public static final class Builder {
private final List groups = new ArrayList<>();
private TokenGroup group = null;
private Set loadableDirectives = new TreeSet<>();
private String version = "1.0";
private SourceInfo info = null;
/**
* TokenGroup
is created for each directive in
* the recipe. This method creates a new TokenGroup
* by passing the SourceInfo
, which represents the
* information of the source parsed.
*
* @param info about the source directive being parsed.
*/
public void createTokenGroup(SourceInfo info) {
if (group != null) {
groups.add(group);
}
this.group = new TokenGroup(info);
}
/**
* This method provides a way to add a Token
to the TokenGroup
.
*
* @param token to be added to the token group.
*/
public void addToken(Token token) {
group.add(token);
}
/**
* Recipe can specify the version of the grammar. This method
* allows one to extract and add the version to the RecipeSymbol.
*
* @param version of the recipe grammar being used.
*/
public void addVersion(String version) {
this.version = version;
}
/**
* A Recipe can specify the pragma instructions for loading the directives
* dynamically. This method allows adding the new directive to be loaded
* as it's parsing through the call graph.
*
* @param directive to be loaded dynamically.
*/
public void addLoadableDirective(String directive) {
loadableDirectives.add(directive);
}
/**
* Returns a fully constructed and valid RecipeSymbol
object.
*
* @return An instance of RecipeSymbol
*/
public RecipeSymbol build() {
groups.add(group);
return new RecipeSymbol(version, loadableDirectives, this.groups);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy