/* * Copyright 2015 Coursera 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 com.linkedin.data.schema.resolver; import com.linkedin.data.schema.DataSchemaLocation; import com.linkedin.data.schema.DataSchemaParserFactory; import com.linkedin.data.schema.DataSchemaResolver; import com.linkedin.data.schema.Name; import com.linkedin.data.schema.NamedDataSchema; import com.linkedin.data.schema.SchemaParserFactory; import com.linkedin.data.schema.grammar.PdlSchemaParserFactory; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Combines multiple file format specific resolvers (and respective file format specific parsers) * into a single resolver. * * E.g. a resolver for the ".pdsc" file format and the ".pdl" file format, each with their * own file format specific parsers, can be combined into a single resolver able to look up * schemas of either file format. */ public class MultiFormatDataSchemaResolver implements DataSchemaResolver { private final List<DataSchemaResolver> resolvers; public static List<DataSchemaParserFactory> BUILTIN_FORMAT_PARSER_FACTORIES; static { BUILTIN_FORMAT_PARSER_FACTORIES = new ArrayList<>(2); BUILTIN_FORMAT_PARSER_FACTORIES.add(SchemaParserFactory.instance()); BUILTIN_FORMAT_PARSER_FACTORIES.add(PdlSchemaParserFactory.instance()); } /** * Create a MultiFormatDataSchemaResolver able to resolve all builtin file formats (.pdsc and .pdl). */ public static MultiFormatDataSchemaResolver withBuiltinFormats(String resolverPath) { return new MultiFormatDataSchemaResolver(resolverPath, BUILTIN_FORMAT_PARSER_FACTORIES); } /** * Initializes a new resolver with a specific set of file format parsers. Use @{link withBuiltinFormats} * instead to initialize with the default file format parsers. * * @param resolverPath provides the search paths separated by the provided separator, or null for no search paths. * @param parsersForFormats provides a list of parser factories, one for each file format (e.g. PDSC, PDL) * this resolver supports. */ public MultiFormatDataSchemaResolver( String resolverPath, List<DataSchemaParserFactory> parsersForFormats) { resolvers = new ArrayList<>(); for (DataSchemaParserFactory parserForFormat: parsersForFormats) { FileDataSchemaResolver resolver = new FileDataSchemaResolver(parserForFormat, resolverPath, this); resolver.setExtension("." + parserForFormat.getLanguageExtension()); resolvers.add(resolver); } } @Override public Map<String, NamedDataSchema> bindings() { Map<String, NamedDataSchema> results = new HashMap<>(); for (DataSchemaResolver resolver: resolvers) { results.putAll(resolver.bindings()); } return results; } @Override public Map<String, DataSchemaLocation> nameToDataSchemaLocations() { Map<String, DataSchemaLocation> results = new HashMap<>(); for (DataSchemaResolver resolver: resolvers) { results.putAll(resolver.nameToDataSchemaLocations()); } return results; } @Override public NamedDataSchema findDataSchema(String name, StringBuilder errorMessageBuilder) { for (DataSchemaResolver resolver: resolvers) { NamedDataSchema result = resolver.findDataSchema(name, errorMessageBuilder); if (result != null) { return result; } } return null; } @Override public void bindNameToSchema(Name name, NamedDataSchema schema, DataSchemaLocation location) { for (DataSchemaResolver resolver: resolvers) { resolver.bindNameToSchema(name, schema, location); } } @Override public NamedDataSchema existingDataSchema(String name) { for (DataSchemaResolver resolver: resolvers) { NamedDataSchema result = resolver.existingDataSchema(name); if (result != null) { return result; } } return null; } @Override public boolean locationResolved(DataSchemaLocation location) { for (DataSchemaResolver resolver: resolvers) { if (resolver.locationResolved(location)) { return true; } } return false; } }